在使用 VS2015 编译的应用程序中加载 VS2008 的调试可再发行组件失败
Loading debug redistributables of VS2008 in app which got compiled with VS2015 fails
我的应用程序(使用 VS2015 编译)加载第 3 方 DLL(使用 VS2008 编译)。 运行 发布中的应用程序仅需要目标计算机上 MS 网页中的 VS2008 和 VS2015 可再发行组件。
运行 调试模式下的应用程序(例如在另一台开发人员机器上)需要 VS2008 的 debug 可再发行组件,应避免使用。复制第 3 方 DLL 旁边的 msvcX90d.dll 不会成功。有什么想法可以说服 Windows 加载 VS2008 调试运行时吗?我的应用程序需要清单吗?需要清单吗?
关于混合运行时的信息
是的,我对混合运行时不满意,但在我的上下文中,两个运行时不会相互干扰。并且重新编译第 3 方 DLL 不是一个选项。
进一步简化问题。如何在 VS2015 编译的应用程序中加载 msvcr90d.dll?
LoadLibrary(L"msvcr90d.dll");
阅读评论中的有用资源后,这是我在 VS2015(发布和调试)中加载 VS2008 (msvcr90d.dll) 的调试可再发行组件的方法。
首先,您的应用程序需要一个清单文件。什么是清单文件?此页面总结得很好:http://www.samlogic.net/articles/manifest.htm
A manifest is a XML file that contains settings that informs Windows
how to handle a program when it is started. The manifest can be
embedded inside the program file (as a resource) or it can be located
in a separate external XML file.
清单文件可以放在我们的可执行文件旁边或嵌入(默认)。 switch/change 它转到 Projects Property Page -> Linker -> Manifest Tool -> Input and Output -> Embed Manifest
。
下面源代码中的编译指示将我们(默认情况下)的嵌入式清单文件添加到我们的可执行文件中。
转到 C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\redist\Debug_NonRedist\amd64\Microsoft.VC90.DebugCRT
并复制可执行文件旁边的所有文件
打开新的 Microsoft.VC90.DebugCRT.manifest
并删除令牌 publicKeyToken="1fc8b3b9a1e18e3b"
。如果它在里面,Windows 一直拒绝加载 msvcr90d.dll。请不要问我为什么。
编译并执行你的程序
#include <Windows.h>
#pragma comment(linker,"/manifestdependency:\"type='win32' "\
"name='Microsoft.VC90.DebugCRT' "\
"version='9.0.21022.8' "\
"processorArchitecture='amd64' "\
"\"")
int main()
{
auto* lib = LoadLibrary(L"msvcr90d.dll");
if (!lib)
{
return -1;
}
FreeLibrary(lib);
return 0;
}
背景
为什么我们有一个外部清单文件 (Microsoft.VC90.DebugCRT.manifest) 和一个嵌入式清单文件(通过 pragma)用于此解决方案?看起来 pragma 只提供了有限的选项来让你的清单看起来像什么。一种选择是参考另一个包含更多信息的清单文件。
编辑: 这个 MSDN enter link description here 线程中的答案也很有帮助。
编辑 2: 无需从嵌入式清单引用外部 Microsoft.VC90.DebugCRT.manifest
,您可以将其嵌入到您的可执行文件中(也可以通过属性 页),但我得出这个结论为时已晚,但我的初步解决方案有望提供更多见解
我刚刚通过将我的第 3 方 DLL 与清单嵌入来解决了类似的问题。
运行 取决于我的第 3 方 DLL 显示它正在 C:\Windows\System32 中寻找 msvcr90.dll。显然,这不是正确的位置 - 它应该在 WinSxS 文件夹之一中查找。
幸运的是,对于我的第 3 方 DLL,我有源代码和原始 makefile,因此我能够生成正确的清单文件并使用 mt 命令将其嵌入到 DLL 中:
mt -manifest myDLL.dll.manifest -outputresource:myDLL.dll;2
在那之后,我能够正确加载 DLL,并且我的 R6034 错误消失了。
我的应用程序(使用 VS2015 编译)加载第 3 方 DLL(使用 VS2008 编译)。 运行 发布中的应用程序仅需要目标计算机上 MS 网页中的 VS2008 和 VS2015 可再发行组件。
运行 调试模式下的应用程序(例如在另一台开发人员机器上)需要 VS2008 的 debug 可再发行组件,应避免使用。复制第 3 方 DLL 旁边的 msvcX90d.dll 不会成功。有什么想法可以说服 Windows 加载 VS2008 调试运行时吗?我的应用程序需要清单吗?需要清单吗?
关于混合运行时的信息
是的,我对混合运行时不满意,但在我的上下文中,两个运行时不会相互干扰。并且重新编译第 3 方 DLL 不是一个选项。
进一步简化问题。如何在 VS2015 编译的应用程序中加载 msvcr90d.dll?
LoadLibrary(L"msvcr90d.dll");
阅读评论中的有用资源后,这是我在 VS2015(发布和调试)中加载 VS2008 (msvcr90d.dll) 的调试可再发行组件的方法。
首先,您的应用程序需要一个清单文件。什么是清单文件?此页面总结得很好:http://www.samlogic.net/articles/manifest.htm
A manifest is a XML file that contains settings that informs Windows how to handle a program when it is started. The manifest can be embedded inside the program file (as a resource) or it can be located in a separate external XML file.
清单文件可以放在我们的可执行文件旁边或嵌入(默认)。 switch/change 它转到 Projects Property Page -> Linker -> Manifest Tool -> Input and Output -> Embed Manifest
。
下面源代码中的编译指示将我们(默认情况下)的嵌入式清单文件添加到我们的可执行文件中。
转到
C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\redist\Debug_NonRedist\amd64\Microsoft.VC90.DebugCRT
并复制可执行文件旁边的所有文件打开新的
Microsoft.VC90.DebugCRT.manifest
并删除令牌publicKeyToken="1fc8b3b9a1e18e3b"
。如果它在里面,Windows 一直拒绝加载 msvcr90d.dll。请不要问我为什么。编译并执行你的程序
#include <Windows.h> #pragma comment(linker,"/manifestdependency:\"type='win32' "\ "name='Microsoft.VC90.DebugCRT' "\ "version='9.0.21022.8' "\ "processorArchitecture='amd64' "\ "\"") int main() { auto* lib = LoadLibrary(L"msvcr90d.dll"); if (!lib) { return -1; } FreeLibrary(lib); return 0; }
背景 为什么我们有一个外部清单文件 (Microsoft.VC90.DebugCRT.manifest) 和一个嵌入式清单文件(通过 pragma)用于此解决方案?看起来 pragma 只提供了有限的选项来让你的清单看起来像什么。一种选择是参考另一个包含更多信息的清单文件。
编辑: 这个 MSDN enter link description here 线程中的答案也很有帮助。
编辑 2: 无需从嵌入式清单引用外部 Microsoft.VC90.DebugCRT.manifest
,您可以将其嵌入到您的可执行文件中(也可以通过属性 页),但我得出这个结论为时已晚,但我的初步解决方案有望提供更多见解
我刚刚通过将我的第 3 方 DLL 与清单嵌入来解决了类似的问题。
运行 取决于我的第 3 方 DLL 显示它正在 C:\Windows\System32 中寻找 msvcr90.dll。显然,这不是正确的位置 - 它应该在 WinSxS 文件夹之一中查找。
幸运的是,对于我的第 3 方 DLL,我有源代码和原始 makefile,因此我能够生成正确的清单文件并使用 mt 命令将其嵌入到 DLL 中:
mt -manifest myDLL.dll.manifest -outputresource:myDLL.dll;2
在那之后,我能够正确加载 DLL,并且我的 R6034 错误消失了。