在工作中,我们使用WiX来构建安装包。我们希望产品X的安装会导致该机器上该产品以前版本的卸载。
我已经在互联网上的几个地方读到一个重大升级,但不能让它工作。 任何人可以指定我需要采取的确切步骤,以添加卸载以前版本的功能到WiX?
在工作中,我们使用WiX来构建安装包。我们希望产品X的安装会导致该机器上该产品以前版本的卸载。
我已经在互联网上的几个地方读到一个重大升级,但不能让它工作。 任何人可以指定我需要采取的确切步骤,以添加卸载以前版本的功能到WiX?
最后我找到了一个解决方案——我把它贴在这里,给其他可能有同样问题的人(你们5个人):
将产品ID更改为* 产品下添加以下内容: <Property Id="PREVIOUSVERSIONSINSTALLED" Secure="yes" /> <升级Id = " YOUR_GUID " > < UpgradeVersion 最大最小= " 1.0.0.0 " = " 99.0.0.0 " 属性= " PREVIOUSVERSIONSINSTALLED " IncludeMinimum="yes" IncludeMaximum="no" /> > < /升级 在InstallExecuteSequence下添加: <RemoveExistingProducts Before="InstallInitialize" />
从现在开始,每当我安装产品,它删除以前安装的版本。
注意:请将升级Id替换为自己的GUID
您最好在WiX-users邮件列表中询问这个问题。
WiX最好在充分理解Windows安装程序的情况下使用。你可以考虑获得“Windows安装程序权威指南”。
删除现有产品的操作是RemoveExistingProducts操作。因为它所做的事情的结果取决于它的计划位置——即,失败是否导致旧产品重新安装,以及是否再次复制未更改的文件——您必须自己计划它。
RemoveExistingProducts processes <升级当前安装中的>元素,将@Id属性匹配到系统上所有已安装产品的UpgradeCode(在<Product>元素中指定)。UpgradeCode定义了一系列相关产品。任何具有此UpgradeCode的产品,其版本落在指定的范围内,且UpgradeVersion/@OnlyDetect属性为no(或省略),将被删除。
RemoveExistingProducts的文档提到了设置UPGRADINGPRODUCTCODE属性。这意味着要移除的产品的卸载过程接收到该属性,其值是正在安装的产品的product /@Id。
如果您的原始安装不包括升级码,您将无法使用此功能。
我使用这个网站来帮助我了解有关WiX升级的基础知识:
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必须相同。
我正在使用最新版本的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偷来的),导致“此产品的另一个版本已经安装”错误:
*Small updates mean small changes to one or a few files where the change doesn't warrant changing the product version (major.minor.build). You don't have to change the Product GUID, either. Note that you always have to change the Package GUID when you create a new .msi file that is different from the previous ones in any respect. The Installer keeps track of your installed programs and finds them when the user wants to change or remove the installation using these GUIDs. Using the same GUID for different packages will confuse the Installer.
次要升级表示产品版本已经更改的更改。修改Product标签的Version属性。产品将保持不变,因此您不需要更改product GUID,当然,需要获得一个新的Package GUID。
主要升级是指从一个完整版本到另一个完整版本的重大变化。更改所有内容:版本属性、产品和包guid。
我阅读了WiX文档,下载了示例,但在升级时仍然有很多问题。次要升级不执行以前产品的卸载,尽管有可能指定这些卸载。我花了一天多的时间进行调查,发现WiX 3.5引入了一个用于升级的新标签。用法如下:
<MajorUpgrade Schedule="afterInstallInitialize"
DowngradeErrorMessage="A later version of [ProductName] is already installed. Setup will now exit."
AllowDowngrades="no" />
但是问题的主要原因是文档中说要在小升级和小升级中使用“重装=ALL REINSTALLMODE=vomus”参数,但它并没有说这些参数在大升级中是禁止的——它们只是停止工作。所以你不应该在重大升级时使用它们。
这对我来说很管用,即使我的主要成绩是DOWN:
<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”匹配。