Как установить функцию на основе свойства, заданного в настраиваемом действии?
Я пытаюсь установить одну из двух функций в зависимости от значения, которое должно быть установлено внутри настраиваемого действия.
Во-первых, я устанавливаю значение свойства:
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",
У меня заканчиваются идеи, что делать, и буду признателен за помощь.
3 ответа
Спасибо за ваши ответы. В конце концов, сочетание ваших предложений помогло мне.
Я хочу заявить, что сделал, а что не сработало:
- Добавление свойства в WiX со значением по умолчанию не было необходимым (также добавление свойства этого свойства Secure='yes')
- Вызов пользовательского действия до CostInitialize не решил проблему сам по себе, но я считаю, что это был один из факторов, который решил проблему.
- Условный синтаксис был исправлен:
а) Помещение условия внутри CDATA и добавление кавычек к значению свойства, как предложено:<Condition><![CDATA[STREAM="RED"]]></Condition>
b) Сторнирование уровней условий, чтобы функция имела уровень условий 1, а условие - уровень 0. Это означает, что функция всегда установлена, если выражение условия не является ложным.
Слишком поздно, чтобы проверить все это, но здесь идет с некоторой информацией. Я проверю завтра. По сути, я думаю, что проблема заключается в последовательности пользовательских действий. Попробуйте до калькуляции.
Некоторые вещи для рассмотрения:
- Последовательность настраиваемых действий: вам нужно правильно упорядочить настраиваемое действие, и оно должно присутствовать как в режиме без вывода сообщений, так и в интерактивном режиме.
- Вы пытались упорядочить заданное свойство настраиваемого действия перед
CostInitialize
? Вы заявляете, что установили его до InstallInitialize, но вместо этого попробуйте его до CostInitialize (возможно, вы пытались). - И вы не забыли вставить это пользовательское действие в
InstallUISequence
так же хорошо какInstallExecuteSequence
? Вам нужно вставить обе последовательности в случае, если установка работает в беззвучном режиме. ДоCostInitialize
в обеих последовательностях я верю.
- Вы пытались упорядочить заданное свойство настраиваемого действия перед
- Уровень функций: управление функциями через уровень функций и INSTALLLEVEL - это только один из способов управления функциями, вы также можете устанавливать функции через командную строку или с помощью пользовательских действий.
- Установка уровня функции на 0 должна скрывать функцию от просмотра в пользовательском диалоговом окне настройки.
- Установка уровня функции выше, чем INSTALLLEVEL установки, отменяет выбор этой функции при установке.
- И наоборот, установка уровня функции ниже или равного INSTALLLEVEL установки выберет функцию для установки.
- Допустимый условный синтаксис достаточно гибок и может обеспечить необходимую вам функциональность, но я никогда не использовал их должным образом. Вот пример с форума Installshield.
- ADDLOCAL & REMOVE: вы можете манипулировать выбором объектов, изменяя значения свойств ADDLOCAL и REMOVE из настраиваемого действия (технически также REINSTALL и ADVERTISE) - и эти свойства также можно установить через командную строку.
- Win32: вы также можете использовать функции Win32 MsiGetFeatureState и MsiSetFeatureState - из пользовательского действия C++ - для установки выбора функции.
Честно говоря, это немного безумие. Также имейте в виду, что существуют состояния действия функции (что будет с функцией) и состояния установки функции (в каком она состоянии). Документация по функциям Win32 должна объяснить.
Перекрестные ссылки для удобного поиска:
Я сделал что-то подобное, но мы закончили тем, что контролировали это на уровне компонентов (добавив условие к <Component/>
элементы вместо элемента элемента, использующего преобразование во время жары). Но наше условие использует CDATA, а также использует двойные кавычки для значения, которое вы не перечислили в том, что вы пробовали. Итак, сначала я попробую следующие условия в ваших функциях:
<Condition><![CDATA[STREAM="RED"]]></Condition>
<Condition><![CDATA[STREAM="BLUE"]]></Condition>
Если это все еще не работает, я бы попробовал следующее:
Добавьте свойство STREAM со значением по умолчанию к вашему WiX. Затем протестируйте его с этим значением по умолчанию, чтобы увидеть, заставляет ли его работать значение по умолчанию. Это может означать, что вам нужно установить свойство раньше, возможно, отключив событие пользовательского интерфейса.
<Property Id="STREAM" Value="RED"/>
В качестве последнего средства вы можете добавить условия к каждому компоненту, как я, но мы сделали это только по очень конкретным причинам, надеюсь, вы сможете использовать условную функцию для работы с приведенными выше предложениями!
Я надеюсь, что вышеизложенное решит вашу проблему или, по крайней мере, приведет вас к ответу!
Что касается правильного порядка настраиваемых действий, описание типа 51 настраиваемого действия содержит решающий намек:
"Чтобы повлиять на свойство, используемое в условии для компонента или функции, настраиваемое действие должно предшествовать действию CostFinalize в последовательности действий".