【问题标题】:WIX - How to selectively uninstall the <Bundle>WIX - 如何有选择地卸载 <Bundle>
【发布时间】:2016-09-06 16:11:52
【问题描述】:

我想保留之前版本的 Bootstrapper App,如何实现?

我知道我们可以在 MSI 中使用 Upgrade 标签,我们可以在其中识别不同的版本并根据这些执行卸载操作。

现在,我有一个捆绑应用程序,它具有一个或多个使用一些 UpgradeCode 的 MSI。每次我创建一个新版本时,我都会升级 MSI 和这个捆绑应用程序。当我继续安装更高版本的 Bundle App 时,它会卸载以前的 Bundle 版本,这不是我想要的。我想保留以前版本的 Bundle Application。

Bundle 中是否也有类似 UpgradeVersion 的东西,我们可以在其中识别不同的版本并选择性地卸载。

我的Bundle文件代码sn-p:

    <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 文件代码 sn -p

<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。保留每个升级 guid 的列表,当您想要删除它时,添加一个 标记来引用您想要删除的特定升级 GUID,并在您的 BootstrapperApplication dll 中相应地处理 OnPlanRelatedBundle。

标签: wix windows-installer


【解决方案1】:

我也会把这个作为答案。

如果您不想删除以前的版本,请不要将新版本视为对旧版本的升级。这意味着更改升级 GUID 并更改产品 GUID。如果您需要删除特定版本,请在您的 Bundle 定义中将 bundle 添加为 并在您的 Bootstrapper 应用程序中正确处理 OnPlanRelatedBundle。

<RelatedBundle Action="Detect" Id="$(var.ProductVersion622UpgradeGUID)"/>

此外,如果您不想在“升级”之间删除,那么您安装的任何 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 中列出旧包,但它安装的包可能已由较新版本升级,因此它只是一个没有任何意义的条目。

【讨论】:

  • 嗨,布赖恩,非常感谢您的回复。确实,这个要求很奇怪。实际上,在我们的安装过程中,我们会询问用户是否要卸载某些特定的先前版本。现在,即使我为新安装程序提供不同的 GUID,我也无法在运行时选择性地放置与这些 ID 对应的 。 MSI 通过 给了我这个选项,但我在 中看不到类似的东西
  • 我的流程类似于.....我有一个自定义 UI,它是在 WPF 中构建的,一个打包 WPF 和实际 Wix 安装程序的包。现在,ARP 中的条目应该是 Bundle 而不是 MSI(因为我希望在卸载期间显示我的自定义 UI)。这让我只有一个选择,我也会升级我的 Bundle。所以,最后让我们说如果我安装了 1.0.0.0 版本,那么在安装 2.0.0.0 期间我会询问用户是否要卸载 1.0.0.0 。如果用户选择是,那么 2.0.0.0 应该识别以前的版本(s )。
  • 没有看到您的整个产品,我无法理解您为什么要留下以前的版本。如果它们不是产品的升级,请不要将它们视为升级并使用相关捆绑包。处理 DetectRelatedBundle 并显示相应的 UI 信息,然后根据用户的选择处理 OnPlanRelatedBundle 事件以请求卸载或留下捆绑包。如果两个捆绑包中包含的 MSI 都在升级自己,那么即使您将旧捆绑包留在机器上,它安装的实际产品也不再存在,那么在 ARP 中包含它有什么意义?
猜你喜欢
  • 2016-05-21
  • 1970-01-01
  • 2014-02-20
  • 2015-01-25
  • 1970-01-01
  • 2010-12-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多