Search code examples
c++visual-c++visual-studio-2005msvcrt

How to buid a Visual C++ project targeted to a specific Visual C++ Redistributable version


I have a C++ native library that I am building with Visual Studio 2005 that is a part of a larger project.

This project usually contains several other dlls including the Microft C++ Redistributable Package libraries (msvcr80.dll for example). This way we can deploy our project without having to make the user install the Microsoft Visual C++ Redistributable Package 2005.

The problem is that whenever I put my library into this larger project I get the following error:

This application has failed to start because the application configuration is incorrect. Reinstalling application may fix this problem.

To solve this I've looked through which version of the Visual Studio CRT my dll was using and which version of it the larger project was using and as it turns out they are different.

Below is the manifest for the larger project:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
    <noInheritable></noInheritable>
    <assemblyIdentity type="win32" name="Microsoft.VC80.CRT" version="8.0.50727.4053" processorArchitecture="x86" publicKeyToken="1fc8b3b9a1e18e3b"></assemblyIdentity>
</assembly>

And this is what I got from my library:

<dependency>
    <dependentAssembly>
      <assemblyIdentity type="win32" name="Microsoft.VC80.CRT" version="8.0.50727.6195" processorArchitecture="x86" publicKeyToken="1fc8b3b9a1e18e3b"></assemblyIdentity>
    </dependentAssembly>
</dependency>

I then did some research on the web and found out at least two methods to manually change the CRT version of my dll.

The first one is to set the following macro in my project:

#define _CRT_ASSEMBLY_VERSION "8.0.50727.4053"

And the second one is detailed on this post.

I've tried both of them, but neither worked.

As for the first one, I've added the _CRT_ASSEMBLY_VERSION to one of my project's header file, but it didn't change its CRT version. Also if I have more than one project, do I have to add this macro to all of them?

As for the second one I've changed my library's manifest to:

<?xml version='1.0' encoding='UTF-8' standalone='yes'?>
<assembly xmlns='urn:schemas-microsoft-com:asm.v1' manifestVersion='1.0'>
    <dependency>
        <dependentAssembly>
            <assemblyIdentity type='win32' name='Microsoft.VC80.CRT' version='8.0.50727.4053' processorArchitecture='x86' publicKeyToken='1fc8b3b9a1e18e3b' />
        </dependentAssembly>
    </dependency>
</assembly>

But now my library is being generated without the tag inside it.

Finally please note that I greatly prefer if I could use the first method, since its simpler and is something that goes right into the code, this way I don't have to keep remembering to maintain a separate manifest file for my projects.


Solution

  • however that is a highly controlled environment

    Which is the problem, that machine hasn't received the latest security updates for the CRT. If that machine is also the originator of the installer then you'll certainly get the problem you describe, you are asking for a DLL version that's not available on the machine.

    Deploying files to a user's machine that has known security problems is definitely a kind of policy that needs to be reviewed. Defining the _CRT_ASSEMBLY_VERSION macro is the correct approach, but do consider setting that macro in the project settings instead of your source file so you can be absolutely sure that it is set before vc/include/crtassem.h gets #included. Project + Properties, C/C++, Preprocessor, Preprocessor definitions setting.

    And yes, certainly on all your projects.