| CodeGuru Home | VC++ / MFC / C++ | .NET / C# | Visual Basic | Newsletters | VB Forums | Developer.com |
|
|
|||||||
| CodeGuru Individual FAQs The indivdual FAQs for CodeGuru. See the specific Topic FAQ forums for index pages and links to these Frequently Asked/Answered Questions. |
![]() |
|
|
Thread Tools | Search this Thread | Display Modes |
|
#1
|
||||
|
||||
|
Visual C++ Application: How to use manifests and re-distributable assemblies?
Q: I have an MFC application that runs on my computer, but when I try to run it on another PC I receive an error message that the application failed to initialize and I should re-install it. What should I do?
A: By default, Visual C++ 2005 builds all native C/C++ applications as isolated applications, i.e. self-describing applications that use manifest files to describe their dependencies to VC++ libraries. The problem occurs because your application doesn't have a manifest, or it has dependencies to assemblies that don't exist on the target PC, or they have a different version number. Basically you have to do two things to solve the problem:
Q: What is a manifest resource? A: A manifest resource is an XML file that describes the dependencies of your application. Such dependencies can include the most current version of the Windows common controls, as well as library assemblies, such as MFC, ATL or CRT assemblies. Your manifest should have the same name as the application and the extension "manifest" and should specify the version number of your assembly (executable or dynamic library), processor architecture, name of the assembly and platform type; a description of your assembly is also recommended. Code:
<?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="CompanyName.ProductName" type="win32" /> <description>Description of your application.</description> </assembly> Q: How do I specify dependencies? A: You have to add a Code:
<?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="CompanyName.ProductName"
type="win32"
/>
<description>Description of your application.</description>
<dependency>
<dependentAssembly>
<assemblyIdentity
type="win32"
name="Microsoft.Windows.Common-Controls"
version="6.0.0.0"
processorArchitecture="X86"
publicKeyToken="6595b64144ccf1df"
language="*"
/>
</dependentAssembly>
</dependency>
</assembly>
Q: Can I achieve the same, using the Win XP style for controls, without a manifest? A: Starting with Visual Studio 2005, you can add the following to stdafx.h (if you are using precompiled headers) or other common header: Code:
#if defined _M_IX86 #pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='x86' publicKeyToken='6595b64144ccf1df' language='*'\"") #elif defined _M_IA64 #pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='ia64' publicKeyToken='6595b64144ccf1df' language='*'\"") #elif defined _M_X64 #pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='amd64' publicKeyToken='6595b64144ccf1df' language='*'\"") #else #pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"") #endif Q: I now understand what a manifest resource is, but what are re-distributable assemblies? A: These are assemblies provided as dynamic link-libraries that you can deploy with your application, because they are required for the application to work. Assemblies are provided in several configurations, Release and Debug, but you can only re-distribute the release configurations (can be found in Visual Studio 8 installation folder, VC\redist). Visual C++ 2005 supports a new deployment model for Windows client applications based on isolated applications and side-by-side assemblies. Basically, assemblies can be:
In Visual C++ 2005, library assemblies (such as MFC, ATL, CRT) have been rebuilt as shared side-by-side assemblies and installed in the native assembly cache, WinSxS folder in Windows. That means they are not globally registered in the system, but are globally available to the applications that specify a dependency with a manifest file. The target machine where you run your application may already have the required dependencies installed. You can look-up for them in the WinSxS folder. Assemblies are grouped here on categories, each with its own folder. Folder names start with the platform name, followed by Microsoft, category (Windows, VC80, MSXML, Tools), assembly name, a token number, version and additional identifiers. The manifest files for these assemblies are located in the Manifest subfolder of WinSxS and have the same name as the folder of the assembly group they contain information about. Q: How do I specify dependencies for my application in the manifest file? A: Suppose your application uses MFC as a shared library, so it has at least a dependency on MFC and one on the C runtime library and C++ runtime library (these two part of the CRT assembly group). In this case your manifest file should look like this: Code:
<?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="CompanyName.ProductName"
type="win32"
/>
<description>Description of your application.</description>
<dependency>
<dependentAssembly>
<assemblyIdentity type='win32' name='Microsoft.VC80.CRT' version='8.0.50727.42' processorArchitecture='x86' publicKeyToken='1fc8b3b9a1e18e3b' />
</dependentAssembly>
</dependency>
<dependency>
<dependentAssembly>
<assemblyIdentity type='win32' name='Microsoft.VC80.MFC' version='8.0.50727.42' processorArchitecture='x86' publicKeyToken='1fc8b3b9a1e18e3b' />
</dependentAssembly>
</dependency>
</assembly>
To distribute the correct assemblies after building the application, go to the Visual Studio 8 installation folder in VC\redist and select your target platform folder, i.e. x86 or amd64. Inside, you will see folders for ATL, MFC, CRT, MFCLOC and OPENMP. The Microsoft.VC80.MFC folder contains 4 DLLS and a manifest file, called Microsoft.VC80.MFC.manifest. You must copy at least MFC80.DLL (or MFC80U.DLL if you built for UNICODE) to your application working folder. You must make sure that the version number of the MFC assembly specified in this manifest matches the one you put in your application manifest and the one of the DLL itself (this should be implicit, but should check that from the file properties, Alt + Enter > Version). The Microsoft.VC80.CRT contains 3 DLLs and the manifest. Of these three DLLs you need at least msvcr80.dll (C runtime library) and msvcp80.dll (C++ runtime library). The same caution for the version number must be taken. With all these taken care of, your application should correctly run on any target machine.
__________________
Marius BancilaHome Page | Blog My CodeGuru articles My latest articles: A TR1 Tutorial: array, tuple, unordered containers, random number generators, regex, smart pointers Customizable alert window Try my VSBuildStatus add-in for Visual Studio 2005, 2008 & 2010 (v1.1). I do not offer technical support via PM or e-mail. Please use vbBulletin codes. Last edited by cilu; June 21st, 2007 at 08:25 AM. |
![]() |
| Bookmarks |
|
||||||
| Thread Tools | Search this Thread |
| Display Modes | |
|
|