CLR2编译的C#COM不适用于.Net 4

有谁知道为什么在CLR2(.Net 3.5)下编译的C#创建的COM库在仅与CLR4(.Net 4)一起使用时不起作用? CLR4中缺少什么在CLR2中用于COM?

我们在app.config中使用适当的启动来使C#在CLR4 / .Net 4下运行:

   

所有的C#东西都有效,直到它尝试创建我们的COM接口。 它提供了以下例外:

无法加载运行时。 (HRESULTexception:0x80131700)

当我们尝试从C ++创建COM接口时,我们遇到了同样的问题。

一旦我们安装CLR2(.Net 3.5),所有COM内容开始工作。 我们想知道发生了什么。

在.NET 4中编译程序集后,您可能需要使用regasm.exe来更新RuntimeVersion。 如果不能重新编译,则可能会将注册表中的RuntimeVersion从v2.0.50727更改为v4.0.30319。 这对我有用。 我在这里找到了类似的答案: 在仅支持.NET-4的系统上使用GAC中的.NET-2.0目标COM DLL

注册程序集需要 CLR v2,但是您明确禁止使用.config文件加载该版本。 你需要在.config文件中多加一点来说,“我知道,但没关系”。 像这样:

    

请注意,您有意绕过.NET 4中添加的进程内并行版本控制function。一项新function,明确添加,允许应用程序加载多个版本的CLR以支持具有不同的COM服务器CLR版本要求。 这当然听起来像你的情景。 在这种情况下,更兼容的鼠标陷阱是允许加载两个版本的CLR:

     

另一个非常重要的细节是此.config文件的名称和位置。 它是不直观的,但CLR从启动EXE的目录和名称中找到.config文件。 因此,如果您从本机C ++程序(例如c:\ foo \ bar.exe)测试此[ComVisible]服务器,则必须将文件命名为“bar.exe.config”并将其复制到c:\ foo目录。 将.config文件放在与DLL名称相同的目录中将不起作用。

CLR版本写在.dll文件头中,其值由regasm工具复制到注册表中。 然后激活器尝试运行具有指定的确切CLR版本的组件。 要让CLR 4运行在CLR 2程序集中实现的组件,您可以手动更改注册信息(Classes / {clsid} / InprocServer32 / component-version / RuntimeVersion)或设置useLegacyV2RuntimeActivationPolicy ,如上一个答案中所述(配置文件确实如此)确实在本机.exe旁边,没有错误)。