WIX - 如何有选择地卸载 <Bundle>
WIX - How to selectively uninstall the <Bundle>
我想保留以前版本的 Bootstrapper 应用程序,如何实现?
我知道我们可以在 MSI 中使用升级标签,我们可以在其中识别不同的版本并根据这些版本执行卸载操作。
现在,我有一个捆绑应用程序,其中有一个或多个使用某些 UpgradeCode 的 MSI。每次我创建一个新版本时,我只是对 MSI 和这个捆绑应用程序进行版本升级。当我继续安装更高版本的 Bundle App 时,它会卸载以前的 Bundle 版本,这不是我想要的。我想保留以前版本的捆绑应用程序。
Bundle中是否也有类似UpgradeVersion的东西,我们可以在其中识别不同的版本并有选择地卸载。
我的 Bundle 文件代码片段:
<Bundle Name="myApp"
Version="1.0.0.0"
Manufacturer="Myself"
UpgradeCode="SOME-GUID">
<BootstrapperApplicationRef Id="ManagedBootstrapperApplicationHost" >
...
</BootstrapperApplicationRef>
<Chain>
<PackageGroupRef Id= 'WindowsInstaller45'/>
<PackageGroupRef Id ='NetFx45Offline'/>
<PackageGroupRef Id ='MY_MSI'/>
</Chain>
</Bundle>
<Fragment Id ='PkgFragments'>
<PackageGroup Id ="MY_MSI">
<MsiPackage SourceFile= "$(var.Installer.TargetPath)"
Id="MYAPP"
Cache ="yes"
Visible ="no"
DisplayInternalUI ="no"
Permanent="no">
<MsiProperty Name='INSTALLLOCATION' Value='[InstallFolder]' />
<MsiProperty Name='SELECT_UNINST' Value='[UninstallPrevVersion]' />
</MsiPackage>
</PackageGroup>
</Fragment>
我的产品 WIX 文件代码片段
<Product Id="*"
Name="$(var.ProductName)"
Version="$(var.ProductVersion)"
Manufacturer="$(var.ManufacturerName)"
UpgradeCode="$(var.UpgradeCode)">
<Property Id="SELECT_UNINST" Secure="yes">1</Property>
<Upgrade Id="SOME-GUID2">
<UpgradeVersion Minimum="0.0.0.0" Maximum="$(var.ProductVersion)" IncludeMinimum="yes" IncludeMaximum="yes" Property="UNINSTALL_PREV_VERSION" />
</Upgrade>
<CustomAction Id="UninstPrev" Property="UNINSTALL_PREV_VERSION" Value="0" />
<InstallExecuteSequence>
<Custom Action="UninstPrev" Before="InstallInitialize"><![CDATA[SELECT_UNINST <> 1]]></Custom>
<RemoveExistingProducts Overridable="no" After="UninstPrev"></RemoveExistingProducts>
</InstallExecuteSequence>
</Product>
我也会把这个作为答案。
如果您不想删除以前的版本,请不要将新版本视为对旧版本的升级。这意味着更改升级 GUID 并更改产品 GUID。如果您需要删除特定版本,请将捆绑包作为 添加到您的捆绑包定义中,并在您的 Bootstrapper 应用程序中正确处理 OnPlanRelatedBundle。
<RelatedBundle Action="Detect" Id="$(var.ProductVersion622UpgradeGUID)"/>
此外,如果您不想在 "upgrades" 之间删除,那么您 和 安装的任何 msi 软件包都需要采用与新升级 GUID 相同的行为。保留哪些 GUID 与哪些已发布版本的列表。如果你想删除你的 msi 版本中的特定版本,你需要添加
<Upgrade Id="$(var.Version6InstallerUpgradeGUID)" >
<UpgradeVersion
IncludeMaximum ="no"
IncludeMinimum="yes"
Maximum="6.0.0.1"
Minimum="6.0.0.0"
MigrateFeatures="no"
Property="V6FOUND"
OnlyDetect="no" />
</Upgrade>
我会认为这个要求很奇怪,建议你认真考虑一下你是否真的想支持这种行为。
还要注意,存在的引导程序的 ARP 条目并不一定意味着它安装的产品仍在系统上。您可以通过始终在 OnPlanRelatedBundle 中设置 pRequestedState = RequestState.Present;
并将您的 msi 包设置为 visible="yes" 来对此进行测试。您将在 ARP 中列出旧包,但它安装的包可能已由较新版本升级,因此它只是一个条目,没有任何意义。
我想保留以前版本的 Bootstrapper 应用程序,如何实现?
我知道我们可以在 MSI 中使用升级标签,我们可以在其中识别不同的版本并根据这些版本执行卸载操作。
现在,我有一个捆绑应用程序,其中有一个或多个使用某些 UpgradeCode 的 MSI。每次我创建一个新版本时,我只是对 MSI 和这个捆绑应用程序进行版本升级。当我继续安装更高版本的 Bundle App 时,它会卸载以前的 Bundle 版本,这不是我想要的。我想保留以前版本的捆绑应用程序。
Bundle中是否也有类似UpgradeVersion的东西,我们可以在其中识别不同的版本并有选择地卸载。
我的 Bundle 文件代码片段:
<Bundle Name="myApp"
Version="1.0.0.0"
Manufacturer="Myself"
UpgradeCode="SOME-GUID">
<BootstrapperApplicationRef Id="ManagedBootstrapperApplicationHost" >
...
</BootstrapperApplicationRef>
<Chain>
<PackageGroupRef Id= 'WindowsInstaller45'/>
<PackageGroupRef Id ='NetFx45Offline'/>
<PackageGroupRef Id ='MY_MSI'/>
</Chain>
</Bundle>
<Fragment Id ='PkgFragments'>
<PackageGroup Id ="MY_MSI">
<MsiPackage SourceFile= "$(var.Installer.TargetPath)"
Id="MYAPP"
Cache ="yes"
Visible ="no"
DisplayInternalUI ="no"
Permanent="no">
<MsiProperty Name='INSTALLLOCATION' Value='[InstallFolder]' />
<MsiProperty Name='SELECT_UNINST' Value='[UninstallPrevVersion]' />
</MsiPackage>
</PackageGroup>
</Fragment>
我的产品 WIX 文件代码片段
<Product Id="*"
Name="$(var.ProductName)"
Version="$(var.ProductVersion)"
Manufacturer="$(var.ManufacturerName)"
UpgradeCode="$(var.UpgradeCode)">
<Property Id="SELECT_UNINST" Secure="yes">1</Property>
<Upgrade Id="SOME-GUID2">
<UpgradeVersion Minimum="0.0.0.0" Maximum="$(var.ProductVersion)" IncludeMinimum="yes" IncludeMaximum="yes" Property="UNINSTALL_PREV_VERSION" />
</Upgrade>
<CustomAction Id="UninstPrev" Property="UNINSTALL_PREV_VERSION" Value="0" />
<InstallExecuteSequence>
<Custom Action="UninstPrev" Before="InstallInitialize"><![CDATA[SELECT_UNINST <> 1]]></Custom>
<RemoveExistingProducts Overridable="no" After="UninstPrev"></RemoveExistingProducts>
</InstallExecuteSequence>
</Product>
我也会把这个作为答案。
如果您不想删除以前的版本,请不要将新版本视为对旧版本的升级。这意味着更改升级 GUID 并更改产品 GUID。如果您需要删除特定版本,请将捆绑包作为
<RelatedBundle Action="Detect" Id="$(var.ProductVersion622UpgradeGUID)"/>
此外,如果您不想在 "upgrades" 之间删除,那么您 和 安装的任何 msi 软件包都需要采用与新升级 GUID 相同的行为。保留哪些 GUID 与哪些已发布版本的列表。如果你想删除你的 msi 版本中的特定版本,你需要添加
<Upgrade Id="$(var.Version6InstallerUpgradeGUID)" >
<UpgradeVersion
IncludeMaximum ="no"
IncludeMinimum="yes"
Maximum="6.0.0.1"
Minimum="6.0.0.0"
MigrateFeatures="no"
Property="V6FOUND"
OnlyDetect="no" />
</Upgrade>
我会认为这个要求很奇怪,建议你认真考虑一下你是否真的想支持这种行为。
还要注意,存在的引导程序的 ARP 条目并不一定意味着它安装的产品仍在系统上。您可以通过始终在 OnPlanRelatedBundle 中设置 pRequestedState = RequestState.Present;
并将您的 msi 包设置为 visible="yes" 来对此进行测试。您将在 ARP 中列出旧包,但它安装的包可能已由较新版本升级,因此它只是一个条目,没有任何意义。