如何根据自定义操作中设置的 属性 安装功能?
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>
如果还是不行,我会尝试以下方法:
将具有默认值的 STREAM 属性 添加到您的 WiX。然后使用该默认值对其进行测试,以查看将默认值设置为开头是否可以使其正常工作。这可能意味着您需要尽快设置 属性,可能需要关闭 UI 事件。 <Property Id="STREAM" Value="RED"/>
作为最后的手段,您可以像我一样将条件添加到每个组件,但我们这样做只是出于非常具体的原因,希望您可以获得条件功能以配合上述建议!
希望以上内容能解决您的问题,或者至少能引导您找到答案!
来不及测试所有这些,但这里有一些信息。我明天再回来查看。从本质上讲,我认为问题在于您的自定义动作顺序。在计算成本之前尝试。
需要考虑的一些事项:
- 自定义操作排序:您需要对自定义操作进行正确排序,并且需要在静默和交互安装模式下都出现.
- 您是否尝试将设置 属性 自定义操作排序在
CostInitialize
之前?你说你在 InstallInitialize 之前设置它,但是在 CostInitialize 之前尝试它(你可能已经尝试过)。
- 您是否记得在
InstallUISequence
和 InstallExecuteSequence
中插入此自定义操作?您需要在两个序列中插入,以防安装程序以静默模式运行。我相信在两个序列中 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方便检索:
感谢您的回复。最后,您的建议组合对我有所帮助。
我想说明哪些有效,哪些无效:
- 不需要将 属性 添加到具有默认值的 WiX(以及添加此 属性 Secure='yes' 的 属性)
- 在 CostInitialize 之前调用自定义操作本身并没有解决问题,但我相信这是解决问题的因素之一。
- 条件语法已更正:
a) 将条件放入 CDATA 并按照建议将引号添加到 属性 的值:<Condition><![CDATA[STREAM="RED"]]></Condition>
b) 反转条件级别,使功能具有条件级别 1,条件具有级别 0。这意味着功能始终安装,除非条件表达式为 false。
关于自定义动作的正确顺序,custom action type 51的描述包含了决定性的提示:
“要影响在组件或功能的条件中使用的 属性,自定义操作必须在操作序列中出现在 CostFinalize 操作之前。”
我正在尝试根据应在自定义操作中设置的值从两个功能中安装一个。
首先,我设置 属性:
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>
如果还是不行,我会尝试以下方法:
将具有默认值的 STREAM 属性 添加到您的 WiX。然后使用该默认值对其进行测试,以查看将默认值设置为开头是否可以使其正常工作。这可能意味着您需要尽快设置 属性,可能需要关闭 UI 事件。
<Property Id="STREAM" Value="RED"/>
作为最后的手段,您可以像我一样将条件添加到每个组件,但我们这样做只是出于非常具体的原因,希望您可以获得条件功能以配合上述建议!
希望以上内容能解决您的问题,或者至少能引导您找到答案!
来不及测试所有这些,但这里有一些信息。我明天再回来查看。从本质上讲,我认为问题在于您的自定义动作顺序。在计算成本之前尝试。
需要考虑的一些事项:
- 自定义操作排序:您需要对自定义操作进行正确排序,并且需要在静默和交互安装模式下都出现.
- 您是否尝试将设置 属性 自定义操作排序在
CostInitialize
之前?你说你在 InstallInitialize 之前设置它,但是在 CostInitialize 之前尝试它(你可能已经尝试过)。 - 您是否记得在
InstallUISequence
和InstallExecuteSequence
中插入此自定义操作?您需要在两个序列中插入,以防安装程序以静默模式运行。我相信在两个序列中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方便检索:
感谢您的回复。最后,您的建议组合对我有所帮助。
我想说明哪些有效,哪些无效:
- 不需要将 属性 添加到具有默认值的 WiX(以及添加此 属性 Secure='yes' 的 属性)
- 在 CostInitialize 之前调用自定义操作本身并没有解决问题,但我相信这是解决问题的因素之一。
- 条件语法已更正:
a) 将条件放入 CDATA 并按照建议将引号添加到 属性 的值:<Condition><![CDATA[STREAM="RED"]]></Condition>
b) 反转条件级别,使功能具有条件级别 1,条件具有级别 0。这意味着功能始终安装,除非条件表达式为 false。
关于自定义动作的正确顺序,custom action type 51的描述包含了决定性的提示:
“要影响在组件或功能的条件中使用的 属性,自定义操作必须在操作序列中出现在 CostFinalize 操作之前。”