Wix ExePackage 并排安装无需卸载
Wix ExePackage Side by Side Install without Uninstall
我有两个产品正在尝试为其编写安装程序。两种产品都是 Wix 捆绑包,都需要第三个产品捆绑包。
理想情况下,当您安装一个时我希望发生的是:
- 如果没有安装 Product3,那么应该安装它。
- 如果安装了 Product3 并且安装的版本更高或相同,则什么都不做。
- 如果安装了 Product3 并且安装的版本较低,则升级。
- 如果卸载后产品 1 或 2 仍然安装,请不要卸载产品 3。
到目前为止,我能够征服其中的一些点,但不是同时征服所有点。
最初我尝试使用 ProductSearch 和 InstallCommand
获取安装版本。但是,我 运行 在并排安装时遇到卸载问题,因为安装命令更像是 "requested install state" ,所以如果我不希望它在检测到相同版本时安装它,它实际上会开始卸载它.
我看了下这个类似的回答:
How to avoid uninstalling previously installed ExePackage (redistributables) while installing a WiX Bundle?
建议使用 provideskey
和 requires
元素,但我找不到任何关于它们的有用文档。我尝试用它进行试验,但它似乎根本没有做任何事情。
我看过 RelatedBundle
,但我不确定这是我想要的。似乎更针对热修复系统。
我希望有一种方法可以做到这一点,而不必诉诸自定义操作,因为对于看似相当简单的功能来说,这似乎有点极端。
经过大量试验和错误后,我想出了如何让 DependencyExtension 正常工作。
在下面的示例中,ProductC 是一个 Wix Bundle 可执行文件。该捆绑包包含一个 MSI 文件。我使用 productSearch 来查找该 MSI 文件(不是捆绑包)的升级代码,以检测它是否已安装。
在项目 A 和 B 的捆绑文件中:
<Wix xmlns:dep="http://schemas.microsoft.com/wix/DependencyExtension"
xmlns:util="http://schemas.microsoft.com/wix/UtilExtension">
<Bundle>
<util:ProductSearch Id="ProductCInstallSearch"
UpgradeCode="{ProductC_MSI_UpgradeCode_GUID}"
Variable="ProductCInstalled"
Result="state"/>
<dep:Requires Id="ProductCRequired" ProviderKey="ProductC"/>
<Chain>
<PackageGroupRef Id="ProductC_pkg"/>
</Chain>
</Bundle>
<Fragment Id="Required_Pkgs">
<PackageGroup Id="ProductC_Pkg">
<ExePackage Id="ProductC_Bundle"
Permanent="no"
DetectCondition="NOT ProductCInstalled = 2"
InstallCommand="/quiet"
UninstallCommand="/uninstall /quiet">
<dep:Provides Key="ProductC"
Version="0.0.0.0">
<dep:RequiresRef Id="ProductCRequired"/>
</dep:Provides>
</ExePackage>
</PackageGroup>
</Fragment>
</Wix>
现在您可以任意排列安装A和B,卸载产品C只会在卸载最后一个产品时被删除。
我有两个产品正在尝试为其编写安装程序。两种产品都是 Wix 捆绑包,都需要第三个产品捆绑包。
理想情况下,当您安装一个时我希望发生的是:
- 如果没有安装 Product3,那么应该安装它。
- 如果安装了 Product3 并且安装的版本更高或相同,则什么都不做。
- 如果安装了 Product3 并且安装的版本较低,则升级。
- 如果卸载后产品 1 或 2 仍然安装,请不要卸载产品 3。
到目前为止,我能够征服其中的一些点,但不是同时征服所有点。
最初我尝试使用 ProductSearch 和 InstallCommand
获取安装版本。但是,我 运行 在并排安装时遇到卸载问题,因为安装命令更像是 "requested install state" ,所以如果我不希望它在检测到相同版本时安装它,它实际上会开始卸载它.
我看了下这个类似的回答:
How to avoid uninstalling previously installed ExePackage (redistributables) while installing a WiX Bundle?
建议使用 provideskey
和 requires
元素,但我找不到任何关于它们的有用文档。我尝试用它进行试验,但它似乎根本没有做任何事情。
我看过 RelatedBundle
,但我不确定这是我想要的。似乎更针对热修复系统。
我希望有一种方法可以做到这一点,而不必诉诸自定义操作,因为对于看似相当简单的功能来说,这似乎有点极端。
经过大量试验和错误后,我想出了如何让 DependencyExtension 正常工作。
在下面的示例中,ProductC 是一个 Wix Bundle 可执行文件。该捆绑包包含一个 MSI 文件。我使用 productSearch 来查找该 MSI 文件(不是捆绑包)的升级代码,以检测它是否已安装。
在项目 A 和 B 的捆绑文件中:
<Wix xmlns:dep="http://schemas.microsoft.com/wix/DependencyExtension"
xmlns:util="http://schemas.microsoft.com/wix/UtilExtension">
<Bundle>
<util:ProductSearch Id="ProductCInstallSearch"
UpgradeCode="{ProductC_MSI_UpgradeCode_GUID}"
Variable="ProductCInstalled"
Result="state"/>
<dep:Requires Id="ProductCRequired" ProviderKey="ProductC"/>
<Chain>
<PackageGroupRef Id="ProductC_pkg"/>
</Chain>
</Bundle>
<Fragment Id="Required_Pkgs">
<PackageGroup Id="ProductC_Pkg">
<ExePackage Id="ProductC_Bundle"
Permanent="no"
DetectCondition="NOT ProductCInstalled = 2"
InstallCommand="/quiet"
UninstallCommand="/uninstall /quiet">
<dep:Provides Key="ProductC"
Version="0.0.0.0">
<dep:RequiresRef Id="ProductCRequired"/>
</dep:Provides>
</ExePackage>
</PackageGroup>
</Fragment>
</Wix>
现在您可以任意排列安装A和B,卸载产品C只会在卸载最后一个产品时被删除。