【问题标题】:How to execute conditional custom action on install and modify only?如何仅在安装和修改时执行条件自定义操作?
【发布时间】:2019-02-21 12:59:43
【问题描述】:

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

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

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

【问题讨论】:

    标签: wix windows-installer custom-action


    【解决方案1】:

    InstallFinalize:你写信给 HKCU 还是 HKLM?在 InstallFinalize 之后排序的任何内容都不会在托管环境中运行提升,因此如果您尝试写入 HKLM(除非您将 ACL 更改为您写入的密钥 - 或者您从已经提升的 cmd.exe 中关闭 MSI - 不推荐,该软件包有缺陷)。

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

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

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

    修改:对于您的情况,Installshield 的人提供了一份备忘单,在他们的"MSI Condition Cheat Sheet" 中提出了以下条件:

    • Installed AND NOT REINSTALL AND NOT REMOVE~="ALL"
    • 上述条件应使自定义操作仅在修改操作中运行。如果您稍作更改,它应该仅适用于安装和修改:
    • NOT Installed OR ((Installed AND NOT REINSTALL) AND NOT REMOVE~="ALL")

    明天我将不得不对最后一个条件进行额外检查,但我只是发布此消息,以便您自己进行测试。我取出了 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 &amp; 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

    【讨论】:

    • 阿斯穆尔,感谢您的回复。这是HKLM。我设置了 NOT Installed OR ((Installed AND NOT REINSTALL) AND NOT REMOVE~="ALL") 条件,CA 在 install 中运行,但仅在我更改安装程序功能时才在 modify 中运行。如果我更改数据库或不更改任何内容,它就不会运行。即使用户在安装程序功能中没有任何更改,我也想在任何修改的情况下运行 CA。我也必须提供补丁。
    • NOT REMOVE~="ALL" 解决我的问题。它在除卸载之外的所有情况下运行。感谢您分享备忘单并再次感谢您的帮助。
    • 您是否在 UI 序列中运行此自定义操作? (我认为您在提到 InstallFinalize 时没有看到,但只是想验证一下,因为从外观上看,每个序列中的条件可能略有不同)。您使用的是什么 WiX 对话框集?寻找 UIRef 元素。我使用&lt;UIRef Id="WixUI_Mondo" /&gt;。在我的测试人员中,您在第一条评论中提到的条件使自定义操作仅在全新安装和修改时运行(即使没有任何功能修改),但我不怀疑您的结果 - 这就是为什么如果您不这样做我想要更多详细信息的原因不介意。
    • 哦,我假设您已将其附加到现有条件的特征条件&amp;BaseModel = 3 OR &amp;FeaturePostMaster = 3。我没看到。我认为这意味着您必须更改功能状态才能使条件为真,是的。尚未测试。
    • 条件很难调试。如果您需要更多调试,我有一些结构可以提供帮助。它涉及消息框和脚本以显示条件何时有效,但您可能已经拥有了。
    猜你喜欢
    • 2013-06-29
    • 1970-01-01
    • 1970-01-01
    • 2022-11-23
    • 1970-01-01
    • 2010-10-06
    • 1970-01-01
    • 2020-04-26
    • 2013-12-01
    相关资源
    最近更新 更多