在使用VS2015编译的应用程序中加载VS2008的调试可再发行组件失败

时间:2018-03-16 19:53:47

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

我的应用(使用VS20 15 编译)加载第三方DLL(使用VS20 08 编译)。在发布中运行应用程序只需要从目标计算机上的MS网页获取VS2008和VS2015的可再发行组件。

在调试模式下运行应用程序(例如在另一台开发人员计算机上)需要VS2008的 debug 可再发行组件,这应该避免。复制第三方DLL旁边的msvcX90 d .dll不会导致成功。任何想法如何说服Windows加载VS2008调试运行时?我的应用程序是否需要清单以及它是哪一个?

关于混合运行时的FYI

是的,我对混合运行时不满意,但在我的上下文中,两个运行时都不会互相干扰。并且重新编译第三方DLL不是一种选择。

进一步简化问题。如何在VS2015编译的应用程序中加载msvcr90d.dll?

LoadLibrary(L"msvcr90d.dll");

enter image description here

2 个答案:

答案 0 :(得分:2)

从评论中读取了很多资源后,我的方法是如何在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. 下面的源代码中的pragma为我们的(默认情况下)嵌入式清单文件添加了几行到我们的可执行文件中。

  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;
    }
    
  5. <强>背景 为什么我们有一个外部清单文件(Microsoft.VC90.DebugCRT.manifest),以及这个解决方案的嵌入式文件(通过编译指示)?看起来pragma只提供了有限的选项,你的清单看起来如何。一种选择是引用另一个包含更多信息的清单文件。

    enter image description here

    enter image description here

    编辑:此MSDN enter link description here帖子中的答案也有很大帮助。

    编辑2:您可以将此嵌入清单嵌入到您的可执行文件(也可以通过“属性页”),而不是从嵌入式清单引用到外部Microsoft.VC90.DebugCRT.manifest,但是我得出这个结论为时已晚,但我的初步解决方案希望能提供更多见解

答案 1 :(得分:1)

我只是通过在清单中嵌入第三方DLL解决了类似的问题。

运行取决于我的第三方DLL,表明它正在C:\ Windows \ System32中寻找msvcr90.dll。显然,这不是正确的位置-应该在WinSxS文件夹之一中查找。

幸运的是,对于我的第三方DLL,我拥有源代码和原始的makefile,因此我能够生成正确的清单文件,并使用mt命令将其嵌入DLL中:

mt -manifest myDLL.dll.manifest -outputresource:myDLL.dll;2

之后,我能够正确加载DLL,而我的R6034错误消失了。