[转载自:http://blogs.msdn.com/nikolad/articles/427101.aspx][http://msdn.microsoft.com/en-us/library/ms235342(VS.80).aspx]
Here is another unofficial preview of a topic that I am going to send out to our UE team later today for publishing on MSDN. As always, standard disclosure that this post is provided "AS IS" with no warranties, and confer no rights and use of this sample is subject to the terms specified at http://www.microsoft.com/info/cpyright.htm Please feel free to send me any feedback (other the grammar and spelling errors :-)).
Loading C/C++ application may fail if dependent Visual C++ libraries can not be found. In this section the most common reasons for a C/C++ application failing to load are described with proposed steps to resolve the problems.
One of the most common errors messages one may see when dependent Visual C++ DLLs cannot be found is a message box with a text saying “ The system cannot executed the specified program”. Below several things are listed that may help to understand a reason for this error.
Note: It is not supported to build VC++ projects without manifest generation. All C/C++ program built in Visual C++ 2005 have to include a manifest describing its dependencies on Visual C++ libraries.
Example:
Let's assume we have an application appl.exe built with Visual C++ 2005. This application may have its manifest either embedded inside appl.exe as a binary resource RT_MANIFEST with ID equal to 1, or store as an external file appl.exe.manifest. The content of a manifest may be something like below:
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<dependency>
<dependentAssembly>
<assemblyIdentity type="win32" name="Microsoft.VC80.CRT" version="8.0.50215.4631" processorArchitecture="x86" publicKeyToken="1fc8b3b9a1e18e3b"></assemblyIdentity>
</dependentAssembly>
</dependency>
</assembly>
To the operating system loader this manifest says that appl.exe depends on an assembly named Microsoft.VC80.CRT, version 8.0.50215.4631 and built for 32bit x86 processor architecture.
The dependent side-by-side assembly can be installed as either shared assembly or as private assembly. For example, Visual Studio 2005 installs CRT assembly as a shared side-by-side assembly and it can be found in the directory
C:\WINDOWS\WinSxS\x86_Microsoft.VC80.CRT_1fc8b3b9a1e18e3b_8.0.50215.4631_x-ww_b7acac55 (assuming C:"Windows is the operating system's root directory).
The assembly manifest for a shared Visual C++ CRT assembly is also installed in
C:\WINDOWS\WinSxS\Manifests\x86_microsoft.vc80.crt_1fc8b3b9a1e18e3b_8.0.50215.4631_x-ww_b7acac55.manifest
And it identifies this assembly and lists its content (DLLs that are part of this assembly):
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!-- Copyright © 1981-2001 Microsoft Corporation -->
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<noInheritable/>
<assemblyIdentity type="win32" name="Microsoft.VC80.CRT" version="8.0.50215.4631" processorArchitecture="x86" publicKeyToken="1fc8b3b9a1e18e3b"/>
<file name="msvcr80.dll" hash="3ca5156e8212449db6c622c3d10f37d9adb12c66" hashalg="SHA1"/>
<file name="msvcp80.dll" hash="92cf8a9bb066aea821d324ca4695c69e55b27cff" hashalg="SHA1"/>
<file name="msvcm80.dll" hash="7daa93e1195940502491c987ff372190bf199395" hashalg="SHA1"/>
</assembly>
Side-by-side assemblies can also use publisher configuration files, also called policy files, to globally redirect applications and assemblies from using one version of a side-by-side assembly to another version of the same assembly. You can check policies for shared Visual C++ CRT assembly in
C:\WINDOWS\WinSxS\Policies\x86_policy.8.0.Microsoft.VC80.CRT_1fc8b3b9a1e18e3b_x-ww_77c24773"8.0.50215.4631.policy
which content is something like
</assembly>
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!-- Copyright © 1981-2001 Microsoft Corporation -->
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity type="win32-policy" name="policy.8.0.Microsoft.VC80.CRT" version="8.0.50215.4631" processorArchitecture="x86" publicKeyToken="1fc8b3b9a1e18e3b"/>
<dependency>
<dependentAssembly>
<assemblyIdentity type="win32" name="Microsoft.VC80.CRT" processorArchitecture="x86" publicKeyToken="1fc8b3b9a1e18e3b"/>
<bindingRedirect oldVersion="8.0.41204.256" newVersion="8.0.50215.4631"/>
</dependentAssembly>
</dependency>
</assembly>
The policy above basically specifies that any application or assembly that asks for version 8.0.41204.256 of this assembly should use version 8.0.50215.4631 of this assembly, which is the current version installed on the system. If a version of the assembly mentioned in the applications manifest is specified in the policy file, the loader looks for a version of this assembly specified in the manifest in the WinSxS folder, and if this version is not installed load fails. And if assembly of version 8.0.50215.4631 is not installed also, load fails for applications that ask for assembly of version 8.0.41204.256.
However CRT assembly can also be installed as a private side-by-side assembly in the applications local folder. If the operating system fails to find CRT or any other assembly as a shared assembly, it starts looking for this assembly as a private assembly. It searches for private assemblies in the following order:
1. Ceck the application local folder for a manifest file with name <assemblyName>.manifest. In this example, the loader tries to find Microsoft.VC80.CRT.manifest file in the same folder as appl.exe.
a. If the manifest has been found, the loader loads CRT Dll from the application folder.
b. If CRT DLL is not found, load fails.
2. Try to open folder <assemblyName> in appl.exe local folder and if it exists, load manifest file <assemblyName>.manifest from this folder.
a. If the manifest has been found, the loader loads CRT DLL from <assemblyName> folder.
b. If CRT DLL is not found, load fails.
See Assembly Searching Sequence for more detailed description on how loader searches for dependent assemblies. If the loader fails to find dependent assembly as a private assembly, load fails and "The system cannot executed the specified program” is display. To resolve this message dependent assemblies and DLLs that are part of them has to be installed on this computer as either private or shared assemblies.
Related Sections
About Isolated Applications and Side-by-side Assemblies