我的最后一个补丁以错误的 UpgradeCode 发布。我如何在后续补丁中修复此问题?

My last patch went out with the wrong UpgradeCode. How can I fix this in a subsequent patch?

前提

我正在使用 WiX 工具集 3.5。

我已经成功发布了几个使用相同 UpgradeCode 和 ProductCode 的产品补丁。但是,最近的两个补丁错误地以不同的 UpgradeCode 发布。这些补丁安装成功,但是我最新的补丁安装失败

这是自上次 MSI 发布以来我的发布历史:

  1. 带有升级代码 A 的安装程序 (10.0.20935.0)
  2. 带有 UpgradeCode A 的补丁 (10.0.21069.0)
  3. 带有 UpgradeCode A 的补丁 (10.0.21188.0)
  4. 带有 UpgradeCode A 的补丁 (10.0.21334.0)
  5. 带有 UpgradeCode A 的补丁 (10.0.21671.0)
  6. 补丁 (10.1.0.264) UpgradeCode B.
  7. 补丁 (10.1.0.21682) UpgradeCode C.
  8. Patch (10.2.0.0),最新的补丁,无论我使用UpgradeCode A、B还是C都失败

以下是我尝试安装补丁 10.2.0.0 时出现的错误消息:

The upgrade patch cannot be installed by the Windows Installer service because the program to be upgraded may be missing, or the upgrade patch may update a different version of the program. Verify that the program to be upgraded exists on your computer and that you have the correct upgrade patch.

不允许用户安装补丁。


问题

我需要发布一个

的补丁

如何实现?


我尝试了什么?

我尝试了以下方法,但没有成功:

以上所有场景都会导致相同的错误信息(前提给出)。我还在 Whosebug 上发现了以下问题:

这导致我将 OnlyDetect="no" 添加到我产品的 .wxs 文件中新 <Upgrade> 元素的 <UpgradeVersion> 元素:

<Upgrade Id="UpgradeCode C">
  <UpgradeVersion Property="OLD_PRODUCT_FOUND"
                  IncludeMaximum="yes"
                  Maximum="10.2.0.0"
                  MigrateFeatures="yes"
                  OnlyDetect="no" />
</Upgrade>

然而,这与之前的结果完全相同。


示例代码

我创建了一个小项目,用于复制我的场景。

下面是我的测试项目中产品版本 10.2.0.0 的 .wxs 文件:

<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
    <Product Id="{8CB0CC73-82B1-495E-B768-D1C38372678A}"
        Name="Sample Application"
        Language="1033"
        Version="10.2.0.0"
        Manufacturer="Sample Corporation"
        UpgradeCode="{7E72848F-FC99-4737-87DE-91C738B7C5EE}">

        <Package Description="Installs a file that will be patched."
            Comments="This Product does not install any executables"
            InstallerVersion="200"
            Compressed="yes" />

        <Media Id="1" Cabinet="product.cab" EmbedCab="yes" />
        <FeatureRef Id="SampleProductFeature"/>
    </Product>

    <Fragment>
        <Feature Id="SampleProductFeature" Title="Sample Product Feature" Level="1">
            <ComponentRef Id="Sample.txt" />
        </Feature>
    </Fragment>

    <Fragment>
        <DirectoryRef Id="SampleProductFolder">
            <Component Id="Sample.txt" Guid="{d738b2a9-0dbc-4381-9efd-5801723b1569}" DiskId="1">
                <File Id="Sample.txt" Name="Sample.txt" Source=".$(var.Version)\Sample.txt" />             
            </Component>    
        </DirectoryRef>
    </Fragment>

    <Fragment>
        <Directory Id="TARGETDIR" Name="SourceDir">
            <Directory Id="ProgramFilesFolder" Name="PFiles">
                <Directory Id="SampleProductFolder" Name="Patch Sample Directory">
                </Directory>
            </Directory>
        </Directory>
    </Fragment>
</Wix>

以下是版本 10.2.0.0 补丁的 .wxs 文件:

<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
    <Patch 
        AllowRemoval="no"
        Manufacturer="Sample Corp" 
        MoreInfoURL="http://www.dynamocorp.com/"
        DisplayName="Sample Patch" 
        Description="Small Update Patch" 
        Classification="Update"
        OptimizedInstallMode="yes">

        <Media Id="8000" Cabinet="RTM.cab" CompressionLevel="none">
            <PatchBaseline Id="RTM">            
            </PatchBaseline>
        </Media>

        <PatchFamilyRef Id="SamplePatchFamily"/>    
    </Patch>

    <Fragment>    
        <PatchFamily Id='SamplePatchFamily' Version='10.2.0.0' Supersede='no'>
        </PatchFamily>
    </Fragment>
</Wix>

您绝对不应该更改 ProductCode。如果您一直在构建更改了 UpgradeCode 的 MSI 文件,那么可能会更改更多关键项目。您构建了一个针对具有特定 ProductCode 和 PackageCode(基于您创建的 MSI 文件)的产品的补丁,这就是它想要的。

最重要的是,我会检查带有 UpgradeCode C 的补丁 7 是否更改了已安装产品的 ProductCode 或 PackageCode,因为这是产生问题的补丁,如果您的新补丁 8 找不到要修补的产品,那就是它将寻找的 ProductCode 和 PackageCode。这就是错误所说的 - 未安装此补丁程序所针对的 ProductCode(或 PackageCode)。换句话说,我非常怀疑 UpgradeCode 在该错误消息中是否重要,并且关于通过重大升级升级多个产品的链接文章与这样的补丁问题无关,除非您担心重大升级,在这种情况下您只需列出所有需要升级的 UpgradeCodes,所以这不是问题。

事实证明,解决方案就像禁用最新补丁的 UpgradeCode 验证一样简单。这可以通过将 Validate 上的 UpgradeCode 属性设置为 "no" 来完成。

<Media Id="8000" Cabinet="RTM.cab" CompressionLevel="none">
    <PatchBaseline Id="RTM">
        <Validate UpgradeCode="no" />
    </PatchBaseline>
</Media>

这个10.2.0.0补丁引入了一个新的UpgradeCode,在10.1.0.21682之上成功运行,我能够成功执行三个后续补丁。 (这些补丁启用了 UpgradeCode 验证并与 10.2.0.0 共享相同的 UpgradeCode。)