WiX: Как немедленно перезапустить explorer.exe? - PullRequest
1 голос
/ 21 февраля 2020

Я новичок в деле упаковки программного обеспечения. Я использую cpack + Wix. Я пытался найти полезную информацию или хорошую документацию о util: RestartResource , но не смог найти ничего интересного в моем вопросе.

Проблема: Мне нужно установить ShellExtension, который нуждается в перезапуске explorer.exe после установки некоторых значений реестра. Из-за этого я использую команду (https://wixtoolset.org/documentation/manual/v3/xsd/util/restartresource.html):

<util:RestartResource ProcessName="explorer.exe"/>

Все почти работает, как и ожидалось. Explorer.exe будет завершен, как ожидается, но перезапуск explorer.exe будет запущен после того, как пользователь завершит установку. Это неприятно, потому что explorer.exe исчезает, пока пользователь не нажмет кнопку завершения установки. Я бы хотел прямой перезапуск проводника после установки значений реестра. Я знаю, что это должно быть возможно, потому что, если WiX сам запускает перезапуск explorer.exe, он будет выполнен немедленно и не будет ждать окончания установки. В чем подвох? Я уже пробовал CustomActions и помещаю util: RestartResource в другую позицию WiX-кода (я в отчаянии.).

[EDIT] Я анализирую логи установки. И я понял, что по умолчанию менеджер перезапуска вызывается в начале процесса и закрывается перед финальным диалогом. Если я добавлю ProcessName в RestartResource, он откроет другой менеджер перезапуска, который закрылся после последнего диалога. Необходимо выяснить, как вызывать RestartResource , как по умолчанию RestartResource.

[EDIT2] Я думаю, util: RestartResource содержит ошибки. В настоящий момент я сканирую код реализации WiX и документацию MSI, и обычно вы должны зарегистрировать все RestartResources до состояния «InstallValidate». И это именно то, что WiX пытается сделать в UtilExtension_Platform.wxi :

  <Fragment>
    <CustomAction Id="WixRegisterRestartResources$(var.Suffix)" BinaryKey="WixCA" DllEntry="WixRegisterRestartResources$(var.Suffix)" Execute="immediate" Return="check" SuppressModularization="yes" />

    <InstallExecuteSequence>
      <Custom Action="WixRegisterRestartResources$(var.Suffix)" Before="InstallValidate" Overridable="yes" />
    </InstallExecuteSequence>
  </Fragment>

Потому что после этого состояния MsiRestartManagerSessionKey будет прекращен. И WiX пытается использовать этот ключ в случае регистрации RestartResource . Но внутри журналов я вижу, что мой вызов util: RestartResource всегда будет выполняться после состояния «InstallValidate». И в журнале уже сказано, что MsiRestartManagerSessionKey был прерван раньше (после состояния «InstallValidate»). Это с моей точки зрения против политики MSI.

[EDIT3] Это не глючит. Я опубликую сообщение.

Ответы [ 2 ]

1 голос
/ 21 февраля 2020

Способ "перезапустить проводник" - перезагрузить систему. Для этого вы можете использовать элемент Forcereboot.

Предлагает пользователю перезагрузить систему во время установки. Специальные действия не имеют встроенного порядкового номера и поэтому должны отображаться относительно другого действия. Предлагаемый способ сделать это - использовать атрибут «До» или «После». InstallExecute и InstallExecuteAgain могут дополнительно появляться в любом месте между InstallInitialize и InstallFinalize.

Более подробную информацию можно найти здесь: https://wixtoolset.org/documentation/manual/v3/xsd/wix/forcereboot.html

В стороне: принудительное выполнение windows процесс, который вы не можете перезапустить, кажется опасным. Вероятно, он изначально не поддерживается с WiX, потому что вы, вероятно, не должны этого делать. :)

0 голосов
/ 28 февраля 2020

Невозможно сделать то, что я хочу, с помощью util: RestartResource . Потому что util: RestartResource записывает в базу данных установки, какой процесс необходимо перезапустить. (позиция util: RestartResource внутри файла xml не влияет на запланированное завершение работы и перезапуск)

Существует CustomAction, который вызывает WixRegisterRestartResources (часть WixUtilExtension.dll ) до состояния «InstallValidate» . Это именно то, что необходимо для регистрации процесса в RestartManager MSI с помощью MsiRestartManagerSessionKey . Процессы перезапуска будут извлечены из базы данных установки. RestartManager MSI завершает работу всех процессов после состояния InstallValidate . К сожалению, он перезапускает все процессы, когда процесс MSI полностью завершен, а не раньше. Это означает, что он всегда будет запускаться после нажатия пользователем кнопки Fini sh в FinalDialog. Это не изменится, потому что это logi c внутри рабочего процесса Установщика MSI.

Я попытался реализовать пользовательское действие, которое регистрирует себя в MsiRestartManagerSessionKey и пытается перезапустить все процессы до EndDialog, но RestartManager MSI отклоняет все виды этих запросов (своего рода ошибка сеанса). И это является частью дизайна MSI, поскольку установщик MSI удаляет свойство MsiRestartManagerSessionKey после состояния InstallValidate . Они не хотят, чтобы вы могли получить доступ к RestartManager после состояния InstallValidate .

В конце я реализовал свой собственный RestartManager с CustomAction в C ++ и позже, когда я реализовывал в C# код более чистый, я реализовал его в C#. Хорошее объяснение, как это может работать, вы найдете здесь: http://community.bartdesmet.net/blogs/bart/archive/2006/11/12/Exploring-Windows-Vista_2700_s-Restart-Manager-in-C_2300_.aspx

...