3

我们有一个使用大量 DLL 的大型 MFC 应用程序。到目前为止,我们一直在使用 vcredist_x86.exe 将 MFC 和 CRT 安装到非托管并行程序集缓存 (C:\Windows\WinSxS) 中。当以这种方式安装 MFC/CRT 时,应用程序会运行(在干净的 XP 机器上)。

根据 MSDN 文档,您可以通过将程序集文件复制到安装应用程序的文件夹中来安装 MFC/CRT。我已经用一个简单的 MFC 应用程序对此进行了测试,它可以工作。但是我在让我们的大型 MFC 应用程序使用这种方法工作时遇到了问题。

问题似乎是由于某些 DLL 的清单引用了早期版本的 CRT,例如,一个 DLL 包含以下清单。

<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<dependency>
<dependentAssembly>
<assemblyIdentity type="win32" name="Microsoft.VC80.CRT" version="8.0.50215.4652" processorArchitecture="x86" publicKeyToken="1fc8b3b9a1e18e3b" /> 
</dependentAssembly>
</dependency>
</assembly>

我们将 CRT 程序集的 8.0.50727.762 版本复制到我们应用程序的文件夹中。如您所见,这是 CRT 的较新版本。但由于某种原因,操作系统加载程序无法使用上述清单加载 DLL。在 WinSxS 中安装相同的 CRT 程序集时不会发生这种情况。当我使用 DependencyWalker 跟踪加载时,我收到错误 LDR: LdrpWalkImportDescriptor() failed to probe c:\documents and settings\qatest\desktop\test\log4cpp.dll 的清单,ntstatus 0xc0150002

加载程序加载较新版本的程序集的能力似乎在使用私有并排程序集时不起作用,但在将程序集安装到 WinSxS 时它确实起作用。

有针对这个的解决方法吗?

4

1 回答 1

1

我认为答案归结为 CRT 发布者政策。看看例如 c:\windows\winsxs\Manifests\x86_policy.9.0.microsoft.vc90.crt_1fc8b3b9a1e18e3b_9.0.30729.4148_none_f47e1bd6f6571810.manifest。这指定引用旧版本 CRT 的应用程序应加载此版本。

在不安装 vcredist 的情况下执行此重定向需要做的是更改清单,或编写一个libraryX.dll.config(或可能libraryX.dll.2.config)来重定向绑定。

有关示例配置,请参阅我的帖子。请注意,您不需要<publisherPolicy apply="no"/>; 应该应用发布者策略来关闭安全漏洞。

请务必在不同版本的 Windows 上进行测试,因为 SxS 的工作方式可能略有不同。

于 2010-06-29T20:47:01.963 回答