Windows Installer自定义操作:不会执行提交操作

时间:2013-10-28 09:46:50

标签: wix windows-installer custom-action

我正在使用WIX设计一个Windows安装程序项目。现在它在安装中失败,因为提交自定义操作将不会被执行,这很奇怪,因为计划的后续自定义操作有一条路由返回ActionResult.Success。让我详细解释一下:

基本上我有两个关于安装的自定义操作:一个叫做CommitCA,一个叫做InstallCA。执行计划如下所示:

<CustomAction Id="CommitCA" BinaryKey="CustomActionDll" DllEntry="CommitCA" Execute="commit" Return="check" Impersonate="no"/>
<CustomAction Id="InstallCA" BinaryKey="CustomActionDll" DllEntry="InstallCA" Execute="deferred" Return="check" Impersonate="no"/>

我已经从ORCA验证,在编译的安装程序中,CommitCA是在InstallCA之前安排的。 CommitCA的类型是3585,InstallCA是3703(我找不到对它们的引用,但我假设一个用于提交操作,另一个是像我声明的那样的延迟操作)。想法是在CommitCA中它将生成一些将由InstallCA使用的文件。

我的InstallCA的结构如下所示:

Try
    ' Do some work
    ...

Catch ex As Exception
    ' Log the failure into installation log
    Return ActionResult.Failure
End Try
Return ActionResult.Success

令人困惑的部分:最初我有一个工作版本,我在ActionResult.Failure块中没有返回Catch的行。换句话说,该函数仍然记录失败,但即使抛出异常,最终也会返回Success。我发现它有点误导,因为有时当异常发生并检查日志时,它表示自定义操作成功。这就是我添加行

的原因
        Return ActionResult.Failure

然而,现在它不再起作用了!每当我安装时,我发现我的CommitCA永远不会被执行。注意:不是InstallCA,它是我唯一的代码修改,而是CommitCA,它实际上是在InstallCA之前安排的。当我说“永远不会执行”时,我的意思是我找不到任何我放在函数调用中的日志条目,而MMSIBREAK环境变量甚至根本不起作用(窗口通知我附加到rundll32进程永远不会弹出)。但是下面的InstallCA仍然会被执行。

如果我对该行Return ActionResult.Failure发表评论,那么一切都会再次发挥作用:我可以附加进入CommitCA并且InstallCA也会被调用。

我可能会误解自定义操作的返回结果。我不应该在这种情况下返回ActionResult.Failure吗?但实际上我也会在其他地方返回ActionResult.Failure。实际上在CommitCA函数本身中,我使用了相同的结构:在ActionResult.Failure块中返回Catch。所以有人能告诉我我做错了什么吗?

1 个答案:

答案 0 :(得分:4)

我首先阅读:

Installation Phases and In-Script Execution Options for Custom Actions in Windows Installer

有关提交CA的一些事项:

提交自定义操作通常并不意味着更改计算机的状态。它们用于清理回滚临时数据。

如果禁用回滚(通过属性或系统策略),则不会执行提交自定义操作,因为这意味着没有要清理的回滚数据。

有时,提交自定义操作用于在无法执行回滚时配置计算机,并且您希望将更改推迟到尽可能晚。 (更改用户密码,将DLL安装到GAC)在这些方案中,成本核算应指示延迟的自定义操作执行工作,因为回滚/提交永远不会执行。

应在延迟自定义操作之前安排回滚自定义操作,并且应在延迟自定义操作之后安排提交操作。这样脚本生成阶段就可以正确创建脚本。

如果延迟阶段失败,脚本将向后移动,以便执行回滚。

如果所有延迟阶段都成功,则执行提交脚本。这意味着所有提交的CA必须在任何提交执行之前完成。