【问题标题】:Wix - How to handle minor upgrades with Enable Feature Selection turned on?Wix - 如何在启用功能选择打开的情况下处理小升级?
【发布时间】:2025-12-14 17:50:01
【问题描述】:

我们一直致力于使用自定义引导程序应用程序使用 WIX 和 Burn 重建我们的安装程序。我们在主 MSI 中使用功能树,并设置了 EnableFeatureSelection="yes",以便我们可以在自定义 BA UI 中复制功能树,并在计划/应用时将这些功能选择发送到 MSI。在我们最近开始测试升级过程之前,这一切都运行良好。我们在 Burn 中遇到了一个似乎是未解决的错误:

http://wixtoolset.org/issues/4616/

当我们进行次要升级时,已经安装的功能不会升级...最初安装的代码保留在机器上。从我们所做的测试和调查来看,我们认为这是因为 Burn 没有将 REINSTALL="ALL" 传递给 MSI 包(这就是上述错误所说的)。

我们发现这个问题,Rob 说你必须处理 OnPlanMsiFeature() 回调,我们正在正确地处理。

wix pass option to msi for repair

由于上述错误自 2014 年 12 月以来一直存在,我们不相信它会很快得到修复,因此我们决定尝试寻找解决方法。到目前为止,我们的想法充其量只是 hackish,但在概念验证级别上,它显示出一些希望。我们正在复制整个 MsiPackage 节点,为副本提供一个新 ID,并在其上添加一个 REINSTALL=ALL 属性,如下所示:

  <MsiPackage  Id="MSI"
    Cache="yes"
    Compressed="no"
    DisplayInternalUI="no"
    Vital="yes"
    Visible="yes"
    EnableFeatureSelection="yes"
    SourceFile="<path to MSI>">
  </MsiPackage>


  <MsiPackage  Id="MSI_REINSTALL"
    Cache="yes"
    Compressed="no"
    DisplayInternalUI="no"
    Vital="yes"
    Visible="yes"
    EnableFeatureSelection="yes"
    SourceFile="<path to MSI>">

    <MsiProperty Name="REINSTALL" Value="ALL"/>
  </MsiPackage>

然后,在我们的自定义 BA 中,我们使用 DetectRelatedMsiPackage 事件来检测次要升级。并在我们的 PlanPackageBegin 事件处理程序中使用该次要升级检测将每个 MsiPackage 的 RequestState 设置为 Local 或 None,如下所示:

            if (e.PackageId == "MSI")
            {
                if (Operation == RelatedOperation.MinorUpdate)
                {
                    e.State = RequestState.None;
                }
                else
                {
                    e.State = RequestState.Present;
                }
            }

            if (e.PackageId == "MSI_REINSTALL")
            {
                if (Operation == RelatedOperation.MinorUpdate)
                {
                    e.State = RequestState.Present;
                }
                else
                {
                    e.State = RequestState.None;
                }
            }

我们希望在启用 EnableFeatureSelection 的 Burn 升级中遇到此错误的其他人提供一些指导。我们的解决方法能完成这项工作吗?或者,有没有办法从自定义 BA 动态创建 MsiProperty,以便我们可以根据需要创建 REINSTALL=ALL?是否有人对如何解决这个问题有其他更清洁和/或更可靠的想法?

如果您需要更多信息,请告诉我。我们已经使用 Wix/Burn 工作了几个月,所以我们知道一些事情......但我们还不是专家。

【问题讨论】:

  • 这里的困难在于,次要更新严格来说是对现有已安装文件的更新,其中 REINSTALLMODE=vomus REINSTALL=ALL,受 REINSTALLMODE 变化的影响,并且在此类更新期间显示功能选择是一些事情我很怀疑。我怀疑 MSI 在更新文件时无法同时添加和删除功能。我相信您应该着眼于重大升级 - 这是安装升级产品并显示功能树的正常且简单的方法。
  • @PhilDW,根据我们所见,您是正确的……您无法更改您在次要更新中选择的功能。但我们并没有尝试。我们只希望之前已经安装的功能能够更新到新版本,而这并没有发生。当我们查看刻录日志时,当它调用 MSI 时,我们不会得到 REINSTALL=ALL。并且以前安装的组件没有更新......它们仍然具有原始版本。根本问题似乎是 EnableFeatureSelection 破坏了次要更新过程......我们正在努力寻找一个好的解决方法。

标签: wix windows-installer installation burn wix3.9


【解决方案1】:

几个月来,我们一直在运行我最初的问题中描述的“双 MSI”解决方案,并且它运行可靠。如果打开的错误得到修复,那么我们可以改变我们的方法。另外,如果有人有更好的答案,请告诉我。在此之前,我会将其标记为已回答。

【讨论】:

    【解决方案2】:

    如果您设置EnableFeatureSelection="no",则次要升级将按预期工作。如果您有EnableFeatureSelection="no",也许可以将“ADDLOCAL”添加为您想要更新的功能的MSIProperty,例如https://*.com/a/9679734/5698530。这篇文章也帮助了我https://*.com/a/15394954/5698530

    【讨论】:

    • 感谢您发布答案,但这不适用于我们的情况。由于我们希望用户能够选择安装哪些功能,我们不能在 XML 中做任何静态的事情……它必须通过代码来控制。几个月来,我们一直在使用我在原始问题中描述的“双 MSI”解决方案,一旦我们解决了问题,它就可以可靠地工作。我会把它写下来作为答案并标记它......我应该早点这样做。
    最近更新 更多