This is the source code of an amended version of Vcredist_x86.exe, the redistributable distributed by Microsoft. Microsoft forgot to include the required Windows Installer 3.1 in the redistributable. The above file comes with a bootstrapper that detects if any prerequisites are missing and installs the required runtimes.

This article is also a compilation of the various forum/usenet/message board postings and findings on the topic of C++ deployment in Visual C++ 2005.

This section mostly applies to programs built from the command line (with cl or nmake). Although, you can reproduce the same from the IDE, it requires changing numerous project settings, and if you're doing this, I assume you already know what you're doing!

You've set up the Visual Studio environment and compiler, you've successfully built your project, and now your ready to test your VC++2005 app. However, before it is able to start up, you get an error:

And you want to know what's going on.

Programs compiled with Microsoft Visual C++ that dynamically link to the C runtimes (/MD or /MDd) have to bundle with them a copy of the C-runtime DLLs (usually called MSVCRT.DLL or MSVCRxx.DLL where xx represents the version of Visual C++). If you just copy the .EXEs but forget to copy MSVCRxx.DLL along with it, you'll get the above error.

Okay, you note that MSVCR80.dll isn't located in System32. It is located in another directory (C:\WINDOWS\WinSxS\x86_Microsoft.VC80.CRT_1fc8b3b9a1e18e3b_8.0.50727.42_x-ww_0de06acd). You copy it from there to System32 (or if you're a veteran from the DLL hell days, you'll know better and copy the DLL to your app directory instead) and you try to run it again:

.

This error occurs whether you copy it to your application directory or System32. The release build gives you a slightly different error message, but still mostly the same.

Visual Studio 2005 made a number of changes to the way the C-runtime library is linked in. The first change is that the single threaded libraries are now gone. If you need the performance boost that the single threaded libraries provided and are willing to sacrifice thread safety, you should make use of the nolock variants of the CRT library functions. The second change is that projects created with VC2005 IDE now dynamically link to the C-runtime libraries by default. In VC2003, only MFC and managed C++ apps dynamically linked to the CRTs by default.

Finally, the C and C++ runtimes are now implemented as Side-by-Side DLLs. It's no longer enough to copy MSVCR80.DLL/MSVCP80.DLL/MSVCM80.DLL (from now on called the CRT DLLs) into the System32 directory. You must now load the CRT DLLs through a manifest. If you attempt to load the CRT DLLs without using a manifest, the system will detect this, raise an R6034 assertion, and abort(). That's why the CRT DLLs are now located in WinSXS and not in the System32 directory.

If you go back to the build directory, you will notice that there is a new manifest file called <appname>.exe.manifest (if it's not there, then remove the /MANIFEST:NO switch from the linker command line). You can either copy this manifest to the local directory, or you can embed this as a resource of your executable:

(This part applies to builds made in the VS IDE and command line builds that followed the previous section). You've built your app, and now you attempt to run it on your machine. At last your program runs properly:

However, when you try to run on another machine (a machine that does not have Visual C++ installed), you receive this message:

A bit of troubleshooting (Dependency Walker) tells you that it has something to do with the CRT DLLs, but you cannot figure out where to put those darn DLLs. You've copied msvcr80.dll to the System32 directory, the application directory, even the WinSXS directory. It still doesn't work. What's going on?

Now that your app is configured to load the CRTs through a manifest, the CRT DLLs must now be placed in a directory recognized by the side-by-side technology. You can either load the CRT DLLs via a shared side-by-side assembly, or through applocal assemblies. Applocal assemblies are covered in a later section (see below). First, we will cover how to install the CRTs as a shared side-by-side assembly.

If you choose to install a shared side-by-side assembly, they will need to be installed with a Windows Installer setup project (copying doesn't work). The setup will create policies, manifests, and some registry keys to the HKLM registry (the manifests and policies are important for the side-by-side engine to recognize the isolated library).

You cannot use a third party setup to install a shared side-by-side assembly. That part of the setup must be performed by a Windows Installer package. It's bad news if you're using Express Edition (which doesn't have the ability to create setup projects).

For older Windows (Win2K and below), there is no such concept as a side-by-side DLL, and the CRT DLLs will need to be installed either in the System32 directory or the same folder as the application. All this means that you have to create a complicated installer that behaves differently on different operating systems (even the service pack level of the OS can alter the behaviour of your installer).

Fortunately, Microsoft has already written a merge module that does all this for you (including registering the side-by-side DLL). Look in the "\Program Files\Common Files\Merge Modules" to find a set of MSM files (ignore the properties that say it's Beta 2. It actually installs the final release). The files that have "CRT" in their names are the ones you need to redistribute (if you use MFC/ATL, you'll also need the other MSMs). By including these files in your setup project, your setup will properly install the runtime DLLs in the correct location.

If you're not using Windows Installer, you can use the executable located in "\Program Files\Microsoft Visual Studio 8\SDK\v2.0\Bootstrapper\Packages\vcredist_x86\vcredist_x86.exe". All you have to do is execute this redistributable in your third party setup.

However, there is a major bug with the current version of the merge modules. Before you install the runtime redistributables you have to ensure the following components are installed first:

For example, if you're trying to run your app on a Win2K computer, you have to download the latest Windows 2000 service pack (SP4), install that, reboot, then download Windows Installer 3.1, install that and reboot. Then finally, you need to copy the vcredist_x86 file and install that. Such a number of steps (which significantly alters the operating system, requires many reboots, and probably breaks the existing apps) are very inconvenient for an end user. If any one of these components is not present, the merge module will fail with a nondescript error at the end user's expense (I got an error 1723 when testing). This complex install process was a design decision made by Microsoft.

Although there are changes coming for SP1, I couldn't wait for that to be released, so I came up with my own installer that included all the necessary updates in it. And this is the topic of this article.

The code is for a bootstrapper that detects the presence of C-runtimes and if not present, installs them. If either Internet Explorer or Windows Installer needs to be updated, the user is presented with a dialog asking to install them as well. The main components are launched in an interactive mode with the /norestart switch set to prevent them from rebooting the computer. If you want to change this, you'll need to alter the InstallRequiredApps() function in my source. You'll also need to download each component separately:

Detecting Internet Explorer is done through checking the value of the "Version" string in HKLM\Software\Microsoft\Internet Explorer. The version of Windows installer is checked by calling the DllGetVersionInfo export from MSI.DLL. The Windows version is checked through the GetVersionEx() API. In order to detect if the CRTs are installed, I have created a simple DLL that dynamically links to the C runtimes. If a call to LoadLibrary() fails for this DLL, we know that the C-runtimes are not installed and should install them.

The bootstrapper's binaries will be compressed with IExpress (the package and deploy wizard bundled with Windows). The IExpress packager works in all 32-bit versions of Windows, checks for binary integrity (e.g. bad downloads), and automatically determines a writable temporary directory (for LUAs). Although, we could implement these features ourselves (that's what earlier editions of this article did), I'd rather make use of externally tested code than attempt to reinvent the wheel.

When you make a bootstrapper application (that needs to run on every OS from NT3.x to Windows Vista), you have to be very careful about which APIs you invoke, and how you run your app (static link only, no shlwapi, no MFC, no internet, no ATL, no .NET, no debug helpers, etc.). Unfortunately, Visual C++ 2005 makes code that is inherently unrunnable in older Windows (it needs GetLongPathNameW() and IsDebuggerPresent() to be present in Kernel32.dll). If you want my bootstrapper to run on older Windows OSes (even if it's just a message box telling the user the program cannot run on this OS), you have to use an older compiler, such as VC6.

And that should be it. The return numbers returned by my bootstrapper are:

0: if the install succeeded or was not needed.

3: if an uncaught exception was thrown (e.g. if a system resource allocation failed), or abort() was called.

If you dynamically link to the MFC DLLs and make use of its data access classes, you'll have to include a whole bunch of redistributables (such as the updated common controls, the MDAC, and DCOM update). And if you use its internet related classes, you'll have to update the version of Internet Explorer. Note that the requirement of IE is only for MFC. If you don't use MFC, you don't need to redistribute Internet Explorer (indeed, if you #define EXCLUDE_IE60 with my bootstrap, then you can compile a smaller bootstrap that removes the IE-related stuff).

The MFC runtimes themselves will be installed by vcredist_x86.exe, which will also install the ATL and OpenMP runtimes. If you are using the Unicode release of the MFC DLLs, note that the Microsoft provided DLLs will not work on Win9x (since Win9x does not implement Unicode). Please follow the instructions located in Michael Kaplan's blog to see how to rebuild the MFC DLLs to use the MSLU.

If you're running Visual C++ Express, you can still use my bootstrapper application even though you lack the capability of creating a setup project (and you lack the redist folder, and vcredist_x86). Outlined in Nikola Dudar's blog are the steps to compile a CRT MSI from those merge modules which you can redistribute to the end users. The first step is to download and extract the WiX binaries to a folder (actually, the first step is to download and install platform SDK, but you've already done that haven't you?).

Once you have installed WiX (I'll assume you installed it to "C:\WiX"), you need to open up a SDK command prompt. Run the following command twice:

uuidgen.exe

This should give you two GUIDs (one for each time you run uuidgen) which will be useful later on. Memorize those two GUIDs. Now create an XML file called "C:\WiX\vccrt.wxi".

Don't save the file now, replace those 0s with the two GUIDs you memorized earlier. Once you have replaced those GUIDs you can save the file (and you can also forget those GUIDs you memorized). Now create a file called C:\WiX\vccrt.wxs and give it the contents:

In the end, you should have a file called vccrt.msi. If you're getting any errors, you should check out the troubleshooting section of Nikola's blog. With the vccrt.msi created, run this file on all the machines you intend your app to work on.

If you want my bootstrapper application to invoke vccrt.msi instead of vcredist_x86.exe, you need to alter my code so that the MSI is executed instead (instructions are given in install.txt).

Assuming your application is called helloconsole.exe, and is installed in C:\test\, you can copy the CRT DLLs to the application folder.

Once you have done that, open up your \Program Files\Microsoft Visual Studio 8\VC\Redist\x86\Microsoft.VC80.CRT folder and look for the file called Microsoft.VC80.CRT.manifest. If you run C++ Express or don't have the redist folder, this is what the Microsoft.VC80.CRT.manifest looks like:

Save this to a UTF-8 XML file called Microsoft.VC80.CRT.manifest (and make sure the copyright sign comes out correctly).

Once you have the manifest, copy it to the C:\Test\ directory, along with the CRT DLLs and then your application should successfully run. Your directory should now look like:

C:\Test\helloconsole.exe

C:\Test\MSVCR80.dll

C:\Test\MSVCP80.dll

C:\Test\MSVCM80.dll

C:\Test\Microsoft.VC80.CRT.Manifest

If you're making use of MFC/ATL/OpenMP, you will also need to copy the corresponding runtimes and their manifests as well (see your redist folder). Now your app should run.

Exercise: what happens when the user (or more accurately, the administrator) subsequently installs the vcredist_x86.exe package after you have copied these "app-local" DLLs? Which version will be loaded?

In earlier versions of this article, I assumed that the applocal DLLs would override the WinSXS DLLs (not desirable if the shared assemblies are a later version of the CRT). To make certain however, let's confirm this by performing some PSAPI tests:

This shows that my earlier assumption was wrong. The shared assemblies are indeed loaded in preference to the app-local DLLs. Until the administrator is coerced into installing the shared CRT DLLs, your app can make use of the app-local DLLs. Once the shared CRTs are installed, your app will start using the shared CRT DLLs, and your app local DLLs become unused files. This method has two advantages going for it (no setup required, will run on unpatched Windows 2000/XP/2003 systems), and I cannot find anything else wrong with this approach, I feel that this method offers an attractive solution for making your app run on another computer. Microsoft fully supports this method of deployment, albeit by arranging the CRT DLLs slightly differently.

If you look at your redist folder, you will notice that the files are located in strangely named subdirectories, like Microsoft.VC80.CRT, or Microsoft.VC80.MFC. These directories are purposefully named, because when you install your application, Microsoft recommends you to copy these folders as-is to your application directory.

According to Microsoft your setup should look like this for WinXP and above:

C:\Test\helloconsole.exe

C:\Test\Microsoft.VC80.CRT\Microsoft.VC80.CRT.manifest

C:\Test\Microsoft.VC80.CRT\msvcr80.dll

C:\Test\Microsoft.VC80.CRT\msvcp80.dll

C:\Test\Microsoft.VC80.CRT\msvcm80.dll

For Win2K and below, it should look like:

C:\Test\helloconsole.exe

C:\Test\msvcr80.dll

C:\Test\msvcp80.dll

C:\Test\msvcm80.dll

(Exercise: How would you arrange the DLLs such that it is the setup for both WinXP and Win2K?)

Not only are you going to need redundant copies of the CRT DLLs, Microsoft admits that this approach only works if your application is an executable (EXE). It does not work for DLLs. For DLLs, Microsoft mandates that you follow a setup similar to the one I've described. However, if my method works for both EXEs and DLLs, why don't we just always arrange the CRT DLLs in the way I've described?

According to Microsoft, installing a private side-by-side assembly is not supported on Windows 2000 and below, but it seems to work okay. They prefer the CRT DLLs to be installed in the System32 directories. In my opinion, it sounds more like scare tactics from Microsoft. They say it may or may not work, but they're not going to help you if you do it.

If you use any part of the CLR (say, you're writing a C++/CLI app), then you have to install the .NET Framework. If this is the case, then you can kill two birds with one stone by just redistributing the .NET Framework. Note that the .NET Framework is a larger redistributable that will refuse to install if you don't have Internet Explorer 6.0, or the latest service pack for Windows 2000 (or XP or 2003 or Vista). Again, you will also require Windows Installer 3.0. However, with the .NET Framework, at least you get a friendlier error message that indicates the missing component (no need for my bootstrapper).

Overall, the end user may have to download 360 MB of patches before they can install the .NET Framework. However, once the .NET Framework is installed the user will probably have nearly everything they need to run the app (including the CRTs, MSIE, latest service pack, MSI 3.0). Everything apart from MFC / ATL / OpenMP libraries - they still need to be redistributed if you use them.

If you have the source code of C runtimes (only available if you do a full install, and you're not on Express Edition), then you can rebuild the entire CRT to get them to behave just the way you want (in this case, load from your own dir). However, there is a legal issue with distributing an application that links to a hacked CRT (make sure you review the VS EULA with your legal team). Most importantly, the name of these rebuilt DLLs must not be called MSVCR80.DLL (or MSVCP80.DLL or MSVCM80.DLL). You might have other reasons to use a custom CRT, (e.g. to enable MSLU support for the CRTs). If that is the case, you should choose this solution. Steps to rebuild the CRT are given in the MSDN site.

Unlike Microsoft's CRT, this private CRT is not supposed to be placed in the WinSXS directory or even the System32 directory - it should be placed in the same directory as your app. The primary difference between your private CRT and Microsoft's CRT is that _CRT_NOFORCE_MANIFEST is not defined in your build. That means the code that checks if the DLL was loaded via the manifest (which also happens to be the code that prevents your app from running under Windows NT) gets preprocessed out. Thus you can deploy this DLL locally with your app, without needing to include a manifest with it (Windows NT compatibility is an added bonus).

To use the modified CRT, you need to add a /NODEFAULTLIB switch to your linker command line (Project -> Project Properties -> Configuration Properties -> Linker -> Input -> Ignore All Default Libraries, set to Yes). Then, you need to add the full path to your rebuilt CRT in the Additional Dependencies field (as well as any Win32 libs that got excluded). This needs to be repeated for all your projects.

Also note that you will get serious problems if you use a rebuilt CRT, you call into a DLL that expects STL parameters (or a FILE* or any other CRT-specific construct), and that DLL does not use your modified CRT. Such problems include heap corruptions, unreleased locks, debug asserts and other crashes (i.e. all those crashes which only occurred on the end users' machines but not yours).

The major disadvantage with this approach is that if you're using a buggy function in the CRT DLLs and Microsoft issues a fix for that function, your application will not be updated. The only way you can fix this bug is to patch your version of Visual Studio and rebuild the CRTs again.

The final option is to statically link your executable to the CRT (by the way, this is how the bootstrapper is able to run without the CRTs). To statically link to the executables, go to the Project -> Project Properties -> Configuration Properties -> C/C++ -> Code Generation -> Runtime Library (change from "Multi-Threaded DLL" to "Multi-Threaded").

If you're careful enough, you can even get the application to run on Windows NT! The pieces of the CRT that require InterlockedCompareExchange and GetLongPathNameW get discarded out of your final executable, and thus your app can run on Windows NT. In order for this to happen, you have to be careful about which C functions you call (no iostream, no locale, no algorithm), and you'll probably have to upgrade to the latest service pack for Windows NT (plus all post service pack patches).

Using this method is not much better than rebuilding the CRTs. Once again, if your application consists of several DLLs where each DLL expects STL/CRT parameters, you will get serious bugs until you rebuild by dynamically linking the CRT.

And if Microsoft issues a fix for their routines, and you use this method, you become solely responsible for fixing both yours and Microsoft's bugs.

If you have Windows 2000, please consider yourself a tester for my app. I have not tested my bootstrapper on this OS, and some of my most complex code runs specifically on this operating system. If you are on Win2K, please, let me know how it works.

There is a lot of hardcoding going on in my bootstrapper. It's not as configurable as this installer. It does not support the installation of .NET (although it could with a few minor modifications). And currently it only supports one command line option (/silent), and even this switch doesn't work that well as it should.

My bootstrap behaves rather unreliably if the user chooses to install Microsoft's components, but cancels them in the middle of the install. If you're still receiving errors even after you have deployed your application, then...

If you're getting errors related to MSVCR80D.DLL/MSVCP80D.DLL/MSVCM80D.DLL (note the D), then please recompile your app to be a release build (go to Build -> Configuration Manager and where it says Active Solution Configuration, select "Release"). If you're the end user, ask the application developer to rebuild his program in a release build.

If you're getting some other error related to missing DLLs, then try opening your application under Dependency Walker (it's located somewhere under the Platform SDK folder - search for the depends.exe in the folder where you installed the Platform SDK. If it's not there, then download it from here). Dependency walker should tell you how a DLL is loaded and if any DLL is missing or outdated. Missing DLLs are noted with ? marks and outdated DLLs are flagged red.

If you are receiving a R6034 error, then make sure your app contains a manifest. Then make sure your folder includes a second manifest called Microsoft.VC80.CRT.Manifest (see above). Note that if you're running Windows 95/NT or below, then it's not possible to solve your error unless you upgrade your operating system.

If you are building a DLL and that DLL is having trouble loading, then make sure that DLL has an embedded manifest. The manifest for a DLL should be created with the following command:

DLLs need to have its manifest embedded as a resource with the resource ID equal to 2 (according to MSDN). External manifests do not work for DLLs, they only work for applications, so unless you are able to alter the application's manifest, you should embed the mt.exe generated manifest into your DLL.

One trick that seemed to have solved some problems is to enable the "Use FAT-32 Workaround" setting in project properties. Although Microsoft hasn't revealed what this setting actually does, some users have replied that it solved whatever problems they had.

If you are not receiving a R6034 and Dependency Walker shows nothing wrong, and you've fully patched Windows and it has a supported version of Windows then perhaps it might be a problem related to the DLL itself. Try looking at the links below to see if they are of any help.

Since this article was published, Microsoft has paid attention to the complaints, and in service pack 1 for Visual Studio 2005, they have fixed some of the most pressing concerns with their software. The vcredist_x86.exe no longer requires MSI 3.0 to run, it can now run on machines where the Windows installer version is 2.0. This means the vcredist install sequence becomes relatively simple:

Run InstMSIA.exe (if MSI2.0 is already installed, this will do nothing)

Run vcredist_x86.exe (if the CRTs are already installed, this will do nothing)

Install your application.

You no longer need to check the windows version or service pack level (the table above is no longer relevant). What's more, vcredist_x86.exe will guarantee that the CRT DLLs are installed into the correct locations. This same procedure works for all supported versions of Windows. The fix is available as a QFE if you can't wait for service pack 1 to be released.

Updated article with subsequent information discovered in 2006. Changed the intro to show what happens if you miss some steps. Changed the executable to use IExpress.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

Share

About the Author

Mr. Shah is a reclusive C++/C# developer lurking somewhere in the depths of the city of London. He learnt physics at Kings' College London and obtained a Master in Science there. Having earned an MCAD, he teeters on the brink of transitioning from C++ to C#, unsure of which language to jump to. Fortunately, he also knows how to use .NET interop to merge code between the two languages (which means he won't have to make the choice anytime soon).

His interests (apart from programming) are walking, football (the real one!), philosophy, history, retro-gaming, strategy gaming, and any good game in general.

He maintains a website / blog / FAQ / junk at shexec32.serveftp.net, where he places the best answers he's written to the questions you've asked. If you can find him, maybe you can hire Mr. Shah to help you with anything C++[/CLI]/C#/.NET related .

Comments and Discussions

I wanna ask if you know whether the user need to restart his/her machine after installing MSI 3.1? Currently, I do not have a machine without MSI 3.1 to test that out. If it does require restart, won't that break your bootstrapper?

I am working on a wrapper dll (in managed c++) over a legacy dll. The legacy dll is compiled in VS 6, using msvc60*.dll, and using STL. I am developing the wrapper in VS 2005.

After I build the dll, and run it, it says the system can't find the file (or one of the dependency).
From the dependency walker loading the wrapper, I get this:
“Error: At least one module has an unresolved import due to a missing export function in an implicitly dependent module.”
And the unresolved import seems to stems from the legacy dll.

But if I load the legacy dll in to dependency walker, there's no error. However I notice that loading just the legacy dll will load msvc60* version dlls. While loading the wrapper dll, it is loading the msvc80* version dlls, which I think causing this problem.

It seems there's a conflict in STL implementations between msvc60* and msvc80*, or could it be that I have to prepare the manifest for each version of the CRTs?

Copying the debug version of manifest seems to work only for regular applications but debug versions of COM Objects. Debug versions of COM objects cannot be registered on the machine that does not have VS8 installed. Dose anyone have a solution to this ?

i am doing a application using windows forms in my pc runs perfect but it doesn't run in other machine that has vs6 i dont what i have to do i please help me, i trying to follow the steps in the article but it doesn't work.

Do you have Debug or Release?
The redist is only for Release. You can find it out be compile the Release version and copy that version. If this works, you have to copy the debug manifests ( as descriped in my 2nd entry) for your Debug. (Have a look on the licening !)

I am trying to deploy my application and I thought the very easy way was the 2nd alternative you present here i.e. including with my app.exe a subfolder (XP target) with .dll and Microsoft.VC80.CRT.manifest file. No problem with the dll files, but I discovered there's no Microsoft.VC80.CRT.manifest in my system. I found in the folder c:\WINDOWS\WinSxS\manifests a file named "x86_Microsoft.VC80.CRT_1fc8b3b9a1e18e3b_8.0.50727.42_x-ww_0de06acd.manifest". I think it is the right one but now I doubt about how to call the subfolder of my distribution...., what do you think about it?
Thanks in advance and best regards

> The fix is available as a QFE if you can't wait for service pack 1 to be released.

Are you referring to the hotfixes described in KB articles 919280 and/or 919588? In my understanding, these offer only a solution for the following scenarios:

- 919280 installs new merge modules to the development machines, so when you create a new setup project, it will depend only on MSI 2.0
- 919588 allows to redistribute "new" (patched) VC runtime files onto (customer) machines which have vcredist/RTM already installed. So this new patch EXE is no solution to overcome the MSI 3.0 restriction of vcredist/RTM.

What we still don't have is an EXE like vcredist without the MSI 3.0 restriction.

It's quite possible that I have gotten the above wrong, so please correct me. Or were you referring to a different hotfix? Then I'd appreciate a KB number or additional information.

I have a question in the same way.
My context is not the development of a DLL... but I have to check if vcredist_x86.exe has been installed on the system (I'm creating an installer which has to be able to detect VC++ ATL80, MFC80 etc before launching vcredist_x86.exe).

Is there a 'discriminant' registry key which will ensure me that vcredist_x86.exe has been installed ?

by my opinion it's not a robust way to detect vcredist_x86.exe by registry. More over there are at least 3 different vcredist_x86.exe (from VC2005, VC2005SP1 and VC2005SP1 beta) that can be installed and SP1 compiled programs requires SP1 vcredist_x86.exe.

The only way I know is:
1. make support dll that uses features from ATL80, MFC80, C/C++ (check with depends.exe that it really depends on those dlls).
2. make support application that tries to dynamically load that support dll. If dll load fails - you must install vcredist_x86.exe.

Or, if you don't mind - just install vcredist_x86.exe (in a silent mode) _always_ - it will take not so many additional time, but robust enough.

The first version of my installer lanched vcredist_x86.exe in silent mode, but "local decompression" was still visible, that's why I would detect if it's really necessary to launch it.

Ok, if the registry can't ensure that, I'll get the support application method.
Or may be more simple (for me, in my context) :
Trying to register (regsvr32) an existing DLL which needs ATL80, MFC80, C/C++ ;
and check if it fails or not.

I build the solution for this project in VC++ 2005. whenever I run this executable on machine where VC++ 2005 is not installed but it will show error.
The error message as "The application has failed to start because the application configuration is incorrect. Reinstalling the application may fix the problem".

The vcredist_x86.exe no longer requires MSI 3.0 to run, it can now run on machines where the Windows installer version is 2.0

Well, not exactly. Using vcredist_x86.exe released in last April, I'm still getting error 1723 while executing it on a Windows XP (with and without SP1). It is also explicity stated at the download page that WI3 and above is required for that to run. Am I missing something?

Can you contact Microsoft support and ask them for hotfix number 919280 (or perhaps 919588)? Apparently, these hotfixes will patch the MSMs in your "Microsoft Shared" directory so that when you next create a Setup project, that setup project will only require WI2, and will install the CRTs onto the user's machine. I know it's not quite the same as having a vcredist_x86.exe, but it does install the CRTs.

BTW, these hotfixes also patch some other problems with the CRT library (such as the iostream memory leak).