前提
我使用的是WiX工具集3.5。
我已经成功地为我的产品发布了几个使用相同UpgradeCode和ProductCode的修补程序。然而,最近的两个补丁错误地使用了不同的UpgradeCode。这些修补程序安装成功,但我的最新修补程序拒绝安装。
以下是我自上次MSI发布以来的发布历史:
- 安装程序(10.0.20935.0),升级代码为A
- 升级代码为A的修补程序(10.0.21069.0)
- 升级代码为A的修补程序(10.0.21188.0)
- 升级代码为A的修补程序(10.0.21334.0)
- 升级代码为A的修补程序(10.0.21671.0)
- 带有升级代码B的修补程序(10.1.0.264)
- 带有升级代码C的修补程序(10.1.0.21682)
- 修补程序(10.2.0.0)是最新的修补程序,无论我使用UpgradeCode A、B还是C,都会失败
以下是我尝试安装补丁10.2.0.0:时出现的错误消息
Windows安装程序服务无法安装升级修补程序,因为要升级的程序可能丢失,或者升级修补程序可能会更新不同版本的程序。请验证您的计算机上是否存在要升级的程序,以及您是否有正确的升级补丁。
不允许用户安装修补程序。
问题
我需要发布一个的补丁
- 在生产中成功安装(10.1.0.21682)
- 允许我在将来继续发布修补程序
如何实现这一点?
我试过什么
我尝试过以下几种,但没有成功:
- 将UpgradeCode更改为A,即10.0.21671.0及更早版本的代码
- 将UpgradeCode更改为B,即从10.1.0.264更改为B
- 将UpgradeCode更改为C,即从10.1.0.21682更改为C
- 更改产品代码
- 创建一个从10.0.21671.0到10.2.0.0的补丁(当然在生产中它将在10.1.0.21682上运行)
以上所有场景都会导致相同的错误消息(在前提中给出)。我还在StackOverflow上发现了以下问题:
- WIX:升级时,当有两个不同的UpgradeCode时该怎么办
这导致我将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在错误消息中是否重要,而那篇关于通过重大升级升级多个产品的链接文章与这样的补丁问题无关,除非你担心重大升级,在这种情况下,你只列出了所有需要升级的UpgradeCode,所以这不是问题。
事实证明,解决方案很简单,只需禁用最新补丁的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。)