CLR2编译的C#COM不';我不能使用.NET4

CLR2编译的C#COM不';我不能使用.NET4,c#,com,clr,clr4.0,C#,Com,Clr,Clr4.0,有人知道为什么在CLR2(.Net 3.5)下编译的C#创建的COM库在仅与CLR4(.Net 4)一起使用时无法工作吗?CLR2 for COM中的CLR4缺少什么 我们正在app.config中使用适当的启动,以使C#在CLR4/.Net 4下运行: <startup> <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/> </startup> 所有的C#东西都能工

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

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

<startup>
  <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/>
</startup>

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

未能加载运行时。(来自HRESULT的异常:0x80131700)

当我们试图从C++中创建COM接口时,我们得到了同样的问题。
一旦我们安装了CLR2(.NET3.5),所有COM组件都开始工作。我们想知道发生了什么。

程序集已注册为需要CLR v2,但您明确禁止将该版本与.config文件一起加载。您需要在.config文件中添加一个额外的位来表示“我知道,但没关系”。像这样:

<startup useLegacyV2RuntimeActivationPolicy="true">
   <supportedRuntime version="v4.0"/>
</startup>  

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

<startup>
   <supportedRuntime version="v4.0"/>
   <supportedRuntime version="v2.0.50727"/>
</startup>  



另一个非常重要的细节是这个.config文件的名称和位置。它不直观,但CLR从启动EXE的目录和名称中查找.config文件。因此,如果您正在从本地C++程序中测试这个[COMVICE]服务器,请说c:\fo\BAR.exe,那么您必须命名文件“bar .exe。COFIG”并将其复制到C:\FO目录。将.config文件与具有DLL名称的DLL放在同一目录中将不起作用。

在.NET 4中编译程序集后,可能需要使用regasm.exe更新运行时版本。如果不选择重新编译,则可能会将注册表中的运行时版本从v2.0.50727更改为v4.0.30319。这对我有用。我在这里找到了类似的答案:

CLR版本写入.dll文件头中,其值通过regasm工具复制到注册表中。激活器然后尝试使用指定的确切CLR版本运行组件。要让CLR 4运行在CLR 2程序集中实现的组件,您可以手动更改注册信息(Classes/{clsid}/InprocServer32/component version/RuntimeVersion)或设置
useLegacyV2RuntimeActivationPolicy
,如前一个答案中所述(配置文件确实位于native.exe旁边,这没什么问题).

AFAIK,.net运行时都是独立的,必须单独安装。不过,假设您拥有源代码,您可以重新编译COM库并以4.0框架为目标。重新编译为.net 4不会产生相同的问题。不过,这是出于测试目的,因为出于兼容性原因,我们需要保留.net 3.5,但在Windows上运行8无需用户安装.Net 3.5。正如我所说,在CLR4下运行时,除了COM部分外,其他一切都可以正常工作。不过,我还是第一次在3.5中安装了不在4.0中的COM部分。虽然这听起来很有希望,但人们会认为它不会正常工作。在使用useLegacyV2Ru的CLR4上运行时,我们基于CLR2/.Net 3.5的COM DLL不可用请记住,C++不能在C.Cycom COM DLL中实例化COM对象,除非安装了.NET 3.5,因为DLL的App.CONTIs不能像这个属性那样简单。有些东西根本没有安装在CLR4上,而是与COM相关的CLR2。要查看EXE搜索丢失的文件,请首先检查它是否加载了.config文件。如果没有加载,则说明您没有将其放置在正确的位置。它与本机EXE而不是DLL是同一文件夹。本机EXE是什么意思?这是一个C#COM DLL它没有本机.EXE程序集使用使程序集COM可见oOption和GUID、InterfaceType、DispId、ClassInterface、ComVisible属性来装饰接口、类和方法。有一个配置文件具有启动功能,并且它位于正确的位置,就好像我们删除了启动功能一样。使用此C#COM DLL的C#应用程序根本不会启动。因此,可以安全地假设我们使用的是正确的配置文件C++应用程序是一个测试应用程序,它帮助解决这个问题。我的意思是使用这个COM DLL的程序。就像C++测试应用程序,编译后的本地EXE。这强烈地表明你把.CONFIG文件放在错误的目录中。如果听起来奇怪,一个本地EXE会有一个.CONFIG文件:不,那是。真的是这样。CLR从启动EXE目录和名称中找到.CONFIG文件。C++是一个测试应用程序。使用的exe是一个不是本地的C语言应用程序。但是这看起来不像是问题。问题是regasm.exe以及它如何向CLR2注册COM类,因为它们是用CLR2编译的。这就是为什么我们尝试了.NET 4版本,但我们只是在其中加入了这些版本,它们不起作用。如果我们用regasm.exe重新注册,NET 4.0将起作用。但是,我们希望避免.NET 4.0编译。我们按照回答中的说明进行了更改,并且所有的人都只是通过C++和C++开始工作。你只有一半正确。在标记答案(StaskExoal.COM/A/13238652/196020)中描述的注册表更改确实有效,将UsRealyYv2RunTimeActPurvivPosivor设置为true并没有修复先前评论中已经提到的这个C com问题。