【问题标题】:WiX: CustomAction based on the outcome of another CustomActionWiX:基于另一个 CustomAction 的结果的 CustomAction
【发布时间】:2017-08-28 11:58:59
【问题描述】:

我对 WiX 还很陌生,所以我可能会问一些非常直截了当的问题,但我在谷歌上搜索时找不到太多帮助。

我想执行 2 个 customAction,比如 ca1 和 ca2,其中 ca2 的执行取决于 ca1 的结果,如下所示:

if ( ca1 == SUCCESS )
{
  Perform ca2
}

所以只有当我的 ca1 返回成功(没有失败)时,才应该执行 ca2。

在 WiX 中最简单的方法是什么?

【问题讨论】:

    标签: wix windows-installer wix3.5 wix3 wix3.6


    【解决方案1】:

    您所描述的是默认值。如果自定义操作失败,安装将中止,之后只能执行回滚操作。因此,要使您的问题有意义,首先您必须忽略或以其他方式掩盖您的第一个自定义操作的失败。

    其次,一个动作知道另一个动作的返回结果的唯一方法是它是否通过调用MsiDoAction(或其一些包装器)来调用它。这样做会模糊自定义操作之间的界限,因此我假设这不是您所描述的场景。

    这给您留下了第三种也是最后一种方法:找到外部沟通渠道。对于即时操作,我建议 ca1 在成功时设置一个属性(调用 MsiSetProperty 或像 DTF 的 session[property] 这样的包装器),然后 ca2 读取 (MsiGetProperty / MsiEvaluateCondition)或直接以该财产的价值为条件。对于延迟操作,属性不会传播,因此您必须识别其他通道。 (也许提前选择路径的临时文件会起作用。)

    但整个场景对于 Windows Installer 来说有点不寻常;我建议避免它。也许合并您的操作,以便在返回序列之前可以“内部”处理任何失败场景。或者,您的具体行为可能会导致提出更具体的建议。

    【讨论】:

    • 感谢您的回答。问题是,如果 ca1 失败,我不想中止并回滚安装,只是 ca2 在 ca1 失败时不会执行。 ca1 和 ca2 动作都是即时的,所以我认为使用第三种方式是正确的方式。那么如何根据 ca1 结果设置属性.. 任何示例代码?
    • 具体来说,在 ca1 中我要检查 windows 防火墙服务是否启用,在 ca2 中我会将我的应用程序作为例外添加到防火墙例外列表中。
    • 一个 CA 写入的 HKLM 密钥是否可以被第二个 CA 读取?即使在延迟模式下?我从未使用过这样的构造。对我来说似乎有点“部署臭”。无论哪种情况,我认为他应该尝试一下 WiX 的防火墙功能?
    • 谢谢,我考虑过只在一个电话中处理这两个操作。
    • @SteinÅsmul 虽然我看不出它不适用于提升操作的任何原因,但我建议避免使用它。我受到desktop bridge docs 中反对使用注册表进行进程间数据共享的警告的影响。当然,这种情况并不完全是进程间的,但它仍然是对注册表的另一种滥用。 (您可能对防火墙功能是正确的,或者在不考虑初始状态的情况下设置它。但这是基于 cmets;问答仍然更笼统。)
    【解决方案2】:

    您绝不能使用即时模式自定义操作对系统进行更改。当设置由具有提升权限的受限用户执行时,它们将永远不会正常运行(即时模式操作永远不会提升,它们总是模拟用户,因此您尝试更改的任何内容都会触发访问被拒绝)。此外,它们可能无法在静默执行模式下运行,具体取决于您的顺序(例如,如果您尝试从设置 GUI 调用它们)。

    Michael Urman 谈到的自定义操作之间的另一个“外部通信渠道”可能是 HKLM 中的一个注册表项,您可以写入然后读回。

    不过,真正的解决方案是尝试 WiX 的内置防火墙功能。它由知识渊博的 MSI 专家可靠编写,并支持适当的回滚。它将大大优于任何人可以自己滚动的内容: http://wixtoolset.org/documentation/manual/v3/xsd/firewall/firewallexception.html

    【讨论】:

    • 非常感谢您的意见。项目中已经有一个用 C++ 编写的防火墙 DLL,因此我无权更改它。但我希望您的回答对其他人有所帮助。
    • 好的,如前所述 - 确保不要在即时模式下运行自定义操作 - 否则您将看到企业部署问题,其中受限用户使用提升的权限进行安装。并且不要仅在设置 GUI (InstallUISequence) 中插入自定义操作 - 当您的设置以静默方式安装时,此序列将完全跳过。您应该使用插入到 InstallExecuteSequence 中的延迟自定义操作。如果您愿意,我可以在单独的答案中提供有关如何测试其是否有效的一些详细信息。
    【解决方案3】:

    来自 WiX 文档here

        <InstallExecuteSequence>
             <Custom Action='FooAction1' After='InstallFiles'/>
             <Custom Action='FooAction2' After='FooAction1' Condition='FOOACTION1SUCCESS'/>
        </InstallExecuteSequence>
    

    让 FooAction1 中的代码设置属性 MsiSetProperty('FOOACTION1SUCCESS', '1') 现在 FooAction2 只会在设置 FOOACTION1SUCCESS 属性时运行。但实际上迈克尔·乌尔曼的反应是正确的。您应该在一个自定义操作中处理所有异常。

    【讨论】:

      【解决方案4】:

      让第一个自定义操作设置一个属性。然后仅在该属性存在或设置为预期值时运行第二个自定义操作。

      【讨论】:

      • 谢谢,但您能否展示一些有关如何使用自定义操作设置属性的示例/参考代码。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-04-19
      • 1970-01-01
      • 1970-01-01
      • 2018-07-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多