4

My app (compiled with VS2015) loads a 3rd party DLL(compiled with VS2008). Running the app in release requires only the redistributables for VS2008 and VS2015 from the MS webpage on the target machine.

Running the app in debug mode (e.g. on another developer machine) requires the debug redistributables of VS2008, which should be avoided. Copying the msvcX90d.dll next to the 3rd party DLL does not lead to success. Any ideas how I can convince Windows to load the VS2008 debug runtime? Does my application need a manifest and which one is it?

FYI about mixing runtimes

Yes, I am not happy with mixed runtimes but in my context both runtimes will not intefer with each other. And recompiling the 3rd party DLL is not an option.

To simplify the problem even more. How can I load msvcr90d.dll in a VS2015 compiled application?

LoadLibrary(L"msvcr90d.dll");

enter image description here

HelloWorld
  • 2,392
  • 3
  • 31
  • 68
  • Check this [universal-crt](https://learn.microsoft.com/en-us/cpp/porting/upgrade-your-code-to-the-universal-crt) – Victor Gubin Mar 16 '18 at 19:56
  • 1
    Thanks, but as far as I can see this only refers to improvements of the VS2015 (and higher) redistributables. My problem is actually the VS2008 lib – HelloWorld Mar 16 '18 at 20:03
  • It is also saying - you no longer need to redistribute CRT with your app. Since starting from VC 15 it is a part of Windows OS. According to the Q update you also need a [manifest](https://msdn.microsoft.com/en-us/library/ms235542.aspx) – Victor Gubin Mar 16 '18 at 20:10
  • 1
    It will not remove the 3rd party `.dll` dependency of VS 2008 CRT. – drescherjm Mar 16 '18 at 20:11
  • 1
    And you don't need to. But you can avoid re-distribute VC 17 CRT. One more link with the [solution](https://blogs.msdn.microsoft.com/nikolad/2007/03/29/a-solution-to-two-references-to-different-versions-of-crt-mfc-atl-in-one-application-manifest-file/) – Victor Gubin Mar 16 '18 at 20:13
  • "Workaround#1: Install the newer version (8.0.50727.762 in this case) of VC++ MSMs or VCRedist.EXE on a machine where your application is going to run. Once policy for VC++ assemblies is installed on that machine they are going to redirect all loads of older versions (8.0.50608.0) to the newest version available on the machine." – Victor Gubin Mar 16 '18 at 20:20
  • The app expects a debug redist - these calls get redirected to a release redist. Btw, thanks for the multi crt manifest link! That looks very promising – HelloWorld Mar 16 '18 at 20:25
  • 2
    There is no debug redist. The only legitimate way to install the debug runtimes is to install the appropriate development environment. In this case you need to install VS 2008. – Richard Critten Mar 16 '18 at 21:28
  • Yes, there is none, that was my point. But I just found out a non-hacky way how to do (without installing VS2008). I will post it as an answer. – HelloWorld Mar 16 '18 at 21:35

2 Answers2

2

After reading the helfpful resources from the comments, here is my approach how to load the debug redistributable of VS2008 (msvcr90d.dll) in VS2015 (release and debug).

First your application needs a manifest file. What is a manifest file? This page summarizes it pretty well: 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.

A manifest file can be placed next to our executable OR is embedded (default). To switch/change it go to Projects Property Page -> Linker -> Manifest Tool -> Input and Output -> Embed Manifest.

  1. The pragma in the source below adds a few lines to our (by default) embedded manifest file into our executable.

  2. Go to C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\redist\Debug_NonRedist\amd64\Microsoft.VC90.DebugCRT and copy all files next to your executable

  3. Open the new Microsoft.VC90.DebugCRT.manifest and remove the token publicKeyToken="1fc8b3b9a1e18e3b". If it is inside, Windows keeps rejecting to load the msvcr90d.dll. Please don't ask me why.

  4. Compile and Execute your program

    #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;
    }
    

Background Why do we have an external manifest file (Microsoft.VC90.DebugCRT.manifest), and an embedded one (through the pragma) for this solution? It looks like the pragma only offers a limited amount of options how your manifest can look like. One option is to reference to another manifest file which contains more information.

enter image description here

enter image description here

Edit: The answers in this MSDN enter link description here thread also helped a lot.

Edit 2: Instead of referencing from the embedded manifest to the external Microsoft.VC90.DebugCRT.manifest, you could already embed this one to your executable (can also be done by the Property Pages), but I came to this conclusion just too late but my initial solution hopefully gives some more insights

HelloWorld
  • 2,392
  • 3
  • 31
  • 68
1

I just solved a similar problem by embedding my 3rd-party DLL with a manifest.

Running depends on my 3rd-party DLL showed that it was looking for msvcr90.dll in C:\Windows\System32. Obviously, that's not the correct location - it should be looking in one of the WinSxS folders.

Luckily, for my 3rd party DLL, I had the source code and original makefiles, so I was able to generate the correct manifest file and embed it in the DLL using the mt command:

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

After that, I was able to load the DLL correctly and my R6034 error went away.

James
  • 270
  • 1
  • 10