【问题标题】:Loading debug redistributables of VS2008 in app which got compiled with VS2015 fails在使用 VS2015 编译的应用程序中加载 VS2008 的调试可再发行组件失败
【发布时间】:2018-08-25 23:32:42
【问题描述】:

我的应用程序(用 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 lib
  • 它不会删除 VS 2008 CRT 的第 3 方 .dll 依赖。
  • 你不需要。但是可以避免重新分发 VC 17 CRT。与solution的另一个链接
  • 没有debug redist。安装调试运行时的唯一合法方法是安装适当的开发环境。在这种情况下,您需要安装 VS 2008。

标签: c++ windows visual-studio visual-studio-2015 dllimport


【解决方案1】:

从 cmets 读取有用的资源后,这是我如何在 VS2015(发布和调试)中加载 VS2008 的调试可再发行组件(msvcr90d.dll)的方法。

首先,您的应用程序需要一个清单文件。什么是清单文件?这个页面总结得很好:http://www.samlogic.net/articles/manifest.htm

清单是一个 XML 文件,其中包含通知 Windows 的设置 程序启动时如何处理。清单可以是 嵌入在程序文件中(作为资源)或者它可以位于 在单独的外部 XML 文件中。

清单文件可以放在我们的可执行文件旁边或嵌入(默认)。要切换/更改它,请转到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,您已经可以将此嵌入到您的可执行文件中(也可以通过属性页完成),但我来了得出这个结论为时已晚,但我最初的解决方案希望能提供更多见解

【讨论】:

【解决方案2】:

我刚刚通过将我的第 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 错误消失了。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-10-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多