如何在wix bundle修补程序链中设置检测和安装条件,以便卸载产品

如何在wix bundle修补程序链中设置检测和安装条件,以便卸载产品,wix,Wix,设置如下:我有一个RTMwix捆绑包(2.0),在链中有3个包。我们会说P1、P2和P3。不管它是否重要,P3是一个软件包,正是它给我带来了麻烦。此外,我正在使用由我的公司开发和维护的引导程序,因此有些事情我可以控制,有些事情我不能 在RTM P3包中,定义如下: <PackageGroup Id="P3"> <ExePackage Id="p3" Cache="yes" Compressed="yes"

设置如下:我有一个RTMwix捆绑包(2.0),在链中有3个包。我们会说P1、P2和P3。不管它是否重要,P3是一个软件包,正是它给我带来了麻烦。此外,我正在使用由我的公司开发和维护的引导程序,因此有些事情我可以控制,有些事情我不能

在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捆绑包中出现错误并导致卸载失败


任何建议都将不胜感激。

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

首先,不要在这里使用InstallCondition。我认为您使用InstallCondition时遇到了最坏的情况。我认为,如果您从修补程序包描述中删除InstallCondition,这仍然有效

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

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

因此,在您的修补程序BA中,我们需要转到“OnPlanPackageBegin”

我们在这里要做的是,如果热修复程序BA正在卸载,并且relationType不是NONE,则计划不对P3 ExePackage执行任何操作。我想是这样的

我不是100%确定relationType,但我相信这将不会对修补程序BA中的p3 ExePackage起到任何作用,因为它是由另一个引导程序应用程序卸载/运行的。这样,如果卸载RTM,HotfixBA应该将p3 ExePackage单独保留,以便RTM BA可以删除它

我还将测试RTM BA的修改/修复。您可能需要在if中添加类似
&&m\u command.action==BOOTSTRAPPER\u action\u UNINSTALL
的内容,我不确定

我还将测试升级场景,因为我不太确定当它尝试删除旧的RTM BA时会发生什么。我认为它将使用良好的引用计数,并留下P3.exe,但我不确定。如果它确实尝试在不应该的时候删除它,您可能需要编写一个新的P3.exe,它会修改P3版本的注册表位置(??),以便旧BA认为它尚未安装,而什么也不做。如果您无法更改注册表位置,则可能需要在MSI安装前安排p3,删除/移动版本注册表,并适当更新检测条件,从而修改注册表。这里需要考虑很多……

问题是,在安装产品时,InstallCondition始终为false,因此将始终卸载。InstallCondition没有像我最初预期的那样运行,现在我基本上避免了它

安装程序包之前要评估的条件。仅当条件评估为true时,才会安装包。如果条件评估为false,并且正在安装、修复或修改包,则将卸载包

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

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

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;
}