The dreaded "application configuration is incorrect" error

Periodically, I get asked the following question:

"When I build my program with Visual C++, it runs fine on my own machine, but whenever other people try running it they get an 'application configuration in incorrect' error. How do I fix this?"

...after which I groan and ask the person if they're doing anything else for the rest of the day, because this'll take a while to explain, and probably a lot longer to fix.

This error usually means that your program is set up to use the Visual C++ runtime library (CRT) in DLL mode, and the operating system can't find the versions that your program references. Should be simple -- find the right DLLs and include with the program? Well, no, it's a lot more complicated than that.

Where the CRT references come from

The reference to the C runtime library is added by the compiler, driven by the "Runtime Library" setting:

There are four settings here, arising from two choices: whether you want to use the statically linked (.lib) or dynamically linked (.dll) version, and whether want debugging features enabled or not. If you're statically linking the CRT, then the CRT is being merged directly into your EXE or DLL -- congratulations, you're done! You can skip to the end, because you don't have to worry about anything I'm describing here. Therefore, you should ask whether you need the DLL version of the CRT at all. If you're making a small, self-contained executable that doesn't use managed code, doesn't need to exchange heap memory with other DLLs in the same process and is less than a megabyte, you should just statically link the CRT and be done with it. Otherwise, you've got to pay attention to the CRT DLL that you're using.

What happens at compile time is that the compiler embeds a reference in the .OBJ file that tells the linker to include the library file CRT that you've selected. This can be msvcrt.lib or msvcrtd.lib for the DLL version, and libcmt.lib or libcmtd.lib for the statically linked version. The linker pulls the required lib from the standard LIB path and automatically links your executable with the CRT. This is why you can simply use "cl hello.cpp" or "cl /MT hello.cpp" on the command line, and everything will be automatically set up for you.

Which DLL do I need?

That raises the question of which DLL you actually need. Well, it could be one of several:

MSVCRT.DLL, MSVCRTD.DLL : Used by Visual C++ up to version 6.0, and by the Platform SDK (now Windows SDK) compiler. This one is fun because Windows ships with its MSVCRT.DLL, but the version that's in it depends on the version of Windows. Newer versions like Vista and above have additional functionality required by the newer VC8+ compiler included in the Windows SDK. It used to be common practice to compile programs against MSVCRT to avoid the need to redistribute it and to reduce EXE/DLL size, but I don't recommend that now that MSVCRT is a fast-moving target. (Plus, the Windows team never actually signed up for this responsibility....)

: Used by Visual C++ up to version 6.0, and by the Platform SDK (now Windows SDK) compiler. This one is fun because Windows ships with its MSVCRT.DLL, but the version that's in it depends on the version of Windows. Newer versions like Vista and above have additional functionality required by the newer VC8+ compiler included in the Windows SDK. It used to be common practice to compile programs against MSVCRT to avoid the need to redistribute it and to reduce EXE/DLL size, but I don't recommend that now that MSVCRT is a fast-moving target. (Plus, the Windows team never actually signed up for this responsibility....) MSVCR70.DLL, MSVCR70D.DLL : Visual Studio .NET 2002 (VC7). Hopefully everyone snagged the $18 upgrade deal and no one is using this terrible version any longer.

: Visual Studio .NET 2002 (VC7). Hopefully everyone snagged the $18 upgrade deal and no one is using this terrible version any longer. MSVCR71.DLL, MSVCR71D.DLL : Visual Studio .NET 2003 (VC7.1).

: Visual Studio .NET 2003 (VC7.1). MSVCR80.DLL, MSVCR80D.DLL : Visual Studio 2005 (VC8).

: Visual Studio 2005 (VC8). MSVCR90.DLL, MSVCR90D.DLL: Visual Studio 2008 (VC9).

There are additional DLLs associated with some C++ library and mixed mode features that you may need, denoted by 'm' and 'p' suffixes.

In current versions of Visual Studio, these DLLs are meant to be installed into the system and are installed via a program called vcredist_x86.exe or vcredict_x64.exe. You might be able to get away with not redistributing the DLL, especially since the VS2005 and VS2008 DLLs are typically installed by .NET, but you're taking a big risk by doing this and you really shouldn't rely on it. Microsoft's advice has always been that you need to redistribute the DLL yourself if you are using it, and this is good advice, because you're rolling the dice on the user's machine if you aren't. You don't want to spend time fielding reports like "your popup tool stops working when I uninstall Photoshop."

Microsoft's CRT installation advice, by the way, is in an article on MSDN called "Redistributing Visual C++ Files":

http://msdn.microsoft.com/en-us/library/ms235299.aspx?ppud=4

Avoiding installation

There are times that you want to avoid any installation on the target system, such as when you're pushing out daily builds to people on a team or on an automated test farm. In this case, you can copy the runtime DLLs onto the target system so that they're only used by a specific executable. In older versions of Visual C++, you could just copy the CRT DLLs next to the EXE. This no longer works starting with VS2005, where you'll get an error message about the DLL being incorrectly installed. This happens because starting with VS2005 the CRT relies on the manifest system to select and bind the CRT version. The short answer is that you need to copy the appropriate directories from the VC\redist\x86 or VC\redist\amd64 directory instead. In other words, for a VS2005-built application, you should have a directory called Microsoft.VC80.CRT next to the EXE, with DLLs and a .manifest file inside.

For people using VS2008, there is a nice gotcha involved. In my experience, due to the way CRT manifest binding works in that version, you must use the RTM version of the CRT DLLs for private deployment even if the application was built with VS2008 Service Pack 1. The reason appears to be that by default the built EXE or DLL references the RTM version and redirection is used to bind to the latest version, but this mechanism doesn't work when the CRTs are deployed as private assemblies.

Another gotcha you need to watch out for is that the debug CRT is not a redistributable component, so make sure you're not shipping modules that require it.

If after doing all of this you are still getting misconfigured application errors on launching your program, then you've got a bigger problem.

What happens when you're not paying attention

What happens if you have inconsistent Runtime Library settings in modules in your program? Well, you get the dreaded but common LNK4098 warning:

LINK : warning LNK4098: defaultlib 'MSVCRTD' conflicts with use of other libs; use /NODEFAULTLIB:library

What this means is that the linker has detected that you have CRT conflicts and has picked one of them to resolve it. Some people just shrug off the warning since it's not an error, and that's a bad idea since you don't know which CRT version you're going to get. Others follow the linker's poor advice and add MSVCRTD to the "Ignore Specific Libraries" list. While this gets rid of the warning, it creates a far worse problem relating to the manifest that I described earlier. The manifest is an XML file that is either next to the .EXE (foo.exe.manifest) or merged into the EXE/DLL itself as a resource of type RT_MANIFEST, and looks like this:

<?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.DebugCRT' version='8.0.50727.762'

processorArchitecture='x86' publicKeyToken='1fc8b3b9a1e18e3b' />

</dependentAssembly>

</dependency>

</assembly>

Prior to the manifest, DLLs were bound solely by the import list in the EXE/DLL, which gives the name of a DLL and a list of entry points to import. Manifests additionally say which version of the DLL to use. That there are two separate mechanisms involved in the CRT DLL resolution process should send a chill up your spine. Either the import list or the manifest can cause your program to fail to load, and the problem is that most people are only familiar with how to debug the import list, which leaves them dumbfounded when it's actually the manifest that's the problem. Remember that LNK4098 example I showed earlier? Well, after adding /NODEFAULTLIB:MSVCRTD, the executable's import list only shows MSVCRT.DLL, and all is good... except for the manifest:

<?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.DebugCRT' version='8.0.50727.762'

processorArchitecture='x86' publicKeyToken='1fc8b3b9a1e18e3b' />

</dependentAssembly>

</dependency>

<dependency>

<dependentAssembly>

<assemblyIdentity type='win32' name='Microsoft.VC80.CRT' version='8.0.50727.762'

processorArchitecture='x86' publicKeyToken='1fc8b3b9a1e18e3b' />

</dependentAssembly>

</dependency>

</assembly>

Surprise! Our guinea pig executable now references both the debug and non-debug versions of the CRT and will fail to load if either is missing. I'll resist the urge to make an "XML makes it better" joke... oops, too late.

It can get much worse than this when you realize that not only can you have debug and non-debug versions of the CRT involved, but also versions from different service packs and even different versions of the compiler -- I've seen cases where people had a VC8 CRT and three versions of the VC9 CRT in the manifest. At that point you're fairly screwed from the deployment side and you need to fix the build itself. The right way to fix this is to hunt down every path that is bringing in the wrong version of the CRT and make sure that all of them are rebuilt with the same version of the compiler, at the same service pack level, and with the same Runtime Library setting.

The nightmare of tracking this down is when you have static libraries (.libs) checked in, either pre-built or from a vendor. This is when you discover that the prebuilt .lib doesn't rebuild properly from source anymore, or it wasn't ever upgraded and rebuilt in the last compiler upgrade, or you can't find the source, or it comes from a vendor and you have to negotiate with them to get an updated version. It's very important to make sure that everything required to rebuild your prebuilt libs is checked into source code control and that you track the upstream sources for all of your externally supplied libs, or you could get into a situation where you can't resolve a mixed CRT version situation properly. The other nightmarish part is actually finding the .libs that are causing the problem. If the problem is a debug/release conflict, you can link with /VERBOSE and check who is bringing in the debug CRT, but if it's a version conflict, this is the only good way I know of is by brute force scanning the libs:

for /r %x in (*.lib) do (@echo "%x" && strings -a "%x" | grep -r- "Microsoft.VC")

Track down and fix each offender one by one until there is only one CRT left in the manifest.

There is an alternative option, by the way, which is that you can force the manifest. The way the build process normally works is that LINK produces a .manifest file, and the manifest tool (mt.exe) is then called to merge that into the executable. You can disconnect this link and reconfigure the Manifest Tool step to reference a manifest of your choosing instead. I haven't explored this path, though, and it's risky since you're still combining components that were intended to be used with a different version of the CRT than it being loaded. It may be your only option if for some reason you can't fix and rebuild the offending modules.

When it turns ugly

One aspect where this can turn ugly is when you have external components supplied by a vendor. In that case, you may either have a .lib that you can't rebuild yourself or a .dll that has its own CRT version reference. In that case, you have to hope that everything references exactly the same version or that you can force them to do so by fudging the manifest. Static libraries are such a problem in this regard that some vendors have stopped distributing .libs entirely and only distribute code to licensees in either source code form or as a DLL. You may be in trouble if it turns out that all you have is a .lib built with Visual Studio 2005 and the company that gave it to you is now out of business. Source code form, of course, will give you the most control and allow all of these problems to be avoided, but may be expensive or infeasible.

The other ugly case has to do with an ATL security patch that went out several months ago. This patch can cause a CRT version mismatch problem in your build because it also updates the CRT and can change the version referenced by your build even if you aren't actually using ATL. I haven't seen this problem on my own computers but I have seen ugly cases where CRT load failures started happening in automated builds because the patch wasn't deployed consistently between developer machines and autobuild machines. This is how you get nasty situations where two people with apparently identical development configurations compile the same program and only one of the builds works in the field: only one of them has the ATL update installed. If you have version problems and see both the SP1 and the ATL update version of the CRT showing up in the manifest, you've been bitten by this problem and need to either force the CRT version or deploy the patch to all build and dev machines.

What this all comes down to is that you need to track all dependencies that are included in your program and test both the internally deployed and installed forms of your program on a clean, unpatched install of Windows to be sure that it'll work properly in the field.

The future

CRT deployment is apparently changing in Visual Studio 2010, as the CRT is back to using a plain, non-WinSxS DLL. I don't know how this will work out, but it's possible that much of what I've described above will no longer be a problem in VS2010. Until then, keep your hex editor or resource editor handy, and check the manifest every time your program fails to load on someone's machine.