【问题标题】:How to install feature based on the property set in custom action?如何根据自定义操作中设置的属性安装功能?
【发布时间】:2018-09-04 15:47:00
【问题描述】:

我正在尝试根据应在自定义操作中设置的值安装两个功能中的一个。
首先,我设置一个属性的值:

UINT __stdcall ConfigurationCheckAction(MSIHANDLE hInstall)
{
    HRESULT hr = S_OK;
    UINT er = ERROR_INSTALL_FAILURE;

    hr = WcaInitialize(hInstall, "ConfigurationCheckAction"); 
    if (condition) {
         MsiSetProperty( hInstall, TEXT("STREAM"), TEXT("RED") );
    }
    else {
         MsiSetProperty( hInstall, TEXT("STREAM"), TEXT("BLUE") );
    } 
    return WcaFinalize(er);
}

其次,我为每两个特征设定两个条件:

<Feature Id='Complete' Level='1'>
     <Feature Id="Red" ConfigurableDirectory="TARGETDIR" Title="F1" Level="0">
     <Condition Level="1">STREAM</Condition>
     </Feature>
     <Feature Id="Blue" ConfigurableDirectory="TARGETDIR" Title="F2" Level="0">
     <Condition Level="1">NOT STREAM</Condition>
     </Feature>
</Feature>

请注意,我之前没有在 wxs 文件中定义属性,因为我想从自定义操作中设置它。

我的自定义操作在 InstallInitialize 和立即执行之前被调用。

从安装日志中,我确认该属性已设置。 但是,我的条件安装不起作用,因为条件中的内容似乎总是被评估为假。

我尝试评估条件: STREAM,STREAM=RED,STREAM="RED",

我想不出该怎么做,希望能得到帮助。

【问题讨论】:

  • 在 wxs 中定义你想要使用的属性(它不需要值)并确保你设置了Secure='yes'。您可能必须更新您的条件,但这应该允许该属性的新值传递到安装的提升部分。

标签: c++ wix windows-installer custom-action


【解决方案1】:

关于自定义操作的正确顺序,custom action type 51 的描述包含决定性提示:

“要影响组件或功能条件中使用的属性,自定义操作必须在操作序列中的 CostFinalize 操作之前。”

【讨论】:

    【解决方案2】:

    测试所有这些为时已晚,但这里提供了一些信息。我明天再回来看看。本质上,我认为问题在于您的自定义操作顺序。在成本核算之前尝试。

    需要考虑的一些事项:

    • 自定义操作排序:您需要对自定义操作进行排序,并且它需要以静默和交互式安装模式出现。
      • 您是否尝试在CostInitialize 之前对设置属性自定义操作进行排序?您声明您在 InstallInitialize 之前设置了它,但在 CostInitialize 之前尝试了它(您可能已经尝试过)。
      • 您还记得在InstallUISequenceInstallExecuteSequence 中插入此自定义操作吗?您需要在两个序列中插入,以防安装程序以静默模式运行。我相信在两个序列中都在 CostInitialize 之前。
    • 功能级别:通过feature levelINSTALLLEVEL 操作功能只是进行功能控制的一种方式,您也可以通过命令行或使用自定义设置功能行动。
      • 将功能级别设置为 0 应该会在设置的自定义对话框中隐藏该功能。
      • 将功能级别设置为高于安装程序的 INSTALLLEVEL 将从安装中取消选择该功能。
      • 反之,将功能级别设置为低于或等于安装程序的 INSTALLLEVEL 将选择要安装的功能。
      • The conditional syntax allowed 非常灵活,可以完全提供您需要的功能 - 但我从未正确使用过它们。 Here is an example from the Installshield forum
    • 添加和删除:您可以通过更改自定义操作中的 ADDLOCALREMOVE 属性的值来操作功能选择(技术上也可以重新安装和广告) -并且这些属性也可以通过命令行设置。
    • Win32:您还可以使用 Win32 函数 MsiGetFeatureStateMsiSetFeatureState(来自 C++ 自定义操作)来设置功能选择。

    坦率地说,整件事有点疯狂。另外请记住,有功能操作状态(功能将发生什么)和功能安装状态(它处于什么状态)。 Win32函数文档应该有说明。


    交叉链接方便检索

    【讨论】:

      【解决方案3】:

      感谢您的回复。最后,您的建议对我有所帮助。

      我想说明什么有效,什么无效:

      1. 无需使用默认值向 WiX 添加属性(以及添加此属性 Secure='yes' 的属性)
      2. 在 CostInitialize 之前调用自定义操作本身并不能解决问题,但我认为这是解决问题的因素之一。
      3. 条件语法已通过以下方式更正:
        a) 将条件放入 CDATA 中,并按照建议为属性值添加引号:&lt;Condition&gt;&lt;![CDATA[STREAM="RED"]]&gt;&lt;/Condition&gt;
        b) 反转条件级别,使功能具有条件级别 1,条件具有级别 0。这意味着始终安装该功能,除非条件表达式为假。

      【讨论】:

        【解决方案4】:

        我做过类似的事情,但我们最终在组件级别控制它(将条件添加到 &lt;Component/&gt; 元素,而不是在加热期间使用变换的特征元素)。但是我们的条件使用 CDATA 同时还使用双引号作为值,您没有在您尝试过的内容中列出。所以首先我会在你的功能中尝试以下条件:

        <Condition><![CDATA[STREAM="RED"]]></Condition>
        <Condition><![CDATA[STREAM="BLUE"]]></Condition>
        

        如果还是不行,我会尝试以下方法:

        1. 将具有默认值的 STREAM 属性添加到您的 WiX。然后使用该默认值对其进行测试,以查看是否将默认值设置为开头使其工作。这可能意味着您需要尽快设置属性,可能是关闭 UI 事件。 &lt;Property Id="STREAM" Value="RED"/&gt;

        2. 作为最后的手段,您可以像我一样为每个组件添加条件,但我们这样做只是出于非常特定的原因,希望您可以让条件功能与上述建议一起使用!

        我希望以上内容可以解决您的问题,或者至少可以引导您找到答案!

        【讨论】:

          猜你喜欢
          • 2023-02-24
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多