我正在使用以下非托管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);
对于我们组织中的绝大多数机器(几百台),这种方法非常有效,即使安装了多个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
即。 Excel已加载错误版本的运行时,即使可以使用较新版本的运行时。现在我需要找出原因。
浮现在脑海中的一些可能性:
我强烈怀疑其中的第二个,但不知道如何证明/修复它。
有没有人见过类似的行为?有关正在发生的事情的任何建议吗?
其他几点说明:
我无法更改其中任何一个,因此不能选择较新的Excel版本。
答案 0 :(得分:4)
您可以使用GetCORVersion检查CLR是否已加载?如果GetCORVersion将v1.x作为加载的CLR版本返回,则中止加载CLR并向用户显示错误消息。
将您的加载项迁移到.net v4是一个选项吗? v4支持CLR((v1.x OR V2)和V4及更新版本的进程内并行托管)。请看CLRCreateInstance。
参考文献:
CLR Hosting Overview
In-Process Side-by-Side
@ MSDN Magazine
答案 1 :(得分:3)
这是臭名昭着的CLR版本注入问题。这是一种有点温和的类型,而不是你在.NET中编写shell扩展时遇到的非常讨厌的类型。
问题是有一个加载项加载到你的加载项之前它要求加载1.1版本的CLR。这就是降压停止的地方,一个过程只能有一个版本的CLR。您可以要求在CorBindToRuntimeEx()调用中加载2.0.50727版本,这是您的加载项所需的版本。但那会失败。要求默认版本会成功,但现在您的加载项将无法加载。
'温和'的角度是你可以在技术上改变加载项加载的顺序,确保首先加载CLR 2.0。实际上不确定如何做到这一点。需要1.1的加载项具有仍然正常工作的合理几率。在superuser.com上询问您是否想要这样做。
有一个长期解决方案,CLR版本4支持CLR的进程内并行版本控制。不是什么东西现在会帮助你。