Windows安装程序在产品升级期间删除版本化文件,而不是降级它

时间:2010-11-19 17:01:47

标签: wix windows-installer

我们使用wix来创建我们的设置。对于升级,我们使用this answer by Rob Mensching中演示的主要升级。 (在较新的wix版本中,您可以使用MajorUpgrade元素。)这通常很有效。删除旧产品,然后安装新产品。

但是,显然上述内容并不完全等同于手动卸载旧产品,然后手动安装新产品。

例如考虑以下场景:

  • 我们的产品版本1.0已发布,包含第三方dll的5.0版本
  • 我们产品的1.1版已发布,包含相同的第三方dll版本5.1
  • 我们产品的1.2版本已经发布,再次降级到第三方dll的5.0版本,因为我们发现新版本引入的问题多于解决的问题。

显然,使用上面链接的wix升级逻辑,从版本1.1升级到1.2时,第三方dll将消失。修复是必要的,以恢复它。

是否有其他升级方式,这适用于此方案?我想我正在寻找的是升级逻辑,它允许降级组件,其行为就像手动卸载旧产品然后手动安装新产品一样。

6 个答案:

答案 0 :(得分:7)

我们还遇到了这样的问题,即在主要升级时没有重新安装较低版本的DLL。我觉得很奇怪,安装程序会根据现有文件的版本确定要安装哪些文件,然后完全卸载所有文件,但仍然只安装已确定安装的文件卸载旧产品。这似乎可能是Windows Installer中的一个错误...

要解决此问题,我们已将RemoveExistingProducts操作移到CostFinalize操作之上。

我知道documentation on MSDN建议在RemoveExistingProducts之后放置InstallValidate,我不确定在InstallValidate行动之前放置{{1}}对未成年人有任何负面影响升级,但我们决定只对我们的产品进行重大升级,因此这个解决方案似乎对我们有用。

答案 1 :(得分:4)

这样的行为通常与RemoveExistingProducts的排序有关。如果它发生得足够晚,Windows Installer会发现计算机上有更新版本的.dll,因此版本1.2不需要安装它。但是,当RemoveExistingProducts导致删除.dll时,没有任何内容将其删回。

尝试的方法包括更改RemoveExistingProducts的顺序,并在1.2包中说明.dll的版本(报告版本号高于错误的版本号)。后者的缺点是对维修或修补的影响很小,因为.dll总是看起来过时。

答案 2 :(得分:1)

尝试在InstallValidate之后立即安排RemoveExistingProducts,并将REINSTALLMODE属性的值更改为amus。这样,在复制新产品的任何文件之前,旧产品将被完全删除,a模式将强制重新安装文件。

答案 3 :(得分:0)

这是次优的,但我通过重命名第三方dll并更改.wxs文件中与之关联的组件节点上的GUID来解决同样的问题。

答案 4 :(得分:0)

几年后,该主题帮助我朝着正确的方向发展。成本计算前将RemoveExisitingProducts移到一个完整示例:

<Upgrade Id="UPGRADE-GUID-HERE">
    <UpgradeVersion OnlyDetect="no" Property="UPGRADABLEFOUND"
        Maximum="$(var.ProductVersion)" IncludeMaximum="yes" />
    <UpgradeVersion OnlyDetect="yes" Property="NEWERFOUND"
        Minimum="$(var.ProductVersion)" IncludeMinimum="no" />
</Upgrade>

<InstallExecuteSequence>
    <Custom Action="NoDowngrade" After="FindRelatedProducts">NEWERFOUND</Custom>
    <RemoveExistingProducts Before="CostInitialize" />
</InstallExecuteSequence>

<CustomAction Id="NoDowngrade" Error="A newer version of $(var.ProductName) is already installed." />

答案 5 :(得分:0)

这是我根据@Spacemani给出的答案的最终解决方案。

它产生与此类似的MSI表条目(Upgrade,LaunchCondition等)

<MajorUpgrade DowngradeErrorMessage="!(loc.DowngradeErrorMessage)" />

但可以完全控制InstallExecuteSequence。

<!-- Product upgrade -->
<Upgrade Id="$(var.UpgradeCode)">
  <UpgradeVersion OnlyDetect="no" Property="WIX_UPGRADE_DETECTED"
                  Maximum="$(var.ProductVersion)" IncludeMaximum="no" IncludeMinimum="no"
                  MigrateFeatures="yes" />
  <UpgradeVersion OnlyDetect="yes" Property="WIX_DOWNGRADE_DETECTED"
                  Minimum="$(var.ProductVersion)" IncludeMinimum="no" />
</Upgrade>
<InstallExecuteSequence>
  <RemoveExistingProducts Before="CostInitialize" />
</InstallExecuteSequence>
<Condition Message="!(loc.DowngradeErrorMessage)">NOT WIX_DOWNGRADE_DETECTED</Condition>

请注意,您需要像这样抑制.wixproj文件中的ICE27错误。

<PropertyGroup>
  <SuppressIces>ICE27</SuppressIces>
</PropertyGroup>
相关问题