部署方案示例
更新:2007 年 11 月
假定我们有 MyApplication.exe 和 MyLibrary.DLL,两者都是使用 MFC 生成的。MyApplication.exe 依赖 MyLibray.DLL,它们都通过共享 DLL 使用 MFC,且都可以是本机或混合 (/clr) 二进制文件。在最简单的情况中,它们都是在不更改任何默认设置的条件下,由向导生成的。本节中的示例介绍如何将此应用程序部署到没有安装 Visual Studio 的其他计算机上。本节主要涉及应用程序发布版本的部署;但也指出了部署应用程序调试版本所需的更改。
说明: |
---|
此 EULA 不允许重新发布调试 Visual C++ 程序。但可以为了调试而临时部署它们。请参见 Visual Studio 2008 的软件许可条款 EULA。 |
初始安装
此方案中考虑使用三台计算机。
一台是开发计算机,用于生成应用程序。其上安装了 Visual Studio 2005(STD、PRO 或 TS)。
其余两台是部署目标计算机,其上没有安装 Visual Studio 2005。部署目标 1 的计算机运行支持根据清单将应用程序绑定到其依赖项的操作系统(Windows XP Home Edition、Windows XP Professional、Windows Server 2003、Windows Vista)。部署目标 2 运行不提供这种支持的操作系统 (Windows 2000)。
我们的目标是在开发计算机上生成应用程序,然后将该应用程序部署到两台目标计算机上并运行它。
准备
当生成将在其他计算机上运行的 Visual C++ 二进制文件后,需要确定此二进制文件依赖哪些 DLL。此时,依赖关系查看器 (Dependency Walker) 是一个很有用的工具。在此情形中,必须考虑 Visual C++ DLL,尤其是 CRT 和 MFC。如果在 Visual Studio 中打开 MyApplication.exe 的调试版本并浏览其资源,可以看到 RT_MANIFEST 资源。它是二进制文件的内嵌清单。如果以 XML 文件形式导出并打开该清单,您会看到以下内容:
<?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.VC90.DebugCRT" version="9.0.xxxxx.yy" processorArchitecture="x86" publicKeyToken="1fc8b3b9a1e18e3b"></assemblyIdentity>
</dependentAssembly>
</dependency>
<dependency>
<dependentAssembly>
<assemblyIdentity type="win32" name="Microsoft.VC90.DebugMFC" version="9.0.xxxxx.yy" processorArchitecture="x86" publicKeyToken="1fc8b3b9a1e18e3b"></assemblyIdentity>
</dependentAssembly>
</dependency>
<dependency>
<dependentAssembly>
<assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" processorArchitecture="x86" publicKeyToken="6595b64144ccf1df" language="*"></assemblyIdentity>
</dependentAssembly>
</dependency>
</assembly>
这意味着此应用程序依赖下列程序集:
Microsoft.VC90.DebugCRT 程序集,9.0.xxxxx.yy 版本,适用于 x86
Microsoft.VC90.DebugMFC 程序集,9.0.xxxxx.yy 版本,适用于 x86
Microsoft.Windows.Common-Controls 程序集,6.0.0.0 版本,适用于 x86
在二进制版本中,您将看到以下内容:
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<dependency>
<dependentAssembly>
<assemblyIdentity type="win32" name="Microsoft.VC90.CRT" version="9.0.xxxxx.yy" processorArchitecture="x86" publicKeyToken="1fc8b3b9a1e18e3b"></assemblyIdentity>
</dependentAssembly>
</dependency>
<dependency>
<dependentAssembly>
<assemblyIdentity type="win32" name="Microsoft.VC90.MFC" version="9.0.xxxxx.yy" processorArchitecture="x86" publicKeyToken="1fc8b3b9a1e18e3b"></assemblyIdentity>
</dependentAssembly>
</dependency>
<dependency>
<dependentAssembly>
<assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" processorArchitecture="x86" publicKeyToken="6595b64144ccf1df" language="*"></assemblyIdentity>
</dependentAssembly>
</dependency>
</assembly>
这意味着此应用程序依赖下列程序集:
Microsoft.VC90.CRT 程序集,9.0.xxxxx.yy 版本,适用于 x86
Microsoft.VC90.MFC 程序集,9.0.xxxxx.yy 版本,适用于 x86
Microsoft.Windows.Common-Controls 程序集,6.0.0.0 版本,适用于 x86
对于调试版本和发布版本,都会在 MyLibrary.dll 中看到类似的清单。请注意,清单 ID 对于 EXE 为 1,对于 DLL 为 2。此外,如果清单未嵌入到二进制文件中,它将存储为 <binaryname>.<extension>.manifest 并且具有相同的内容。
说明: |
---|
Visual Studio 2005 不支持生成不带有清单的 C++ 应用程序,并且不支持使用 %PATH% 通过旧方式绑定到 Visual C++ 库。此外,Visual C++ DLL 可以对此进行检测,阻止加载 DLL,并报告不支持的方案和所需更改。请不要使用 /manifest:no 或者删除清单。 |
部署方法
在此示例中,我们要将 MyApplication.exe 安装到 %TARGET% 文件夹中,客户可以在安装过程中指定该文件夹。MyLibrary.dll 将安装在 %TARGET%\MyLibrary 中,\MyLibrary 将添加到路径中。
我们将检查两种部署 VC++ 应用程序的方法:
使用安装和部署项目生成安装程序包。
XCopy 部署。
对于每种方法,我们将研究两个方案:
将 Visual C++ 库部署为共享程序集。
将 Visual C++ 库部署为私有程序集。
在方案 1 中,WinSxS 文件夹中仅有 Visual C++ DLL 的一个副本。在方案 2 中,将有 Visual C++ DLL 的两个副本,它们分别安装在应用程序 EXE 和 DLL 的本地文件夹中。
说明: |
---|
Windows 2000 上不支持方案 2,因为在应用程序本地文件夹中的部署会在提供服务时产生问题。 |