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

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

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

133588 次浏览

最后我找到了一个解决方案——我把它贴在这里,给其他可能有同样问题的人(你们5个人):

  • 将产品ID更改为*
  • 在product add下面

    <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>
    
  • Under InstallExecuteSequence add:

    <RemoveExistingProducts Before="InstallInitialize" />
    

From now on whenever I install the product it removed previous installed versions.

Note: replace upgrade Id with your own GUID

你最好在WiX-users邮件列表上问这个问题。

WiX最好在充分理解Windows安装程序的情况下使用。你可能会考虑得到"Windows安装程序的权威指南"。

删除现有产品的操作是RemoveExistingProducts行动。因为它所做的事情的结果取决于它的计划位置——即,失败是否导致旧产品重新安装,以及是否再次复制未更改的文件——您必须自己计划它。

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

RemoveExistingProducts的文档提到了设置UPGRADINGPRODUCTCODE属性。这意味着卸载过程用于被移除的产品接收到该属性,其值为正在安装的产品的Product/@Id

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

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

< a href = " http://wix.tramontana.co。Hu /tutorial/upgrade -and-modularization" rel="nofollow noreferrer">http://wix.tramontana.co.hu/tutorial/upgrades-and-modularization

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

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

另一个非常有用的网站是这个:

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

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>

请注意,如果您对构建非常谨慎,就可以防止人们意外地安装较旧版本的产品而不是较新的版本。这就是Maximum字段的作用。当我们构建安装程序时,我们将UpgradeVersion Maximum设置为正在构建的版本,但是IncludeMaximum="no"以防止这种情况。

您可以选择有关RemoveExistingProducts的调度。我更喜欢把它安排在InstallFinalize之后(而不是其他人推荐的InstallInitialize之后):

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

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

另一个好处是效率:如果有未更改的文件,当你在InstallFinalize之后调度时,Windows安装程序不会费心再次复制它们。如果在InstallInitialize之后进行调度,则会首先完全删除以前的版本,然后安装新版本。这会导致不必要的删除和重新复制文件。

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

以下是我用于主要升级的语法:

<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必须相同。

我建议你看看Alex Shevchuk的教程。他在从MSI到WiX,第8部分-主要升级用一个很好的实例解释了通过WiX进行的“重大升级”。

我正在使用最新版本的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相同。

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

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

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

我从教程中错过了一件重要的事情(从http://www.tramontana.co.hu/wix/lesson4.php偷来的),导致“此产品的另一个版本已经安装”错误:

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

小的升级 在产品版本已经更改的地方标记更改。修改Product标签的Version属性。产品将保持不变,因此您不需要更改product GUID,当然,需要获得一个新的Package GUID。

主要升级 表示重要的变化,比如从一个完整版本到另一个完整版本。更改所有内容:版本属性、产品和包guid。

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

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

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

这对我来说是有效的,即使是下来的主要成绩:

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

下面的内容对我很有用。

<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>

请确保“产品”中的“升级码”与“升级”中的“Id”匹配。