是否可以动态更改激活旧程序集的 CLR 运行时 (BindAsLegacyV2Runtime)?
这是我的问题:
我必须做一个由第三方应用程序托管的插件。该应用程序是一个 MFC 应用程序,为了完成我的插件,我必须实现一个 COM 对象。我的 COM 对象采用 C# 语言,需要与 .NET 4 程序集互操作(因此,我的 C# 项目面向 .NET 4)。
当我测试时,它不起作用......我收到了异常: 混合模式程序集是针对运行时版本“v2.0”构建的,如果没有附加配置信息,则无法在 4.0 运行时中加载...
现在,因为我正在与第三方集成应用程序中,添加带有 useLegacyV2RuntimeActivationPolicy 设置的 App.exe.config 文件似乎不是一个可接受的解决方案(或者是吗?)。
我尝试在 MFC 应用程序和我的 .NET 代码之间添加额外的 C++ 层。该层实现 COM 对象并将所有调用转发给 C#。我通过使用 ICLRRuntimeInfo::BindAsLegacyV2Runtime() 方法解决了混合模式异常。这很好用。但是,如果在我的之前加载另一个仅使用 .NET 2.0 的插件,则此方法将失败(因为由其他插件启动的 .NET 2.0 运行时管理旧加载策略)。
长话短说,我被困住了。有没有办法动态更改负责遗留加载策略的运行时?
感谢您的帮助。
Here is my problem:
I have to do a plugin hosted by a third-party application. That application is an MFC app and to do my plugin, I have to implement a COM object. My COM object is in C# and needs to interop with .NET 4 assembly (so, my C# project targets .NET 4).
When I tested that, it didn't work... I received the exception:
Mixed mode assembly is built against version 'v2.0' of the runtime and cannot be loaded in the 4.0 runtime without additional configuration information...
Now, since I am doing an integration to a third-party app, adding an App.exe.config file with the useLegacyV2RuntimeActivationPolicy set does not seem to be an acceptable solution (or is it?).
I have tried to add an extra layer of C++ between the MFC app and my .NET code. This layer implements the COM object and forward all calls to the C#. I resolved my mixed-mode exception by using the ICLRRuntimeInfo::BindAsLegacyV2Runtime() method. This worked fine. However, if another plugin using .NET 2.0 only is loaded prior to mine, this method fails (since the .NET 2.0 runtime started by the other plugins manages legacy loading policies).
Long story short, I am stuck. Is there a way to dynamically change the runtime in charge of legacy loading policies?
Thanks for the help.
因为您是不同应用程序的加载组件,所以您将始终面临导致加载不同运行时的加载顺序问题。您可以做的就是尝试使用 .net 4s In-process side by side 确保您加载所需内容的指导。
虽然为您无法控制的应用程序添加应用程序配置通常是一个坏主意,但有时这是解决问题的唯一方法。我当然可以看到添加 app.exe.config 并进行测试 - 但是如果您将插件分发给广泛的受众,这可能会出现问题。
如果所有其他方法都失败,您可能必须执行我们所做的操作 - 在单独的进程中运行必须使用 .net 4 程序集的插件部分,并创建一个与该进程通信的 COM 插件“shim”。如果您使用 .net 程序集中的 UI,这不是一个好的解决方案,但它对于许多其他情况来说效果良好,可以接受。
Because you are a loaded component of a different application, you will always face the issue of load order causing different runtimes to load. What you can do is try to use .net 4s In-process side by side guidance to make sure you load what you want.
And while it's generally a bad idea to add an application config for a app you don't control, sometimes it's the only way around a problem. I can certainly see adding the app.exe.config and testing - however if you are distributing your plugin to a wide audience, this could prove to be problematic.
If all else fails, you may have to do what we did - run the parts of the plugin that must use your .net 4 assemblies in a separate process, and create a COM addin "shim" that communicates with that process. It's not a good solution if you are using UI from the .net assemblies, but it works acceptably well for many other cases.