我正在使用以下非托管C++代码从Excel 2003加载项(用于.NET加载项的COM填充程序)实例化CLR:
hr = CorBindToRuntimeEx(
0, // version, use default
0, // flavor, use default
0, // domain-neutral"ness" and gc settings
CLSID_CorRuntimeHost,
IID_ICorRuntimeHost,
(PVOID*) &m_pHost);
Run Code Online (Sandbox Code Playgroud)
对于我们组织中的绝大多数机器(几百台),这种方法非常有效,即使安装了多个CLR版本的机器也是如此; 但是对于少数机器,实例化了错误的(较旧的)CLR版本,然后无法加载程序集,因为它需要.NET 2运行时.
昨天我第一次运行Process Explorer,这很明显在其中一台问题机器上显示以下内容:
process pid type Handle or DLL
------- --- ---- -------------
procexp.exe 5056 DLL c:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\mscorworks.dll
EXCEL.EXE 7180 DLL c:\WINDOWS\Microsoft.NET\Framework\v1.1.4322\mscorworks.dll
Run Code Online (Sandbox Code Playgroud)
即Excel已加载错误版本的运行时,即使可以使用较新版本的运行时.现在我需要找出原因.
想到的一些可能性:
我强烈怀疑其中的第二个,但不知道如何证明/修复它.
有没有人见过类似的行为?有关正在发生的事情的任何建议?
其他几点说明:
我无法更改其中任何一个,因此不能选择较新的Excel版本.
这就是臭名昭著的 CLR 版本注入问题。这是一种比较温和的类型,而不是在 .NET 中编写 shell 扩展时遇到的真正令人讨厌的类型。
问题是有一个加载项在您之前加载,并且它要求加载 1.1 版本的 CLR。这就是问题所在,一个进程只能拥有一个版本的 CLR。您可以要求在 CorBindToRuntimeEx() 调用中加载 2.0.50727 版本,这是您的外接程序所需的版本。但这将会失败。请求默认版本将会成功,但现在您的加载项将无法加载。
“温和”的角度是,您可以从技术上更改加载项的加载顺序,确保首先加载 CLR 2.0。实际上不确定如何做到这一点。需要 1.1 版本的加载项仍有可能正常工作。请访问 superuser.com 询问您是否想要这样做。
有一个长期解决方案,CLR 版本 4 支持 CLR 的进程内并行版本控制。现在对你没有帮助。