2017-08-28 116 views
0

我对WiX相当陌生,因此我可能会问一些非常简单的问题,但我找不到太多的帮助来搜索它。WiX:CustomAction基于另一个CustomAction的结果

我想执行2个customActions,也就是说,CA1和CA2,其中钙的执行取决于CA1的结果,类似下面:

if (ca1 == SUCCESS) 
{ 
    Perform ca2 
} 

所以钙应该只,如果我的CA1返回成功执行(不会失败)。

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

回答

5

你描述的是默认值。如果自定义操作失败,安装将中止,并且以后只能执行回滚操作。因此,为了让您的问题合理化,首先您必须忽略或以其他方式掩盖您的第一个自定义操作失败。

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

这会让您用第三种也是最后的方式找到外部沟通渠道。对于直接行动,我建议ca1在成功后设置财产(请拨打MsiSetProperty或DTF会话[财产]的包装),并且ca2读取(MsiGetProperty/MsiEvaluateCondition)或直接针对该财产的价值进行调整。对于延迟操作,属性不会传播,因此您必须识别其他频道。 (也许临时文件的路径被选择提前选择)

但是整个场景对于Windows Installer来说有点不寻常;我会建议避免它。也许合并你的行为,以便任何故障情景可以在回到序列之前“内部”处理。或者你的行为的具体细节可能会导致更具体的建议。

+0

感谢您的回答。事情是,我不想中止和回滚安装,如果CA1失败,只是CA2不执行CA1失败。 ca1和ca2的动作都是直接的,所以我认为使用第三种方式就是这种方式。那么如何根据ca1结果设置属性..任何示例代码? – foobar

+0

具体而言,在ca1中,我想检查是否启用了Windows防火墙服务,并且在ca2中,我将在防火墙例外列表中将我的应用程序添加为例外。 – foobar

+0

由一个CA编写的HKLM密钥是否可由第二个CA读取?即使在延期模式?我从未使用过这样的结构。似乎有点“部署臭”给我。无论如何,我认为他应该尝试使用WiX的防火墙功能? –

0

让第一个自定义操作设置属性。然后,如果该属性存在或设置为期望值,则只运行第二个自定义操作。

+0

谢谢,但你能展示一些关于如何使用防火墙的示例/参考代码使用自定义操作设置属性。 – foobar

2

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

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

但是,真正的解决方案是尝试WiX的内置防火墙功能。它由知识丰富的MSI专家可靠编写,并支持适当的回滚。这将大大优于别人怎么能对自己的滚动: http://wixtoolset.org/documentation/manual/v3/xsd/firewall/firewallexception.html

+0

非常感谢您的输入。已经有一个用C++编写的防火墙DLL正在项目中使用,所以我无权更改它。但我希望你的回答会帮助别人。 – foobar

+1

好的,如上所述 - 请务必不要在即时模式下运行自定义操作 - 否则您将看到受限用户使用提升权限进行安装的企业部署问题。并且不要将自定义操作仅插入安装GUI(InstallUISequence)中 - 当您的安装程序安装无提示时,完全跳过此顺序。您应该使用插入到InstallExecuteSequence中的延迟自定义操作。如果你喜欢单独的答案,我可以提供一些关于如何测试这个工作的细节。 –

1

从维克斯文档here

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

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