如何根据自定义操作中设置的 属性 安装功能?

How to install feature based on the property set in custom action?

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

的值
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 和 Execute 立即执行之前被调用。

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

我尝试评估条件: 流,STREAM=RED,STREAM="RED",< ![CDATA[STREAM=RED]]>

我运行不知道该怎么做,希望得到帮助。

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

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

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

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

  2. 作为最后的手段,您可以像我一样将条件添加到每个组件,但我们这样做只是出于非常具体的原因,希望您可以获得条件功能以配合上述建议!

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

来不及测试所有这些,但这里有一些信息。我明天再回来查看。从本质上讲,我认为问题在于您的自定义动作顺序。在计算成本之前尝试。

需要考虑的一些事项:

  • 自定义操作排序:您需要对自定义操作进行正确排序,并且需要在静默和交互安装模式下都出现.
    • 您是否尝试将设置 属性 自定义操作排序在 CostInitialize 之前?你说你在 InstallInitialize 之前设置它,但是在 CostInitialize 之前尝试它(你可能已经尝试过)。
    • 您是否记得在 InstallUISequenceInstallExecuteSequence 中插入此自定义操作?您需要在两个序列中插入,以防安装程序以静默模式运行。我相信在两个序列中 CostInitialize 之前。
  • Feature Level:通过feature level and INSTALLLEVEL操作特征只是进行特征控制的一种方法,您还可以设置通过命令行或使用自定义操作的功能。
    • 将功能级别设置为 0 应该会在设置的自定义对话框中隐藏该功能。
    • 将功能级别设置为高于安装程序的 INSTALLLEVEL 将从安装中删除select该功能。
    • 反之,将功能级别设置为低于或等于安装程序的 INSTALLLEVEL 将 select 安装该功能。
    • The conditional syntax allowed is quite flexible, and could provide the functionality you need outright - but I have never used them properly. Here is an example from the Installshield forum.
  • ADDLOCAL & REMOVE:您可以通过更改 [=16= 的值来操纵特征 selection ] 来自自定义操作的属性(技术上也称为重新安装和广告)- 这些属性也可以通过命令行设置。
  • Win32:您还可以使用 Win32 函数 MsiGetFeatureState and MsiSetFeatureState - 从 C++ 自定义操作 - 设置功能 select离子.

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


Cross-linking方便检索:

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

我想说明哪些有效,哪些无效:

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

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

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