If you create a default CRT/MFC application with VS2008, this application will not run on other computers. You application will complain with
“This application has failed to start because the application configuration is incorrect”.
The problem is that by default VC2008 uses the DLL-version of the CRT/MFC. These DLLs are not pre-installed on any OS.
To overcome this problem, you have tree options:
- Statically link to the CRT/MFC
- Use vcredist_x86.exe / vcredist_x64.exe to install the DLLs in the system
- Deploy the CRT/MFC DLLs with your application (in the same directory)
In the following I will explain the last option. Especially in conjunction with VS2008 service pack 1 (SP1). Because this leads to a little bit more compications in ApppLocal deployment.
In general, it is very easy to deploy your application with the needed CRT/MFC DLLs.
Just copy the contents of the directory
- C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\redist\x86\Microsoft.VC90.CRT
- C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\redist\x86\Microsoft.VC90.MFC
into the same directory as your application. Then you should have the following files in your app-folder:
Microsoft.VC90.CRT.manifest
msvcr90.dll
msvcp90.dll
msvcm90.dll
Microsoft.VC90.MFC.manifest
mfc90.dll
mfc90u.dll
mfcm90.dll
mfcm90u.dll
Then your application works on an other computer!
BUT: This does not work, if you installed VS2008-SP1 🙁
The problem with VS2008 SP1 is: It overwrites all files in the “VC\redist” directory with the new version. This is not really bad. The problem is: It has a newer version number inside the manifest files. But if you compile your application with VS2008-SP1 it write the RTM-version into the application manifest! Now the version number in your application manifest does not match the version in the “new” CRT/MFC manifest. Therefore it will refuse to load these DLLs and your application cannot start.
The simplest way to overcome this problem is by changing the “Microsoft.VC90.CRT.manifest” and “Microsoft.VC90.MFC.manifest” files. Replace the version attribute in both Microfot.*.manifest files from “9.0.30729.1” (or whatever version/SP you have) to the version number in your applications-manifest (which is normally “9.0.21022.8” (RTM)).
Old:
version="9.0.30729.1"
New:
version="9.0.21022.8"
Then your application will work on an OS without installing anything.
Alternatively, you can change your applications manifest, so that it uses the new version number. This can easily done by defining
#define _BIND_TO_CURRENT_VCLIBS_VERSION 1
in stdafx.h (at the top) or in your project settings. This will embed the actual CRT/MFC-version into your applications manifest (works starting with VS2008-SP1).
Also, if you use new features from the MFC-feature-pack, you should always define this!
Just a small note: You should be aware, that this “AppLocal” installation is not really “AppLocal”… it is only AppLocal, if the vcredist_*.exe was not installed. If the vcredist_*.exe is installed, then the DLLs from the WinSxS directory will be used. If you want to prevent this, you can do a really AppLocal deployment.
A small addition: If you write .NET-apps (/clr) you still must install the .NET Framework redistributable.
But the goood news is: Starting with VC2010, the manifest (WinSxS) is gone 😉
Hi.. Thanks for the information.. Currently I have the same problem, but I use VC 2005. Is that same steps?
Yes. There are the same steps… expect the version numbers are different; you need to look at your applications-manifest to lookup the correct version number.
Would it be possible to link to the VC80 libraries within VC2008 ?
We have a lot of systems around with the 2005 redist already installed. We would like to develop using VC2008 but when we update our software we don’t like to install a lot of new dependencies.
Thx
No, this is not possible.
The easiest way is to use static linking:
http://blog.kalmbach-software.de/2008/03/03/screencast-statically-link-to-the-c-runtime-to-prevent-vcredist-and-overcome-application-configuration-problems/
I have updated my dlls and manifest files to the new version, 9.0.30729.4148 and my exe won’t run. I have opened my .exe file and it is looking for old version (9.0.30729.1). I found the ***.exe.intermediate.manifest in the Release dir. It says old version. I can’t figure out what creates ***.exe.intermediate.manifest since it is created during the build.
Figured it out…It’s a long story. If anyone wants to hear it, let me know.
Hello Jochen,
Thanks for the useful article. The described technique work also fine for deploying of debug versions, by working with corresponding debug folders and manifest files:
(Microsoft.VC90.DebugCRT, Microsoft.VC90.DebugCRT.manifest, etc.)
Currently I work on a VS2008 solution that contain 4 executables and 18 dlls, and deploying debugs is a practical (for Testers, PMs, etc. purposes).
And further, even the Common Control Dll (comctl32.dll) can be deployed locally, skipping the WinSxS. This can be done with the following steps:
1. Create a folder “Microsoft.Windows.Common-Controls” in deployment exe folder, for example
MyApp\exe\Microsoft.Windows.Common-Controls
2. copy comctl32.dll file from C:\WINDOWS\WinSxS\x86_Microsoft.Windows.Common-Controls_6595b64144ccf1df_6.0.0.0_x-ww_1382d70a folder
into MyApp/exe/Microsoft.Windows.Common-Controls folder
3. copy x86_Microsoft.Windows.Common-Controls_6595b64144ccf1df_6.0.0.0_x-ww_1382d70a.Manifest file from C:\WINDOWS\WinSxS\Manifests folder
into MyApp/exe/Microsoft.Windows.Common-Controls folder
4. rename x86_Microsoft.Windows.Common-Controls_6595b64144ccf1df_6.0.0.0_x-ww_1382d70a.Manifest to Microsoft.Windows.Common-Controls.Manifest
5. remove publicKeyToken from this new manifest (Microsoft.Windows.Common-Controls.Manifest)
6. in all dlls and exes manifests remove publicKeyToken from the section described “Microsoft.Windows.Common-Controls”.
Now comctl32.dll is deployed locally, and WinSxS is bypassed.
Best regards,
Svetoslav Kyuchukov
Eurorisksystems Ltd.
Varna, BG
Thanks for the _BIND_TO_CURRENT_VCLIBS_VERSION tip!
Thank you very much for the tip about manually correcting the version in the manifest files. I never would have guessed that they’d ship a bogus manifest with the DLLs.
Setting version=”9.0.21022.8″ worked perfectly for me.
You are a star, sir. This page has been really helpful. Thankyou.
Fantastic. Thanks.
_BIND_TO_CURRENT_VCLIBS_VERSION tip worked for me.
Pingback: Troubleshooting VC++ Side by Side Problems « DAVID Systems – R&D Blog
Pingback: Articles about _bind_to_current_vclibs_version 1 volume 2 « Article Directory
Hello Jochen,
thanks for that very helpful advice. I spend day and days investigating that matter… without a solution.
Your my hero!
Greetings,
Dirk
Hallo all,
after a half a year of using VS2010 i switched back to VS2008, cause i found VS2010 mostly unusable. It’s much slower, unstable, compiling and linking is slower, the new data format of Class viewer and browser information is big shit, runtime has errors or unforseeable effects… and so on.
Now that i had this manifest hell again, i found out a easy solution for that problem. I know, it’s looking horrable, but its the most efficent way to overcome this ERROR, that Mircosoft made:
Edit the crtassem.h in C:\Program Files\Microsoft Visual Studio 9.0\VC\include directory to always define _BIND_TO_CURRENT_VCLIBS_VERSION.
Like this:
#if !defined(_BIND_TO_CURRENT_VCLIBS_VERSION)
#define _BIND_TO_CURRENT_VCLIBS_VERSION 1
#endif
or change the original
#ifndef _CRT_ASSEMBLY_VERSION
#if _BIND_TO_CURRENT_CRT_VERSION
#define _CRT_ASSEMBLY_VERSION “9.0.30729.1”
#else
#define _CRT_ASSEMBLY_VERSION “9.0.21022.8”
#endif
#endif
to
#ifndef _CRT_ASSEMBLY_VERSION
#if _BIND_TO_CURRENT_CRT_VERSION
#define _CRT_ASSEMBLY_VERSION “9.0.30729.1”
#else
#define _CRT_ASSEMBLY_VERSION “9.0.30729.1”
#endif
#endif
Theres one more thing:
If you really have a manifest problem and guessing why, just let windows trace the loading of the application with
sxstrace Trace -logfile:log.bin
start your program, then
sxstrace Stoptrace
and convert the logfile to human readable format with
sxstrace Parse -logfile:log.bin -outfile:log.txt
With this, your can see a protocol of loaded and found sxs-dlls, manifests and so on. Very interesting…
Good luck!
Even after using macro and making changes inside crtassem.h still my MFC and ATL are picking wrong version