从并排程序集创建 COM class 时出错 COR_E_NEWER_RUNTIME

Error COR_E_NEWER_RUNTIME when creating COM class from side by side assembly

我有以下情况:

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' 是使用 TLIBIMP.exe 工具从 DLL 生成的。

这是将作为资源链接到 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


我检查了构建 DLL 的 .NET 运行时版本,这是 .NET 4.0(在我的 Windows 10 环境中可用)。

然后我尝试为较旧的运行时版本(2.0、3.0、3.5)构建 DLL,并且对于它们中的每一个都工作得很好。


当然,我一直在研究可能是什么问题,这是我到目前为止发现的有望解决问题(但没有解决)的内容:

目前我不知道还能做什么。我在 Internet 上找到的任何其他资源仅指向我在上面列出的建议之一。

我还能忽略什么?


更新:

一位同事提到这可能是一个 Delphi 奇怪的问题,并且是从非托管代码调用的。

我们正在使用 Embarcadero Seattle Delphi 10.

我在此处找到的信息的帮助下解决了问题:

Runtime Versions and Errors 0x80131700 and 0x8013101b

我已经尝试在 DLL 的程序集清单中添加 .NET CLR 版本。这可以根据 clrClass 部分中的 class 来完成。 我不知道的是,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