Ошибка COR_E_NEWER_RUNTIME при создании класса COM из соседней сборки
У меня следующая ситуация:
- Нативное приложение Delphi должно вызывать COM-интерфейс из C# DLL
- Я хочу сделать сотрудничество приложения и DLL без регистрации C# DLL (бок о бок)
Код приложения Delphi (исполняемый файл консоли):
program TestSideBySide2;
{$APPTYPE CONSOLE}
{$R *.res}
uses
System.SysUtils,
mscorlib_TLB in 'mscorlib_TLB.pas',
TestSideBySide2_TLB in 'TestSideBySide2_TLB.pas';
var
sideBySide : TestSideBySide2_TLB._SideBySideClass;
intfSideBySide : TestSideBySide2_TLB.ISideBySideClass;
res : HRESULT;
begin
try
sideBySide := TestSideBySide2_TLB.CoSideBySideClass.Create();
res := sideBySide.QueryInterface(IID_ISideBySideClass,intfSideBySide);
Writeln(intfSideBySide.Version());
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
end.
Импортированный 'TestSideBySide2_TLB.pas'
был сгенерирован из DLL с использованием TLIBIMP.exe
инструмент.
Вот манифест приложения, который будет связан с приложением Delphi в качестве ресурса:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"
xmlns:asmv3="urn:schemas-microsoft-com:asm.v3">
<assemblyIdentity
type="win32"
name="TestSideBySide.exe"
version = "1.0.0.0" />
<dependency>
<dependentAssembly>
<assemblyIdentity
type="win32"
name="TestSideBySide2"
version="1.0.0.0" />
</dependentAssembly>
</dependency>
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
<security>
<requestedPrivileges>
<requestedExecutionLevel
level="asInvoker"
uiAccess="false"/>
</requestedPrivileges>
</security>
</trustInfo>
</assembly>
C# DLL код (скомпилирован с использованием SharpDevelop)
using System;
using System.Reflection;
using System.Runtime.InteropServices;
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: Guid("07F9C367-BFA4-45AD-8A60-689096BD7AA9")]
namespace TestSideBySide2
{
/// <summary>
/// Exposed interface.
/// </summary>
[Guid("49D49031-12D8-40B5-85FA-B42133FD7DD0")]
public interface ISideBySideClass
{
string Version();
}
/// <summary>
/// Implementation of exposed interface.
/// </summary>
[Guid("A0BDB20B-A6E4-4A36-A64C-CC9186DD1C3E")]
public class SideBySideClass : ISideBySideClass
{
public string Version()
{
return "1.0.0-C#";
}
}
}
И манифест сборки (также связанный как ресурс в DLL):
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1"
manifestVersion="1.0">
<assemblyIdentity
type="win32"
name="TestSideBySide2"
version="1.0.0.0" />
<clrClass
clsid="{A0BDB20B-A6E4-4A36-A64C-CC9186DD1C3E}"
progid="TestSideBySide2"
threadingModel="Both"
name="TestSideBySide2.SideBySideClass" >
</clrClass>
</assembly>
Пока все довольно просто. Приложение Delphi может разрешить привязки, и DLL будет загружена. Но линия
sideBySide := TestSideBySide2_TLB.CoSideBySideClass.Create();
терпит неудачу с исключением
EOleSysError: OLE-Error 8013101B, ClassID: {A0BDB20B-A6E4-4A36-A64C-CC9186DD1C3E}
Код ошибки разрешается в COR_E_NEWER_RUNTIME
,
Я проверил версию среды выполнения.NET, для которой была создана DLL, и это.NET 4.0 (которая доступна в моей среде Windows 10).
Затем я попытался собрать DLL для более старых версий времени выполнения (2.0, 3.0, 3.5), и для каждой из них это работало просто отлично.
Конечно, я исследовал, в чем может быть проблема, и вот что я нашел до сих пор обещающим решить проблему (но не сделал):
- Невозможно заставить работать VB.NET DLL, на которую ссылается клиент VB6 в reg-free сценарии
- Как настроить COM-компоненты на основе.NET Framework для активации без регистрации (с помощью
runtimeVersion="v1.4"
атрибут в манифесте DLLclrClass
элемент конкретно)
В настоящее время у меня нет идей, что еще можно сделать. Любые дополнительные ресурсы, которые я нашел в Интернете, просто указывают на одно из перечисленных выше предложений.
Что еще я мог пропустить там?
Обновить:
Коллега отметил, что это может быть странность Delphi и вызов из неуправляемого кода.
Мы используем Embarcadero Сиэтл Delphi 10.
1 ответ
Я решил проблему с помощью информации, найденной здесь:
Версии и ошибки времени выполнения 0x80131700 и 0x8013101b
Я уже сделал попытку добавить версию.NET CLR в манифест сборки DLL. Это может быть сделано для каждого класса в clrClass
раздел. Чего я не знал, так это того, что runtimeVersion
Атрибут должен быть полностью квалифицированным.
Полный clrClass
Теперь раздел выглядит так:
<clrClass
clsid="{A0BDB20B-A6E4-4A36-A64C-CC9186DD1C3E}"
progid="TestSideBySide2"
threadingModel="Both"
name="TestSideBySide2.SideBySideClass"
runtimeVersion="v4.0.30319">
</clrClass>
Согласно документу, указанному выше, записи версий для других версий CLR должны быть:
- v1.0.3705
- v1.1.4322
- v2.0.50727
- v4.0.30319