Does anyone know why a C# created COM library that was compiled under CLR2 (.Net 3.5) doesn't work when used with only CLR4(.Net 4)? What is missing in CLR4 that is in CLR2 for COM?
We are using the appropriate startup in the app.config to have the C# run under CLR4/.Net 4:
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/>
</startup>
All the C# stuff works until it try's to create our COM interface. It provided the following exception:
Failed to load the runtime. (Exception from HRESULT: 0x80131700)
We get the same issue when we try to create the COM interface from C++.
Once we install CLR2 (.Net 3.5) all the COM stuff starts working. We would like to know what's going on.
After compiling the assemblies in .NET 4, you'll probably need to use regasm.exe to update the RuntimeVersion. If recompiling is not an option, you could potentially change the RuntimeVersion in the registry from v2.0.50727 to v4.0.30319. This worked for me. I found a similar answer here: Using a .NET-2.0-targeted COM DLL in the GAC on a .NET-4-only system
The assembly is registered to require CLR v2 but you explicitly disallowed that version to be loaded with the .config file. You'll need an extra bit in the .config file to say, "I know, but it's okay". Like this:
<startup useLegacyV2RuntimeActivationPolicy="true">
<supportedRuntime version="v4.0"/>
</startup>
Do note that you are intentionally bypassing the in-process side-by-side versioning feature that was added in .NET 4. A new feature, expressly added to allow an application to load multiple versions of the CLR to support COM servers that have different CLR version requirements. Which certainly sounds like your scenario. In which case the more compatible mouse trap is to allow both versions of the CLR to be loaded:
<startup>
<supportedRuntime version="v4.0"/>
<supportedRuntime version="v2.0.50727"/>
</startup>
Another very important detail is the name and location of this .config file. It is unintuitive but the CLR locates the .config file from the directory and name of the startup EXE. So if you are testing this [ComVisible] server from a native C++ program, say c:\foo\bar.exe, then you must name the file "bar.exe.config" and copy it to the c:\foo directory. Putting the .config file in the same directory as the DLL with the DLL's name will not work.
The CLR version is written in the .dll file header and its value is copied to the registry by the regasm tool. The activator then tries to run the component with the exact CLR version specified. To have CLR 4 run the components implemented in CLR 2 assemblies you can either manually change the registration information (Classes/{clsid}/InprocServer32/component-version/RuntimeVersion) or set the useLegacyV2RuntimeActivationPolicy
as described in the previous answer (the config file really does go next to the native .exe, nothing wrong with that).