如何在wix bundle hotfix chain中设置检测和安装条件,以便可以卸载产品

时间:2017-02-06 19:21:13

标签: wix

设置如下:我有一个RTM wix包(2.0),链中有3个包。我们会说P1,P2和P3。是否重要P3是一个ExePackage,它是一个给我带来麻烦的。另外,我正在使用由我公司开发和维护的引导程序,所以我可以控制一些东西,有些我不能。

在RTM P3包中定义如下:

<PackageGroup Id="P3">
  <ExePackage Id="p3"
              Cache="yes"
              Compressed="yes"
              PerMachine="yes"
              Permanent="no"
              Vital="yes"
              InstallCommand="/quiet /norestart"
              SourceFile="Resources\p3.exe"
              DetectCondition="P3Version"
              InstallCondition="Not P3Version"
              UninstallCommand="/quiet /uninstall /norestart">
  </ExePackage>
</PackageGroup>

所有这些工作正常,直到我不得不为捆绑编写一个修补程序(补丁)。专门修补P2。我遇到的第一个问题是当我尝试卸载此修补程序时。卸载此修补程序基本上只在RTM软件包上运行重新安装,并且由于安装了P3,由于上述条件,它最终会被取消安装。

据我所知,由于已经发货,我无法修改捆绑条件。如果有人知道热修补一个很棒的捆绑。

我尝试过的事情:

从仅安排在MSIPATCHREMOVE上运行的自定义操作运行P3的重新安装。这似乎不起作用,因为显然多个MSI不能同时执行。

我将P3添加到我的修补程序捆绑链中。这解决了卸载此修补程序时的问题,因为此修补程序包现在卸载P3,然后重新安装RTM看到P3不存在...并再次安装它。但这引入了一个新问题。我必须能够从ARP菜单一次卸载整个产品。通过RTM卸载菜单执行卸载也应该卸载所有相关的包。当发生这种情况时,似乎两个捆绑包都试图卸载P3。修补程序包似乎赢了并从包缓存中删除了exe。这最终导致RTM捆绑包中的错误并且无法卸载。

感谢任何建议。

1 个答案:

答案 0 :(得分:1)

横向规则下面基本上描述了为什么你被搞砸了但是通过重新阅读你的帖子我更了解这个问题所以我会给你一个更好的解决方案。

首先,不要在这里使用InstallCondition。我认为您使用InstallCondition偶然发现了最糟糕的情况。我想如果你从Hotfix ExePackage描述中删除InstallCondition,这仍然有用。

只有从RTM引导程序卸载时,您才能在Hotfix引导程序应用程序代码中修改P3 ExePackage的计划状态。

(这是针对非托管c ++ BA,应该适用于C#,只需要找到合适的方法/事件处理程序)

因此,在您的Hotfix BA中,我们需要转到“OnPlanPackageBegin”

如果Hotfix BA正在卸载且relationType不是NONE,我们在这里要做的是计划对P3 ExePackage执行NOTHING。所以像这样我认为

virtual STDMETHODIMP_(int) OnPlanPackageBegin(
    __in_z LPCWSTR wzPackageId,
    __inout BOOTSTRAPPER_REQUEST_STATE *pRequestState
    )
{
    // stuff that was here already
    // ...

    if (wcsstr(wzPackageId, L"p3") && m_command.relationType != BOOTSTRAPPER_RELATION_NONE) // "p3" should be the Id of the P3 ExePackage 
    {
          pRequestState = BOOTSTRAPPER_REQUEST_STATE_NONE;
    }      

    return CheckCanceled() ? IDCANCEL : IDOK;
}

我对关系类型不是100%肯定,但我相信当其他引导程序应用程序卸载/运行时,它将计划对修补程序BA中的p3 ExePackage不做任何操作。这样,如果卸载RTM,HotfixBA应该单独保留p3 ExePackage,以便RTM BA可以删除它。

我也会测试RTM BA的修改/修复。您可能需要在if中添加类似&& m_command.action == BOOTSTRAPPER_ACTION_UNINSTALL的内容,我不确定。

我还会测试升级方案,因为我不太确定在尝试删除旧的RTM BA时会发生什么。我认为它将使用良好的引用计数并留下P3.exe,但我不确定。如果它确实尝试删除它不应该你可能需要作者一个新的P3.exe修改p3Version的注册表位置(??),以便旧的BA认为它已经没有安装,什么都不做。如果您无法更改注册表位置,则可能需要通过在安装MSI之前安排p3并删除/移动版本注册表并适当更新检测条件来修改注册表。这里有很多需要考虑......

<小时/>

问题是您的InstallCondition在安装产品时始终为false,因此将始终卸载。 InstallCondition 的行为与我最初预期的一样,现在我主要避免它。

InstallCondition

  

安装软件包之前要评估的条件。只有在条件计算结果为true时才会安装该程序包。如果条件评估为false并且正在安装,修复或修改软件包,则将卸载软件包。

您通常希望将此设置为必须满足的条件才能使您的产品正常运行。这也可以用作可选安装的属性,例如用户可以选择在引导程序的UI阶段安装或不安装的附加组件。

不要将它用作检测何时安装的方法,因为它确实是“可以安装时检测,否则不安装/卸载”。如果产品不存在,则使用检测条件确定何时安装。 InstallCondition的默认值只是假设它应该被安装。