在使用 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

  1. 下面源代码中的编译指示将我们(默认情况下)的嵌入式清单文件添加到我们的可执行文件中。

  2. 转到 C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\redist\Debug_NonRedist\amd64\Microsoft.VC90.DebugCRT 并复制可执行文件旁边的所有文件

  3. 打开新的 Microsoft.VC90.DebugCRT.manifest 并删除令牌 publicKeyToken="1fc8b3b9a1e18e3b"。如果它在里面,Windows 一直拒绝加载 msvcr90d.dll。请不要问我为什么。

  4. 编译并执行你的程序

    #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 错误消失了。