Настраиваемые действия MSI во время удаления или отката

Мне трудно понять, как правильно устанавливать и удалять пользовательские действия и какова цель отката. У меня есть пользовательское действие под названием CreateFSRegistryLink это создает REG_LINK запись реестра (которая не может быть создана MSI / InstallShield непосредственно AFAIK). Я думаю, что по большей части это работает правильно, потому что, если ссылка уже есть, она просто возвращает ERROR_FUNCTION_NOT_CALLED, который MSI, кажется, обрабатывает изящно, продолжая остальную часть установки. Это гарантирует, что несколько экземпляров продукта могут быть установлены без ошибок (у нас есть несколько экземпляров продукта).

Проблема возникает во время удаления. CreateFSRegistryLink кажется, снова работает в режиме без отката. Из журнала MSI я вижу, что он работает так, как должен во время устанавливать и но это также работает во время деинсталляция:

Я проверяю режим с помощью:

if (!MsiGetMode(hInstall, MSIRUNMODE_ROLLBACK))

Когда условие выполняется, я записываю сообщение «CreateFSRegistryLink работает в режиме без отката». Когда оно ложно, я записываю сообщение: «CreateFSRegistryLink работает в режиме отката, поэтому был пропущен». Я никогда не видел, чтобы второе сообщение появлялось в журнале.

я имею CreateFSRegistryLink настроить выполнение In-Script «Отложенное выполнение в контексте системы». У меня также есть другое пользовательское действие DeleteFSRegistryLink настроить выполнение In-Script «Выполнение отката в системном контексте». Я вижу, что он пропускается во время установки, но не во время деинсталляции (я подозреваю, что он работает нормально во время деинсталляции, но не добавил ведения журнала, чтобы подтвердить это).

У меня также есть пользовательское действие CountOtherFSSystems это устанавливает FS_SystemCount на количество систем (экземпляров) помимо текущего экземпляра. Я поставил DeleteFSRegisryLink иметь условие бегать только тогда, когда FS_SystemCount<1 в последовательности Exec. Вот как я могу сказать, что он пропускается во время установки, потому что MSI сообщает, что условие не было выполнено, и так DeleteFSRegistryLink был пропущен Я ожидаю, что это поможет убедиться, что он работает только тогда, когда последний экземпляр удаляется. Я думаю, что это условие работает на основе вывода журнала, но я не знаю, как это получить DeleteFSRegistryLink настраиваемое действие для правильной работы во время удаления без CreateFSRegistryLink действие по переустановке ссылки. Последняя ссылка на DeleteFSRegistryLink Я вижу в журнале это:

MSI (s) (08:CC) [09:42:23:708]: Executing op: CustomActionSchedule(Action=DeleteFSRegistryLink,ActionType=3329,Source=BinaryData,Target=DeleteFSRegistryLink,)

Я еще не добавил запись в журнал для этой функции, поэтому не знаю, запустилась ли она, но после завершения установки ссылка в реестре все еще там. Это не совсем удивительно, потому что сразу после этого я вижу, что CreateFSRegistryLink побежал снова:

MSI (s) (08:CC) [09:42:23:708]: Executing op: ActionStart(Name=CreateFSRegistryLink,,)
Action 9:42:23: CreateFSRegistryLink.
MSI (s) (08:CC) [09:42:23:708]: Executing op: CustomActionSchedule(Action=CreateFSRegistryLink,ActionType=3073,Source=BinaryData,Target=CreateFSRegistryLink,)
MSI (s) (08:0C) [09:42:23:739]: Invoking remote custom action. DLL: C:\windows\Installer\MSI37E1.tmp, Entrypoint: CreateFSRegistryLink
MSI (s) (08:70) [09:42:23:739]: Generating random cookie.
MSI (s) (08:70) [09:42:23:739]: Created Custom Action Server with PID 7640 (0x1DD8).
MSI (s) (08:18) [09:42:23:786]: Running as a service.
MSI (s) (08:18) [09:42:23:786]: Hello, I'm your 32bit Elevated custom action server.
CreateFSRegistryLink is running in non-rollback mode.

Я следовал правилу в https://msdn.microsoft.com/en-us/library/aa371369(v=vs.85).aspx «Настраиваемое действие отката должно всегда предшествовать отложенному настраиваемому действию, которое оно откатывает в последовательности действий», что для меня все еще не имеет смысла видеть этот вывод и результаты журнала. Я думаю, что мне здесь не хватает нескольких ключевых моментов.

0

Решение

Это в моем списке «необходимого чтения» для MSI и хорошее место для начала:

Этапы установки и параметры выполнения в сценарии для настраиваемых действий в установщике Windows

Идея состоит в том, что каждое изменение, сделанное MSI, должно быть транзакционным. Вы сможете откатить изменение состояния при сбое во время установки, обновления, восстановления или удаления.

Иногда вы сталкиваетесь с API, где это невозможно. Примером может быть удаление учетной записи пользователя или взаимодействие со старым API метабазы ​​IIS. Если API не поддерживает возможность .commit () .rollback (), вам нужно просто внести изменения в выполнение фазы фиксации. Учитывая, что этап фиксации можно отключить, отключив откат, вы должны сделать это на ранней стадии в этих сценариях.

Прочитайте официальный документ несколько раз, немного переварите его, а затем ответьте на любые другие вопросы, которые у вас остались.

Редактировать: Вот как я настроил свои собственные действия:

  1. CountOtherFSSystems работает с немедленным выполнением после InstallInitialize при любых обстоятельствах, чтобы установить для FS_SystemCount количество других установленных экземпляров.
  2. RollbackFSRegistryLink запускается с выполнением отката в системном контексте после CountOtherFSSystems при условии FS_SystemCount<1 And $FSRegistry = 3 (Когда компонент FSRegistry устанавливался локально). Вызывает функцию удаления ссылки в реестре.
  3. CreateFSRegistryLink запускается с отложенным выполнением в системном контексте после RollbackFSRegistryLink при условии $FSRegistry=3, Вызывает функцию для создания ссылки в реестре.
  4. Выполняется куча других функций в последовательности, и затем мы получаем стандартное действие WriteRegistryValues.
  5. RollbackDeleteFSRegistryLink запускается с выполнением отката в системном контексте после WriteRegistryValues ​​при условии $FSRegistry<>3 (когда компонент FSRegistry был удален, но откат должен вернуть его обратно). Вызывает функцию для создания ссылки в реестре.
  6. DeleteFSRegistryLink запускается с отложенным выполнением в системном контексте после RollbackDeleteFSRegistryLink при условии FS_SystemCount<1 AND $FSRegistry <> 3, Вызывает функцию удаления ссылки в реестре.
  7. TestError запускается с отложенным выполнением в системном контексте после DeleteFSRegistryLink. Он вызывает тестовую функцию, которая просто возвращает условие ошибки, если пользователь говорит, что все в порядке (через MSIProcessMessage), чтобы ввести ошибку для целей тестирования здесь. (Эта функция будет отключена для производственных сборок.)

Я проверил следующие случаи:

  • Ошибка при установке первого экземпляра — записи реестра или ссылки не создаются.
  • Ошибка при установке второго экземпляра — остаются только записи реестра первого экземпляра, и ссылка также сохраняется.
  • Ошибка при удалении второго экземпляра — оба экземпляра и ссылка остаются в реестре.
  • Ошибка при деинсталляции последнего оставшегося экземпляра. Пока ошибка отображается (до отката), я вижу, что все записи реестра и ссылки пропали, и после продолжения я вижу, что откат восстановил записи реестра и ссылку ,
  • Успешная деинсталляция второго экземпляра — ссылки на реестр и записи первого экземпляра остаются.
  • Успешная деинсталляция последнего оставшегося экземпляра — ссылка и все записи реестра будут удалены.

Пожалуйста, прокомментируйте, если вы видите что-то, что я пропустил здесь. Это кажется довольно полным для меня.

1

Другие решения

Чтобы добавить мои 2 цента: Кажется, проблема связана с условиями пользовательских действий. Что касается вашего звонка в MsiGetMode, чтобы увидеть, если это откат, зачем? Вы настраиваете пользовательское действие отката перед вашим фактическим отложенным ЦС, и по определению оно будет вызываться только в том случае, если было вызвано исходное пользовательское действие, и оно определено как ЦС отката и не требует никаких условий. Может случиться так, что ваш CA для удаления может быть таким же, как и CA для отката, но, строго говоря, CA для удаления может предположить, что его аналогичный CA для установки работал правильно, если он правильно закодирован и сбой приводит к сбою установки, тогда как для CA отката может потребоваться предположить, что установочный ЦС, возможно, работал только частично и должен проверить состояние системы.

Если при удалении вызывается CreateRegistryFSLink, значит, ваше условие в этом CA неверно.

Если ваш код что-то сделал или не сделал, то вам остается вспомнить, что он сделал, и откат CA отменяет это.

Остальное, похоже, касается условий ваших пользовательских действий. Если вы хотите, чтобы он вызывался только при удалении продукта, используйте REMOVE = «ALL». Если у вас есть CA, связанные конкретно с компонентом или удалением компонента, то (как говорит Крис) используйте компонент или условие компонента, они здесь:

https://msdn.microsoft.com/en-us/library/aa368012(v=vs.85).aspx

Если вы хотите, чтобы удаленный ЦС запускался до тех пор, пока продукт не обновляется, тогда будут работать REMOVE = «ALL» и NOT UPGRADINGPRODUCTCODE.

Поэтому, если вы все еще застряли, это может помочь опубликовать ваши определения CA, в частности, условия и типы.

1

По вопросам рекламы [email protected]