分享

Wix打包系列 (六)制作升级和补丁包

 兰亭文艺 2023-04-20 发布于加拿大

原文:Wix打包系列 (六)制作升级和补丁包

前面我们已经知道怎么制作一个完整安装包了,但我们的软件往往不能一次性就满足客户的需要,当客户需要我们给软件进行升级的时候,我们应该怎么做呢?

在这之前,我们有必要了解下Windows Installer中的Upgrades定义:

6.1 关于Windows Installer Upgrades

在Windows Installer中将软件产品的更新划分为3类:

  • Small updates    它意味着安装包里一个或几个文件的很小的改变,使用Small updates时不需要改变Version属性,也不需要改变Product GUID和UpgradeCode属性。唯一要改变的只有Package GUID,事实上我们每次重新生成安装包都需要改变Package GUI。如果是同一安装包,即Package GUID不改变,你在安装程序后,再点击安装包,会弹出维护的界面(卸载和修复);如果是Package GUID改变了,则会弹出错误:“已安装了该产品的另一个版本。无法继续安装此版本…”。

注意任何时候重新生成安装包一定要更改Package GUID,使用不同的Package GUID可以方便管理安装的更新包(msp),不同的Package使用相同的GUID会造成安装程序混乱,造成意想不到的后果。那么既然Small updates时更改Package GUID后运行会弹出错误,那么怎么应用Small updates呢?我们可以用命令行方式执行安装程序,或者通过执行Patch更新包(msp)。制作Patch更新包后面会详细讲,我们先看看命令行方式:

  1. msiexec /fvomus [path to updated .msi file]
  1. 或者
  1. msiexec /I [path to updated msi file] REINSTALL=ALL REINSTALLMODE=vomus.
  • Minor upgrades 在这种情况下,需要更改product version,当然Package GUID也要改变,Product GUIDUpgradeCode属性仍然保持不变。这种方式允许我们添加新的featurescomponents,但是不能改变feature-component树的组织结构。Minor upgradesSmall updates很相似,似乎只是多了个版本变化而已;事实上,可以用Small updates的地方肯定也可以用Minor upgrades,应用Minor upgrades的方式跟应用 Small updates一样,可以使用命令行或者patch方式。
  • Major upgrades 在这种情况下,需要更改Version 属性, Product Package GUID,我们仍然保持UpgradeCode属性不变,大家可能会注意到,UpgradeCode在这里似乎没什么用处,先别急,下面我们会马上讲到它的用处。先看看Major upgrades ,事实上,对开发人员来说,它是一个最安全和最便捷的升级方式,因为Product GUID已经改变,意味着它可以和老版本共存安装到一台计算机上,并且是一个完全的全新安装。

关于Product/@Id属性(GUID),Product/@Version属性,Product/@UpgradeCode属性(GUID),还有Package/@Id属性(GUID);这几个属性在第一章有提到过,在这里我们就可以更清楚他们的意义了

6.2 检测并替换现有版本(Major upgrades

讲到这里,大家应该对Windows Installer制作升级的基础知识有了一定的了解。但是如果我们的安装包体积不大,希望使用Major upgrades,但是又不想每次安装新版本时要手动卸载以前的版本,要怎么做呢?

最好是方式是让安装程序能检测以前版本,然后删除以前版本,最后安装新版本程序;要想能检测到以前版本的信息,这时UpgradeCode就起到作用了。当我们制作更新包或升级版本时,首要要确保我们有以前老的版本的安装包;另外就算我们不打算当前版本被升级,也必须包含UpgradeCode属性,因为一旦你没提供UpgradeCode属性,以后就没有办法再提供了;我们还应该知道什么时候应该改变UpgradeCode属性,事实上,我们在开发一个项目时,可以一直保持UpgradeCode不变,即使Product GUID已经改变,当然你也可以改变UpgradeCode以更好的管理程序版本。

要解决我们的问题还需要引入UpgradeVersion标签,它能帮助我们检测已安装的版本信息和将要升级的版本信息。

  1. <Upgrade Id='F4F8195E-E907-42dd-BB90-CC2403FA7384'>
  1. <UpgradeVersion OnlyDetect='no' Property='PREVIOUSFOUND'
  1. Minimum='1.0.0' IncludeMinimum='yes'
  1. Maximum='$(var.Version)' IncludeMaximum='no' />
  1. <UpgradeVersion OnlyDetect='yes' Property='NEWERFOUND'
  1. Minimum='$(var.Version)' IncludeMinimum='no' />
  1. </Upgrade>

    Upgrade的Id属性是我们安装的以前版本的UpgradeCode,如果你的程序应用了多个UpgradeCode,那么你只需要添加一个新的Upgrade标记就可以了,每个Upgrade标记包含自己的版本范围。我们可以看出来,要想更好的管理版本,我们不应该频繁更换UpgradeCode,不然这里就要写很多个Upgrade标记了,对应还要写很多custom action;我们最多在每个大版本的时候更换UpgradeCode就足够了,比如1.x版本时使用一个UpgradeCode,2.x时使用另外一个UpgradeCode;当然你也可以选择不更换UpgradeCode。

    MinimumMaximum指定Upgrade中我们应该升级的版本范围,IncludeMaximumIncludeMinimum 指定升级范围是否包含边界值(IncludeMinimum='no' 表示只查找以上版本)。

使用Upgrade 标记后将会触发一个新的标准动作FindRelatedProducts,它在LaunchConditions动作后执行,当然我们可以在InstallExecuteSequence中重定义它的执行顺序,但一般情况下我们不用这么做。FindRelatedProducts动作 通过Upgrade 标记检查其中的所有版本,如果找到了,则它的Product GUID将会被追加到UpgradeVersion标记中指定的Property中(如示例中的PREVIOUSFOUND和NEWERFOUND);这里的UpgradeVersionProperty属性,相当于定义了2个Property:PREVIOUSFOUND和NEWERFOUND。

OnlyDetect='yes' 告诉我们安装程序不会移除以前的程序吗,如果我们是Major upgrades ,将OnlyDetect置为no,则会删除以前版本的程序,从而可以保证目标计算机中只有一个版本的product;如果是Minor upgrades ,我们需要将OnlyDetect置为yes。

如果开发一个本地化的软件包,你也可以在UpgradeVersion 中指定Language属性

注意在这里我定义了2个UpgradeVersion,他们的Property属性分别是PREVIOUSFOUND和NEWERFOUND。PREVIOUSFOUND是查找以前安装的版本,最低版本是1.0.0,它是始终不变的;最大版本是当前版本,需要在编译的传进来,这样做的目的是每次改变版本不用去修改源代码中的版本号;OnlyDetect置为no表示会删除掉找到的安装程序版本。比如当前版本是3.0.2,则在安装当前版本过程中,在版本1.0.0和3.0.2之间的任何版本都会被删除,包括修订版本。移除以前版本完全是自动的,如果我们要在移除以前版本前做任何事情,我们可以写一个custom action,设置它的conditionUPGRADINGPRODUCTCODE 属性的值。Windows Installer只是在自动删除的进程里才会设置这个属性,在添加/删除程序里手动删除程序不会设置该属性的值。

那么为什么要设置NEWERFOUND呢,试想如果你已经安装了2.0版本的程序,然后又安装1.0的版本的程序,一般情况下安装会正常进行,安装程序不能自动删除新版本的程序,这时候我们检测到新版本程序后就需要弹出错误提示,提示用户已安装更新的版本。如何做到这点呢,我们需要添加一个custom action,以下代码在FindRelatedProducts后如果找到新版本,则会执行NoDowngrade 的custom action,该action会弹出一个错误提示,阻止安装程序继续运行。

  1. <CustomAction Id='NoDowngrade' Error='已经安装了较新版本的 [ProductName],无法继续安装该版本应用程序 .' />

    <InstallExecuteSequence>
    <Custom Action='NoDowngrade' After='FindRelatedProducts'>NEWERFOUND</Custom>
    </InstallExecuteSequence>
    6.3 制作升级补丁(Minor upgrades And Small updates

 

到这里大家应该知道为什么我说Major upgrades 是最安全的,因为不管你之前安装的是什么版本,都会删除掉然后安装当前版本。而对于Minor upgrades,你需要针对每个不同版本安装包制作Patch更新包(msp),比如从1.1.0到1.1.1,从1.1.1到1.1.2,如果想从1.1.0到1.1.2,则需要重新制作Patch更新包(msp),当然也不是不可以制作通用于所有版本的Patch更新包(msp),前提是你要有所有版本安装包(msi),制作方法相对也比较繁琐,而且Minor upgrades还有诸多限制,如果处理不好会导致安装错误。当然如果你的安装文件体积太大,使用Major upgrades 就不合适了,一般情况下我们使用Minor upgrades ,下面我们就看看如何为Minor upgrades 制作Patch更新包(msp)。

制作制作Patch更新包之前,需要注意以下情形:

  • 当你需要新老版本共存时,则必须使用Major upgrades。
  • 当你需要更改生成的msi文件名称的时候,不能使用Minor upgradesSmall updates
  • 当你更改了Packge里任何Component的GUID时,不能使用Minor upgradesSmall updates
  • 当有组件被移除时,不能使用Minor upgradesSmall updates
  • 当更改了Feature的组织结构,比如在Feature中添加或删除子Feature时,不能使用Minor upgradesSmall updates

如果新版本满足这些条件,我们就可以开始制作更新包了,  这里我们将在新版本(1.0.1)安装中添加一个dll文件,然后更改exe执行文件。制作步骤如下:

1、编译生成1.0.0版本安装文件

  1. candle.exe -dVersion=1.0.0 -ext WixUtilExtension -ext WixSqlExtension Sample.wxs DbConfigDlg.wxs -out 1.0.0/
    light.exe -loc WixUI_zh-cn.wxl -ext WixUIExtension -ext WixUtilExtension -ext WixSqlExtension -out 1.0.0/Sample.msi 1.0.0/Sample.wixobj 1.0.0/DbConfigDlg.wixobj

2、 接着把1.0.0文件夹的内容复制到新的文件夹1.0.1中,用记事本随意修改FoobarAppl10.exe文件和Manual.pdf文件,以区别于1.0.0版本;

3、编译生成1.0.1版本安装文件

  1. candle.exe -dVersion=1.0.1 -ext WixUtilExtension -ext WixSqlExtension Sample.wxs DbConfigDlg.wxs -out 1.0.1/
    light.exe -loc WixUI_zh-cn.wxl -ext WixUIExtension -ext WixUtilExtension -ext WixSqlExtension -out 1.0.1/Sample.msi 1.0.1/Sample.wixobj 1.0.1/DbConfigDlg.wixobj

4、创建wix源文件Patch.wxs,内容如下:

  1. <?xml version='1.0' encoding='utf-8'?>
    <Wix xmlns='http://schemas.microsoft.com/wix/2006/wi'>
    <Patch AllowRemoval='yes' Manufacturer='Acme Ltd.' MoreInfoURL='www.acmefoobar.com'
    DisplayName='Police1.0.1.0 Patch' Description='Minor Update Patch' Classification='Update'>
    <Media Id='5000' Cabinet='SamplePatch.cab'>
    <PatchBaseline Id='SamplePatch' />
    </Media>
    <PatchFamily Id='SamplePatchFamily' Version='1.0.0.0' Supersede='yes'>
    <ComponentRef Id='compMainExecutable'/>
    <ComponentRef Id='compManual'/>
    </PatchFamily>
    </Patch>
    </Wix>

    Classification属性可以是: Hotfix, Security Rollup, Critical Update, Update, Service Pack or Update Rollup。AllowRemoval 属性确定用户在以后是否能够卸载该补丁包。

PatchFamily 标记包含要被修补的项目,Supersede决定是否目前的补丁包替换掉相同的系列里的所有以前的补丁包。PatchFamily 的子元素可以是ComponentRef或者FeatureRef等是对Sample.wxs文件中的元素引用,表示版本间不同的地方

5、使用另外一个wix工具torch在两个安装包之间来创建一个transform文件。命令行参数-xi指示程序使用wix自己的格式.wixpdb 和.wixmst,而不是Windows Installer格式 (.msi and .mst)。

  1. torch.exe -p -xi 1.0.0/Sample.wixpdb 1.0.1/Sample.wixpdb -out Patch.wixmst
    注意执行torch命令所在文件夹不能包含中文,否则执行会出现文件不存在的错误
    6、使用wix编译器和连接器生成补丁包,但是这次输出格式跟往常不一样,是.wixmsp格式的。在这里不需要告诉linker生成这种类型的文件,linker将根据源文件的内容自动决定生成什么格式的文件。
  1. candle.exe Patch.wxs
    light.exe Patch.wixobj
    7、最后,我们用上一步生成的wixmsp文件和刚才生成的transform文件来创建目前的Windows Installer 补丁包。Pyro是负责生成补丁包的wix工具,它不仅需要transform文件名,还需要相应的PatchBaseline/@Id属性,最好是用命令行模式:
  1. pyro.exe Patch.wixmsp -out Patch.msp -t SamplePatch Patch.wixmst

生成的patch.msp就是修补安装程序,为了测试它,我们先安装原始安装包(Error/Product.msi),然后添加修补程序:

  1. msiexec /p Patch.msp

检查文件是否真的被更新成新版本了。接着到添加/删除程序,选择显示更新,并移除第一个补丁,所做的更改将恢复到更新前的状态。

这里介绍的只是1对1版本的升级,也可以同时为多个不同的旧版本制作最终版本的升级包,有兴趣的可以参考sdk文档。下一章我们将介绍如何添加系统必备组件的安装程序。



Wix打包系列 (六)制作升级和补丁包的更多相关文章

  1. Wix打包系列(一)如何使用wix制作安装程序

    原文:Wix打包系列(一)如何使用wix制作安装程序 最近由于项目需要,需要给客户制作安装程序,一开始使用vs2005自带的打包工程来打包,但用了一段时间发现vs打包太死板,而且使用起来问题很多.收费 ...

  2. Wix打包系列(五) 部署数据库

    原文:Wix打包系列(五) 部署数据库 很多人在使用vs进行打包的时候,经常会为数据库部署的问题犯愁,即便是重写Installer类的方法,也不是很可靠方便,下面我们来看看在wix中如何部署数据库. ...

  3. Wix打包系列(七) 添加系统必备组件的安装程序

    原文:Wix打包系列(七) 添加系统必备组件的安装程序 我们知道在vs的打包工程中添加系统必备组件是一件很容易的事情,那么在wix中如何检测系统必备组件并在安装过程中安装这些组件.这里以.Net Fr ...

  4. Wix打包系列(四) 自定义UI

    原文:Wix打包系列(四) 自定义UI 除了标准的安装界面,如果我们要在安装时需要提供一些额外的信息时,这时就需要自定义界面来显示和录入这些信息. 4.1  自定义对话框 如上一章中我们测试数据库的连 ...

  5. Wix打包系列(三)自定义Action(Custom Action)

    原文:Wix打包系列(三)自定义Action(Custom Action) 3.1 关于Action 我们已经知道如何生成具有标准安装界面的安装程序了,Windows Installer按照我们的界面 ...

  6. Wix打包系列(二)用户界面和本地化操作

    原文:Wix打包系列(二)用户界面和本地化操作 上一章节,我们已经大概知道如何对文件进行打包安装,不过我们也注意到,通过对Sample.wxs的编译链接,生成的msi安装包没有任何用户界面,只有一个安 ...

  7. 如何使用Beyond Compare 对比差异文件【制作Patch(补丁包)文件】

    场景:研发部的代码从SVN变更至GIt,通过Jenkins每天自动生成程序包. 如需要获取单独的程序包更新,而不是整个程序包覆盖更新,这时候就需要用到Beyond Compare 对比工具 操作步骤1 ...

  8. DotNetBar for Windows Forms 12.9.0.0_冰河之刃重打包版及制作Visual Studio C#项目模板文件详解

    关于 DotNetBar for Windows Forms 12.9.0.0_冰河之刃重打包版 --------------------11.8.0.8_冰河之刃重打包版-------------- ...

  9. 如何查看SQL Server的版本、补丁包信息?以及如何鉴别是否需要升级自己的SQL Server?

    作为一个SQL Server的数据库管理人员,经常需要碰到的一个问题就是查看自己SQL Server属于哪个版本,是否安装了最新的修复补丁包,是否安装了最近的安全补丁.在此之前,我们可以通过以下SQL ...

随机推荐

  1. 80 多个 Linux 系统管理员必备的监控工具

    随着互联网行业的不断发展,各种监控工具多得不可胜数.这里列出网上最全的监控工具.让你可以拥有超过80种方式来管理你的机器.在本文中,我们主要包括以下方面: 命令行工具 网络相关内容 系统相关的监控工具 ...

  2. Codility上的问题 (17) PI 2012

    这个题比较简单,给定一个整数数组,对每个元素,求出和它最近比它大的数的距离(下标绝对值),如果没有比它大的数,认为距离是0. 数组元素个数 N [0..50000],数组元素范围[-10^9, +10 ...

  3. jquery特效 幻灯片效果

    jquery特效 幻灯片效果,效果图如下: <!DOCTYPE html> <html> <head> <meta http-equiv='Cont ...

  4. C# - 使用 List<> 泛型给GridView控件数据

    创建实体模型: namespace Test.Models { public class Student { public string ID { get; set; } public string ...

  5. HBASE完全分布式模式的安装

    1集群环境下hadoop.1.1.2已经安装成功 2配置hosts,及环境变量 3编辑hbase-env.xml 4编辑hbase-site.xml 5编辑regionservers文件 6把Hbas ...

  6. Indy10.2.5的危险做法

    为了排查一个Bug今天无意看了看Indy源码,结果吓了一跳.TIdIOHandler.ReadLongWord函数用于读取通讯数据并转换成LongWord类型返回,它做用了一种危险的做法可能会导致数据 ...

  7. Android开源框架AsyncHttpClient (android-async-http)使用

    android-async-http 开源框架可以使我们轻松地获取网络数据或者向服务器发送数据,最关键的是,它是异步框架,在底层使用线程池处理并发请求,效率很高,使用又特别简单. 以往我们在安卓上做项 ...

  8. 基于visual Studio2013解决面试题之0303数组求和

     题目

  9. Swift - AnyObject与Any的区别

    1,AnyObject :代表任何class类型的对象实例. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 class Man{ }   class Woman{ ...

  10. Maven项目下 java.lang.ClassNotFoundException 常规解决的方法

    网上非常多要改动.class .project的比較麻烦有时候还不一定管用.以下的方法适合于项目用已经引用了jar.可是执行时却ClassNotFound,请用例如以下方法试试: 严重: Error ...

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多