如何实施WiX安装程序升级?

在工作中,我们使用WiX来构建安装包。 我们希望产品X的安装将导致在该机器上卸载该产品的先前版本。

我已经在互联网上的几个地方读过关于重大升级,但不能得到它的工作。 任何人都可以请指定我需要采取添加卸载以前的版本功能到WiX的确切步骤?

在最新版本(来自3.5.1315.0 beta)中,您可以使用MajorUpgrade元素而不是使用自己的。

例如,我们使用这个代码来进行自动升级。 它可以防止降级,给出一个本地化的错误信息,也可以防止升级已经存在的相同版本(即只升级更低的版本):

<MajorUpgrade AllowDowngrades="no" DowngradeErrorMessage="!(loc.NewerVersionInstalled)" AllowSameVersionUpgrades="no" /> 

最后,我找到了一个解决方案 – 我在这里发布给其他人谁可能有同样的问题(你们五个):

  • 将产品ID更改为*
  • 在产品下添加以下内容:

     <Property Id="PREVIOUSVERSIONSINSTALLED" Secure="yes" /> <Upgrade Id="YOUR_GUID"> <UpgradeVersion Minimum="1.0.0.0" Maximum="99.0.0.0" Property="PREVIOUSVERSIONSINSTALLED" IncludeMinimum="yes" IncludeMaximum="no" /> </Upgrade> 
  • 在InstallExecuteSequence下添加:

     <RemoveExistingProducts Before="InstallInitialize" /> 

从现在开始,每当我安装产品,它删除了以前安装的版本。

注意:用您自己的GUID替换升级ID

以下是我用于重大升级的那种语法:

 <Product Id="*" UpgradeCode="PUT-GUID-HERE" Version="$(var.ProductVersion)"> <Upgrade Id="PUT-GUID-HERE"> <UpgradeVersion OnlyDetect="yes" Minimum="$(var.ProductVersion)" Property="NEWERVERSIONDETECTED" IncludeMinimum="no" /> <UpgradeVersion OnlyDetect="no" Maximum="$(var.ProductVersion)" Property="OLDERVERSIONBEINGUPGRADED" IncludeMaximum="no" /> </Upgrade> <InstallExecuteSequence> <RemoveExistingProducts After="InstallInitialize" /> </InstallExecuteSequence> 

正如@Brian Gillespie指出的那样,还有其他地方可以根据所需的优化安排RemoveExistingProducts。 请注意PUT-GUID-HERE必须相同。

Product元素中的Upgrade元素与适当的动作调度结合在一起就可以执行卸载。 请务必列出您要删除的所有产品的升级代码。

 <Property Id="PREVIOUSVERSIONSINSTALLED" Secure="yes" /> <Upgrade Id="00000000-0000-0000-0000-000000000000"> <UpgradeVersion Minimum="1.0.0.0" Maximum="1.0.5.0" Property="PREVIOUSVERSIONSINSTALLED" IncludeMinimum="yes" IncludeMaximum="no" /> </Upgrade> 

请注意,如果您对自己的构建非常小心,则可以防止人们意外地将旧版本的产品安装到较新的版本上。 这是最大值字段的用途。 当我们构建安装程序时,我们将UpgradeVersion Maximum设置为正在构建的版本,但IncludeMaximum =“no”以防止出现这种情况。

您可以选择有关RemoveExistingProducts的计划。 我更喜欢在InstallFinalize之后安排它(而不是像其他人所建议的那样在InstallInitialize之后):

 <InstallExecuteSequence> <RemoveExistingProducts After="InstallFinalize"></RemoveExistingProducts> </InstallExecuteSequence> 

这会使新版本的产品得到安装,直到复制新文件和注册表项。 这使我可以将数据从旧版本迁移到新版本(例如,您已将用户首选项的存储从注册表切换到XML文件,但您希望保持礼貌并迁移其设置)。 此迁移是在InstallFinalize之前的延迟自定义操作中完成的。

另一个好处是效率:如果文件没有变化,Windows安装程序在InstallFinalize之后安排时不会再次复制它们。 如果在InstallInitialize之后安排,则先前的版本将被完全删除,然后安装新版本。 这导致不必要的删除和重新复制文件。

有关其他计划选项,请参阅MSDN中的RemoveExistingProducts帮助主题。 本周,链接是: http : //msdn.microsoft.com/en-us/library/aa371197.aspx

在WiX用户邮件列表中,您最好问这个问题。

对于Windows Installer正在执行的操作,最好使用WiX。 您可能会考虑获得“ Windows安装程序权威指南 ”。

删除现有产品的操作是RemoveExistingProducts操作 。 因为它所做的后果取决于预定的位置 – 即失败是否会导致旧产品重新安装,以及是否再次复制未更改的文件 – 您必须自行安排。

RemoveExistingProducts处理当前安装中的<Upgrade>元素,将@Id属性与系统上所有已安装产品的UpgradeCode (在<Product>元素中指定)匹配。 UpgradeCode定义了一系列相关产品。 任何具有此UpgradeCode的产品(其版本落入指定的范围内,且UpgradeVersion/@OnlyDetect属性为no (或省略))都将被删除。

RemoveExistingProducts的文档提及设置UPGRADINGPRODUCTCODE属性。 这意味着要删除的产品的卸载过程接收该属性,该属性的值是正在安装的产品的Product/@Id

如果您的原始安装不包含UpgradeCode ,则无法使用此功能。

我使用这个网站来帮助我了解有关WiX升级的基础知识:

http://wix.tramontana.co.hu/tutorial/upgrades-and-modularization

之后,我创建了一个示例安装程序(安装了测试文件),然后创建了升级安装程序(安装了2个示例测试文件)。 这将使您对该机制如何工作有一个基本的了解。

正如Mike在Apress的书中所说:“Windows安装程序权威指南”,它将帮助您理解,但不是使用WiX编写的。

另一个很有帮助的网站是这样的:

http://www.wixwiki.com/index.php?title=Main_Page

我阅读了WiX文档,下载了示例,但升级后仍然遇到很多问题。 尽管可能指定那些卸载,次要升级不执行卸载以前的产品。 我花了更多的时间进行调查,发现WiX 3.5引入了一个新的标签升级。 这是用法:

 <MajorUpgrade Schedule="afterInstallInitialize" DowngradeErrorMessage="A later version of [ProductName] is already installed. Setup will now exit." AllowDowngrades="no" /> 

但问题的主要原因是文档说,使用“ 重新安装=所有REINSTALLMODE = vomus ”参数进行小型和小型升级,但并没有说这些参数是FORBIDDEN主要升级 – 他们只是停止工作。 所以你不应该使用它们进行重大的升级。

我建议看看Alex Shevchuk的教程。 他解释了通过WiX进行的“重大升级”,以及从MSI到WiX的第8部分 – 主要升级 。

我从教程中遗漏了一个很重要的东西(从http://www.tramontana.co.hu/wix/lesson4.php盗取),导致“该产品的另一个版本已经安装”错误:;

* 小的更新 意味着对一个或几个文件的小的更改,其中更改不保证更改产品版本(major.minor.build)。 您也不必更改产品GUID。 请注意,当您在任何方面创建一个与以前的.msi文件不同的新.msi文件时,您总是必须更改包GUID。 安装程序跟踪安装的程序,并在用户想要使用这些GUID更改或删除安装时找到它们。 对不同的软件包使用相同的GUID会使安装程序感到困惑。

次要升级 表示产品版本已经更改的更改。 修改产品标签的版本属性。 该产品将保持不变,所以您不需要更改产品GUID,但是,当然,获得一个新的包GUID。

主要升级 表示从一个完整版本转到另一个完整版本的重大变化。 更改一切:版本属性,产品和包GUID。

我正在使用最新版本的WiX(3.0),不能得到上述的工作。 但是这确实奏效了:

 <Product Id="*" UpgradeCode="PUT-GUID-HERE" ... > <Upgrade Id="PUT-GUID-HERE"> <UpgradeVersion OnlyDetect="no" Property="PREVIOUSFOUND" Minimum="1.0.0.0" IncludeMinimum="yes" Maximum="99.0.0.0" IncludeMaximum="no" /> </Upgrade> 

请注意,PUT-GUID-HERE应该与您在产品的UpgradeCode属性中定义的GUID相同。

下面为我​​工作。

 <Product Id="*" Name="XXXInstaller" Language="1033" Version="1.0.0.0" Manufacturer="XXXX" UpgradeCode="YOUR_GUID_HERE"> <Package InstallerVersion="xxx" Compressed="yes"/> <Upgrade Id="YOUR_GUID_HERE"> <UpgradeVersion Property="REMOVINGTHEOLDVERSION" Minimum="1.0.0.0" RemoveFeatures="ALL" /> </Upgrade> <InstallExecuteSequence> <RemoveExistingProducts After="InstallInitialize" /> </InstallExecuteSequence> 

请确保产品中的UpgradeCode与升级中的Id匹配。

这对我来说是很有用的,即使在大的DOWN级别:

 <Wix ...> <Product ...> <Property Id="REINSTALLMODE" Value="amus" /> <MajorUpgrade AllowDowngrades="yes" />