visual-c++visual-studio-2008side-by-sidevcredist

Microsoft vcredist uses later version at runtime than specified in the manifest


How does the Microsoft C++ redistributable package work?

I have a binary which is built in visual studio 2008. It uses the RunTime Library as "Multi-threaded DLL (/MD)". The version in the manifest is Microsoft.VC90.CRT" version="9.0.21022.8". I have chosen the option to embed the manifest to the binary.

When this binary is deployed in the target machine, it gives a runtime error stating that

The procedure entry point could not be located in the dynamic link library MSVCP90.dll

I understand that the version of msvcp90.dll which the machine contains by default, doesn't have a function that my binary is referring to.

Now I install the vc++ redistributable (vcredist_x86_9.0.30729.17) and run the binary again.

This time it works fine and I see that the loaded msvcp90.dll is of version 9.0.30729 instead of 9.0.21022.8.

How does this happen? How does my exe choose the latest version of msvcp90.dll even though the embedded manifest has the version as 9.0.21022.8?


Solution

  • I believe these variances are specific to the VS 2008 RTM vs the SP1.

    The manifest will specify the code's intent, necessary privileges, etc. However, the system will detect the dependencies even if a manifest doesn't exist. Your program depends on VC90 ver 9.0.21022.8 or greater. That is the only concern. The app.config however can assist in the specific version that is bound, similar to the following:

    <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    <configuration>
        <windows>
            <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
                <dependentAssembly>
                    <assemblyIdentity type="win32" name="Microsoft.VC90.CRT" processorArchitecture="x86" publicKeyToken="1fc8b3b9a1e18e3b"/>
                    <bindingRedirect oldVersion="9.0.30729.1" newVersion="9.0.21022.8"/>
                </dependentAssembly>
            </assemblyBinding>
        </windows>
    </configuration>
    

    In the app.manifest, you can set _BIND_TO_CURRENT_VCLIBS_VERSION to control this.

    The .h and .lib files determine the dependency.

    --> EDIT:

    Regarding your comment about the name mangled entry point _Xbad@tr1@std@@YAXW4error_type@regex_constants@12@@Z:

    (undecorated is void std::tr1::_Xbad(enum std::tr1::regex_constants::error_type))

    It is in fact found in the later SP1 MSVCP90.DLL (9.0.30729.17) Ordinal: 1513 (0x05E9)

    However it is not located in the older RTM version (9.0.21022.8) (Use dependency walker to view the entry points)

    You must have compiled your code with the latest .h and .lib for the linker to resolve the function, so it is curious why your dependency version would not be updated since your code requires a function which does not exist in the older version. I would ensure that your dependencies target the newer version. I hope this helps.