如何为 VS.NET 部署项目创建安装补丁






4.33/5 (12投票s)
2005年8月20日
4分钟阅读

813377
自动创建 Windows Installer 补丁。
引言
我发现自己想知道如何为我的应用程序创建补丁。我查看了 Wise 和 InstallShield 等几种第三方工具以及一些免费安装程序,发现它们对我需要的功能来说都过于复杂。我的分发需求很简单,但我的项目很大。我显然需要一种简单的方法来创建补丁。
VS.NET 部署项目非常易于使用,比直接使用 Windows Installer SDK 要容易得多。易用性是有代价的;VS.NET 部署项目消除了 SDK 的许多功能和灵活性,以简化构建过程。
在查阅了 Windows Platform SDK 文档和 MSDN 上的几个示例后,我提出了这个自动构建过程来创建 MSP 补丁文件。
使用代码
此过程会创建 patch.msp 文件,其中包含 VS.NET 部署项目当前 Release 和 Debug 安装程序与您将放置在 TargetImages 文件夹中的原始安装程序之间的差异。它要求 VS.NET 部署项目生成属性设置为 Package files=In setup file。
- 安装 Microsoft Platform SDK。
- 安装位于 C:\Program Files\Microsoft Platform SDK\Bin\ 的 Orca.Msi。
- 将位于 C:\Program Files\Microsoft Platform SDK\Samples\SysMgmt\Msi\Patching\ 的 TEMPLATE.PCP 复制到您的部署项目文件夹,并将其重命名为 patch.pcp。
- 双击 patch.pcp 文件在 ORCA 中打开它。
- 向 ImageFamilies 表添加一条记录,并将 Family 设置为 fam1。
- 向 PatchSequence 表添加一条记录,并将 PatchFamily 设置为 fam1,Sequence 设置为 1.0.0。
- 在 Properties 表中,选择 PatchGUID 的值并右键单击。选择粘贴新的 GUID。
- 在 Properties 表中,选择 PatchOutputPath 的值并将其值设置为 Patch\patch.msp。
- 向 Properties 表添加一条记录,并将其名称设置为 MinimumRequiredMsiVersion,其值设置为 200。
- 向 TargetImages 表添加一条记录,并设置以下值:Target=target,MsiPath=TargetImage\setup.msi,Upgraded=upgrade,Order=1,IgnoreMissingSrcFiles=0。
- 向 UpgradedImages 表添加一条记录,并设置以下值:Upgraded=upgrade,MsiPath=UpgradedImage\setup.msi,Family=fam1。
- 在部署项目文件夹中创建一个 TargetImage\Release 文件夹,并将第一个发行版安装程序的 MSI 复制到其中。
- 在部署项目文件夹中创建一个 TargetImage\Debug 文件夹,并将第一个调试安装程序的 MSI 复制到其中。如果您不创建和分发调试安装程序,可以跳过此步骤。
- 在部署项目文件夹中创建一个新的 patch.cmd 文件,并添加以下命令:
if "%1"=="" %0 Debug Release Done @SETLOCAL @set path=%path%;"C:\Program Files\Microsoft Platform SDK\Samples\SysMgmt\Msi\Patching" @set PatchTmp=C:\~VSTMP :loop if "%1"=="Done" goto end if not exist %1\*.msi goto nopatch if not exist TargetImage\%1\*.msi goto nopatch :ok rmdir /s /q %PatchTmp% mkdir %PatchTmp% mkdir %PatchTmp%\TargetImage mkdir %PatchTmp%\UpgradedImage mkdir %PatchTmp%\Patch for %%a in (TargetImage\%1\*.msi) do copy %%a %PatchTmp%\setup.msi msiexec /qb /a %PatchTmp%\setup.msi TARGETDIR=%PatchTmp%\TargetImage /L*v %PatchTmp%\TargetImage\setup.log del %PatchTmp%\setup.msi for %%a in (%1\*.msi) do copy %%a %PatchTmp%\setup.msi msiexec /qb /a %PatchTmp%\setup.msi TARGETDIR=%PatchTmp%\UpgradedImage /L*v %PatchTmp%\UpgradedImage\setup.log del %PatchTmp%\setup.msi copy patch.pcp %PatchTmp% set PatchDir=%CD% chdir %PatchTmp% msimsp -s patch.pcp -p Patch\patch.msp -l Patch\patch.log -f %PatchTmp%\Tmp -d rmdir /s /q %PatchTmp%\TargetImage rmdir /s /q %PatchTmp%\UpgradedImage rmdir /s /q %PatchTmp%\Tmp chdir %PatchDir% mkdir Patch mkdir Patch\%1 copy %PatchTmp%\Patch\*.* Patch\%1\*.* rmdir /s /q %PatchTmp% :nopatch shift goto loop :end pause
- 编辑您的部署项目并更改版本属性。这是必需的,以便补丁编译器 (msimsp.exe) 看到不同的版本。重要提示:当它要求更新
ProductCode
和PackageCode
时,您必须回答 否。PackageCode
是一个隐藏属性,VS.NET 每次生成部署项目时都会自动更新它;但是,为了使补丁编译器正常工作,ProductCode
不能更改。补丁编译器将拒绝创建主要升级的有效补丁,它通过检查ProductCode
是否已更改来判断,而不是通过Version
号。 - 生成您的部署项目。如果您同时使用 Debug 和 Release 配置,请务必同时生成它们。
UpgradeCode
和ProductCode
未更改,而隐藏的PackageCode
已更改的事实将指示补丁编译器更新后的版本是次要更新而不是主要升级。 - 运行 patch.cmd 批处理程序。此过程可能需要几分钟才能完成,具体取决于原始部署项目的大小和复杂性。补丁编译器将比较两个安装项目中的每个文件,以确定哪些文件已更改,并创建文件之间的差异,或者在更改过多时包含整个文件。请务必检查 patch.log 文件,查看您的补丁中包含哪些文件,并确保所有内容都已正确编译且没有错误。
关注点
如果您使用的配置名称不是 Release 和 Debug,您将需要修改 patch.cmd 文件中的第 1 行来命名您使用的配置,但请确保 Done
是该行的最后一个单词,以便命令正确退出。
您可以通过编辑批处理程序开头的 set
命令来指定 msimsp.exe 文件和要使用的临时文件夹的不同位置。请注意,PatchTmp
变量指定了一个将由此批处理程序完全创建和完全删除的文件夹,因此不要指定 Windows 或任何其他程序所需的临时文件夹。我还建议指定一个名称尽可能短的临时位置。我曾遇到过在具有非常长的完整路径名称的文件夹中运行 msimsp 的问题。
历史
- 2005 年 8 月 20 日 - 初始版本。