WiX: CustomAction на основе результатов другого CustomAction

Я довольно новичок в WiX, так что, может быть, я спрашиваю что-то очень прямолинейное, но я не мог найти много помощи в поиске в Google.

Я хочу выполнить 2 пользовательских действия, скажем, ca1 и ca2, где выполнение ca2 зависит от результата ca1, что-то вроде ниже:

if ( ca1 == SUCCESS )
{
  Perform ca2
}

Таким образом, ca2 должен выполняться только в том случае, если мой ca1 возвращает успех (не терпит неудачу).

Какой самый простой способ сделать это в WiX?

4 ответа

Решение

Что вы описываете по умолчанию. Если пользовательское действие завершается неудачно, установка прерывается, и впоследствии могут выполняться только действия отката. Поэтому для того, чтобы ваш вопрос имел смысл, сначала вы должны игнорировать или иным образом маскировать сбои при первом пользовательском действии.

Во-вторых, единственный способ для одного действия узнать результат возврата другого, если он вызвал его, вызвав MsiDoAction (или некоторую его оболочку). Это приведет к размытию границ между вашими пользовательскими действиями, поэтому я предполагаю, что вы описываете не тот сценарий.

Это оставляет вам третий и последний путь: найти внешний канал связи. Для немедленных действий я бы предложил, чтобы ca1 устанавливал свойство в случае успеха (вызывал MsiSetProperty или оболочку, такую ​​как сеанс DTF [ property ]), а ca2 либо считывал ( MsiGetProperty / MsiEvaluateCondition), либо напрямую зависел от значения этого свойства. Для отложенных действий свойства не распространяются, поэтому вам придется определить какой-то другой канал. (Возможно, временный файл, путь которого будет выбран заранее, сработает.)

Но весь сценарий немного необычен для установщика Windows; Я бы порекомендовал избегать этого. Возможно, объедините ваши действия, чтобы любые сценарии сбоя можно было обработать "внутри", прежде чем возвращаться к последовательности. Или, возможно, специфика ваших действий может привести к более конкретным предложениям.

Вы никогда не должны вносить изменения в систему, используя немедленные пользовательские действия в режиме. Они никогда не будут работать должным образом, когда установка выполняется пользователем с ограниченными правами с повышенными правами (действия немедленного режима никогда не повышаются, они всегда подражают пользователю, поэтому все, что вы попытаетесь изменить, вызовет отказ в доступе). Кроме того, они могут не работать в режиме без вывода сообщений, в зависимости от последовательности (например, если вы пытаетесь вызвать их из графического интерфейса настройки).

Другим "внешним каналом связи" между настраиваемыми действиями, о котором говорит Майкл Урман, может быть раздел реестра в HKLM, который вы можете записать и затем прочитать.

Однако реальным решением было бы попробовать встроенную функцию межсетевого экрана WiX. Он надежно написан опытными MSI-экспертами и поддерживает правильный откат. Это значительно превосходит то, что каждый может сделать самостоятельно: http://wixtoolset.org/documentation/manual/v3/xsd/firewall/firewallexception.html

Из документации WiX здесь

    <InstallExecuteSequence>
         <Custom Action='FooAction1' After='InstallFiles'/>
         <Custom Action='FooAction2' After='FooAction1' Condition='FOOACTION1SUCCESS'/>
    </InstallExecuteSequence>

Сделайте так, чтобы ваш код в FooAction1 установил свойство MsiSetProperty('FOOACTION1SUCCESS', '1'). Теперь FooAction2 будет работать, только когда установлено свойство FOOACTION1SUCCESS. Но на самом деле ответ Майкла Урмана правильный. Вы должны обработать исключение все в пределах одного настраиваемого действия.

Сделайте, чтобы первое настраиваемое действие установило свойство. Затем выполняйте только 2-е настраиваемое действие, если это свойство существует или для него установлено ожидаемое значение.

Другие вопросы по тегам