如何仅在安装和修改时执行条件自定义操作?

How to execute conditional custom action on install and modify only?

我有一个运行良好的安装程序。我只想 运行 仅在安装和修改中自定义操作。这是我的自定义操作:

<Custom Action="UpdateAPMDBAPasswordAndStoreInRegistry" After="InstallFinalize"><![CDATA[&BaseModel = 3 OR &FeaturePostMaster = 3]]></Custom>

修改安装程序时 运行 不会执行上述自定义操作。它 运行 仅在安装安装程序时出现。谷歌搜索后,我这样做了,但它也不起作用:

<Custom Action="UpdateAPMDBAPasswordAndStoreInRegistry" After="InstallFinalize"><![CDATA[(&BaseModel = 3 OR &FeaturePostMaster = 3) AND (NOT Installed OR MaintenanceMode="Modify")]]></Custom>

它也 运行 仅在安装模式下。我做错了什么?

InstallFinalize:你写到HKCU还是HKLM?在 InstallFinalize 之后排序的任何内容都不会在托管环境中 运行 提升,因此如果您尝试写入 [=14 则在安装过程中会失败=](除非您更改写入密钥的 ACL - 或者您从已经提升的 cmd.exe 中启动 MSI - 不推荐,包有缺陷)。

MaintenanceMode:该条件看起来像是特定于 Installshield 的:NOT Installed OR MaintenanceMode="Modify"。我认为 Installshield 本身以专有方式设置 MaintenanceMode 属性。因此它在 WiX 中根本不可用。

测试条件:条件可能很难测试,您需要在许多安装模式下进行实际测试(installuninstallrepairmodifypatchmajor upgradeself-repairetc...) 以确保它们适合您的特定情况并按预期工作。人们对调节感到惊讶的典型场景是 重大升级 - 卸载旧版本并安装新版本 - 根据我的经验,它往往会揭示意想不到的条件问题。通常是由于复杂的顺序问题以及在此类升级过程中旧设置的卸载顺序和新设置的安装顺序 运行。因此,在主要升级过程中,条件错误的自定义操作可能 运行 多次,并造成真正的混乱。请阅读此答案以获取更多信息:Run Wix Custom action only during uninstall and not during Major upgrade and this short version.

测试提示:要实现快速重大升级,您需要更改产品代码并提高前 3 位数字之一的版本。您需要在其中包含 MajorUpgrade 元素。您可以将产品代码设置为 * 以将其设置为自动生成(我更喜欢手动更改)。编译一个 MSI,用 "_Version1" 后缀,然后执行提到的更新并编译 "_Version2"。 运行升级顺序。您还应该通过更改源路径指向版本 2 的更新文件,但您可以在没有它的情况下滚动以测试条件。

修改:对于你的情况,Installshield guys suggesting the following condition in their "MSI Condition Cheat Sheet"有一个秘籍sheet:

  • Installed AND NOT REINSTALL AND NOT REMOVE~="ALL"
  • 以上条件应仅在修改操作中启用自定义操作 运行。如果你稍微改变一下它应该只适用于安装和修改:
  • NOT Installed OR ((Installed AND NOT REINSTALL) AND NOT REMOVE~="ALL")

明天我将不得不 运行 对最后一个条件进行额外检查,但我只是 post 这样你就可以自己测试了。我去掉了 PATCH,但也许我应该把它加回去以涵盖主要的升级补丁。你会提供补丁吗?


轻型条件测试的快速模型:

The VBScript:

注意! 确保 VBScript 文件在 UTF8ANSI 中。 Unicode 将不起作用。也许在记事本而不是 Visual Studio 中创建它。我在将 VBScript 文件创建为 WiX 文本文件时遇到了问题,然后将其重命名为 *.vbs 格式。不要那样做。

MsgBox "I run, therefore I am conditioned and sequenced"

WiX Markup, Custom Action:

<Binary Id='SayHelloMsgBox.vbs' SourceFile='SayHelloMsgBox.vbs' />
<CustomAction Id='SayHelloMsgBox.vbs' VBScriptCall='' BinaryKey='SayHelloMsgBox.vbs' Execute='immediate' Return='ignore' />

WiX Markup, Sequencing & Conditioning:

<InstallExecuteSequence>
   <Custom Action='SayHelloMsgBox.vbs' After='InstallInitialize'>NOT Installed OR ((Installed AND NOT REINSTALL) AND NOT REMOVE~="ALL")</Custom>
</InstallExecuteSequence>

写入日志:您可以按照本文所述从 VBScript 写入 MSI 日志:MSI Tip: Writing to the Log File from a Custom Action


更新: 条件调试可以去掉单独的VBScript文件using this approach.