首页 文章

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

提问于
浏览
220

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

我已经在互联网上的几个地方读过有关重大升级的内容,但无法让它发挥作用 . 任何人都可以指定我需要采取的确切步骤,以便将卸载以前的版本功能添加到WiX吗?

12 回答

  • 1

    我正在使用最新版本的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应与您在Product的UpgradeCode属性中定义的GUID相同 .

  • 7

    在最新版本(从3.5.1315.0测试版)中,您可以使用MajorUpgrade element而不是使用自己的版本 .

    例如,我们使用此代码进行自动升级 . 它可以防止降级,提供本地化的错误消息,还可以防止升级已存在的相同版本(即只升级较低版本):

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

    最后我找到了一个解决方案 - 我在这里发布给其他可能遇到同样问题的人(所有5个人):

    • 将产品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" />
    

    从现在开始,每当我安装产品时,它都会删除以前安装的版本 .

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

  • 2

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

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

  • 87

    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之前的延迟自定义操作中完成 .

    另一个好处是效率:如果文件未更改,则在安装StartFinalize之后安排时,Windows Installer不会再次复制它们 . 如果您在InstallInitialize之后安排,则先完全删除先前版本,然后安装新版本 . 这导致不必要的删除和重新复制文件 .

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

  • 5

    你最好在WiX-users mailing list上问这个问题 .

    WiX最适合用于对Windows Installer正在做的事情的深入了解 . 你可能会考虑得到“The Definitive Guide to Windows Installer” .

    删除现有产品的操作是RemoveExistingProducts action . 因为它所做的后果取决于它的安排位置 - 即,故障是否导致重新安装旧产品,以及是否再次复制未更改的文件 - 您必须自己安排它 .

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

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

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

  • 167

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

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

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

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

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

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

  • 7

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

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

    但是 main reason 问题是文档说使用“ REINSTALL=ALL REINSTALLMODE=vomus ”参数进行次要和小型升级,但并没有说这些参数是 FORBIDDEN for major upgrades - 它们只是停止工作 . 所以你不应该在主要升级时使用它们 .

  • 40

    我建议看一下Alex Shevchuk的教程 . 他在From MSI to WiX, Part 8 - Major Upgrade以一个很好的动手实例通过WiX解释了"major upgrade" .

  • 10

    我从教程中遗漏了一段时间(从http://www.tramontana.co.hu/wix/lesson4.php被盗)导致"Another version of this product is already installed"错误的一件重要事情:

    • Small updates 表示对一个或几个文件的小更改,其中更改也不必更改产品GUID . 请注意,在创建与以前版本不同的新.msi文件时,始终必须更改包GUID . 安装程序会跟踪已安装的程序,并在用户想要使用这些GUID更改或删除安装时查找它们 . 对不同的包使用相同的GUID会使安装程序混淆 .

    Minor upgrades 表示产品版本已经更改的更改 . 修改Product标记的Version属性 . 产品将保持不变,因此您无需更改产品GUID,但当然会获得新的包GUID .

    Major upgrades 表示从一个完整版本到另一个完整版本的重大变化 . 更改所有内容:版本属性,产品和包GUID .

  • 15

    以下为我工作 .

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

    请确保Product中的UpgradeCode与升级中的Id匹配 .

  • 11

    这对我有用,即使主要是 DOWN 等级:

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

相关问题