1
votes

We're distributing the Visual C++ runtimes as private assemblies (i.e., putting msvcp90.dll, msvcm90.dll, msvcr90.dll, and Microsoft.VC90.CRT.manifest into a Microsoft.VC90.CRT folder that exists in the same directory as our app's executable). So far, on every non-dev machine (several hundreds), this has been fine. However, I have been tracking down one particular problem machine that is completely unable to find these assemblies.

They're running XP, so when they try to launch our app, they get the message:

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

I had them run Dependency Walker on our app's exe, and it indicated that it could not find msvcp90.dll or msvcr90.dll. I then had them trace out the directory contents of our app, which revealed that those "missing" DLLs were in fact where they were supposed to be (inside the Microsoft.VC90.CRT directory adjacent to the exe), but nevertheless, the app just isn't finding them when it starts up.

As a last resort, I am having them install the redistributables directly, but this is mainly just for troubleshooting, as we'd prefer to continue to distribute the DLLs without having an additional installer (our app can simply get run without any installation).


I should probably also include our app's own manifest:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
  <assemblyIdentity version="1.0.0.0" processorArchitecture="X86" name="OurApp.Name" type="win32"/>
  <description>Our App Description</description>
  <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
    <security>
      <requestedPrivileges>
        <requestedExecutionLevel level="asInvoker" uiAccess="false"/>
      </requestedPrivileges>
    </security>
  </trustInfo>
  <dependency>
    <dependentAssembly>
      <assemblyIdentity type="win32" name="Microsoft.VC90.CRT" version="9.0.21022.8" processorArchitecture="x86" publicKeyToken="1fc8b3b9a1e18e3b">
      </assemblyIdentity>
    </dependentAssembly>
  </dependency>
</assembly>

Edit: I previously mentioned that there wasn't a dependentAssembly, but I realized it was being generated, so the above manifest reflects the actual manifest it creates.


What can cause a program to simply not find these dependencies? It finds them just fine on many other computers, most of which have never seen these runtimes before. I'm probably messing up something basic (most likely in my manifest), but it runs fine on 99% of client computers so far.

As a bonus, this article is a nice summary of private assemblies, but so far it hasn't helped resolve things for me.

Update: After moving the DLLs into the same directory as the EXE, it still failed to launch. Then, after installing the redistributables, it launched fine. So it seems like it either wasn't looking in the local directories, or for some reason deemed the local DLLs unacceptable.

2

2 Answers

1
votes

Is there any version of Visual Studio currently installed in that same Windows machine?

You may also take a close look at http://msdn.microsoft.com/en-us/library/windows/desktop/ms682586(v=vs.85).aspx. This link contains information about how the operating system searches for the DLLs. There are a few registry keys that might change that behaviour.

Other option to eliminate this dependency is to use static link with MFC/ATL in your project. Your binaries will be larger, but you eliminate this issue all together..

0
votes

I meant to get back to this sooner, but it was on the back burner waiting for a test case. It turns out it was a remarkably simple problem: it was looking for the wrong DLL version. The manifests that were generated by VS were not set to use the same version of the redistributables that I had extracted from VS. By disabling autogeneration of the manifests and just setting the version in my own manifest to match the version of the DLLs I'm redistributing, it works.