Wix stop service при деинсталляции / обновлении: предотвращение "перезапуска всплывающих окон" (ситуация с использованием файла)
У меня проблема в том, что при удалении (или обновлении) Restart Manager жалуется на файл в ситуации использования и поэтому принудительно перезагружается:
RESTART MANAGER: Detected that application with id 7000, friendly name 'javaw.exe', of type RmCritical and status 1 holds file[s] in use.
RESTART MANAGER: Did detect that a critical application holds file[s] in use, so a reboot will be necessary.
Сервис, на который жалуется RESTART MANAGER, это сервис на базе Java. Служба (здесь она называется myservice.exe) рекурсивно запускает дочерние процессы java:
myservice.exe --run
↳ javaw.exe - некоторые Аргументы
↳ someother.exe - некоторые Аргументы
↳ javaw.exe - некоторые другие аргументы
Фрагмент wix для определения сервиса:
<DirectoryRef Id="BINDIR">
<Component Id="myservice.exe" Guid="PUT-GUID-HERE">
<File Id="myservice.exe" KeyPath="yes" Vital="yes"
Source="SourceDir\bin\myservice.exe"/>
<ServiceInstall Id="MyService" Type="ownProcess"
Vital="yes" Name="MyService" DisplayName="My Service"
Description="My Service" Start="auto" Account=".\LocalSystem"
ErrorControl="normal" Interactive="no" Arguments="--run"/>
<ServiceControl Id="MyService" Name="MyService" Wait="yes" Remove="uninstall" Stop="uninstall" Start="install"/>
</Component>
</DirectoryRef>
Теперь интересная часть:
- Служба может быть запущена при установке
при удалении:
- если не работает, он будет удален
- если работает, и просто согласен сделать перезагрузку
- это действительно останавливается в течение 2-3 секунд (я думаю, по действию StopServices)
- и успешно удален (с помощью действия RemoveServices)
Записи в таблицах Service * мне пока кажутся хорошими.
ServiceControl-Table:
ServiceControl Name Event Arguments Wait Component_
MyService MyService 161 1 myservice.exe
ServiceInstall-Table:
ServiceInstall Name DisplayName ServiceType StartType ErrorControl LoadOrderGroup Dependencies StartName Password Arguments Component_ Description
MyService MyService My Service 16 2 32769 .\LocalSystem --run myservice.exe My Service
Итак, чтобы сломать все: кажется, что Restart Manager не распознает, что Java-процессы являются дочерними процессами и будут остановлены действием StopServices.
Я обнаружил некоторые похожие проблемы здесь: https://www.mail-archive.com/wix-users@lists.sourceforge.net/msg57924.html
Проблема с установщиком Wix: почему RestartManager помечает Service как RMCritical, а не RMService
Заранее спасибо за любую помощь, чтобы решить эту проблему!
2 ответа
У вас есть несколько вариантов решения этой проблемы:
-Отключить "Менеджер перезапуска", используя MSIRESTARTMANAGERCONTROL= "Отключить" в таблице свойств. Это приведет к старому диалоговому окну "FilesInUse". В вашем случае диалоговое окно FilesinUse также может не отображаться (поскольку службы не имеют связанного с ними окна). В диалоговом окне FilesinUse не отображаются процессы, с которыми не связано связанное с ними окно. Таким образом, в вашем случае отключение менеджера перезапуска может не отображать никаких диалогов (ни FilesInUse, ни RestartManager).
Однако это также может означать, что может потребоваться перезагрузка, не обязательно из-за ваших служб, но из-за какого-то другого процесса, который может удерживать ваши файлы в использовании. Если вы думаете, что не может быть никакого другого процесса, кроме ваших собственных сервисов, содержащих файлы, тогда продолжайте и следуйте этому подходу. Если вы считаете, что могут быть и другие процессы, кроме ваших служб, содержащих файлы, то лучше включить "Restart Manager". Отсутствие "менеджера перезапуска" также приведет к одной из вещей:
-Отобразите диалоговое окно Legacy FilesInUse с просьбой завершить процессы, перечисленные в этом диалоговом окне. Это может привести к тому, что вам придется отключить эти процессы с помощью специального действия.
Оба диалоговых окна "RestartManager" и "FilesInUse" отображаются стандартным действием "InstallValidate". Если вы хотите отключить оба эти диалоговых окна, убедитесь, что ваше пользовательское действие запланировано до стандартного действия "InstallValidate". Здесь есть подвох. Планирование такого настраиваемого действия до InstallValidate должно быть немедленным настраиваемым действием (нельзя настраивать настраиваемые действия отложенного режима до "IntsallFinalize"). Таким образом, в случаях, когда вы не работаете от имени администратора (например, в сценариях с включенным контролем учетных записей), у вас могут не быть необходимых привилегий для закрытия приложений. Таким образом, перезагрузка может потребоваться.
-Вы также можете закрыть приложения, используя функцию CloseApplication() расширений утилит WiX. Оцените свой сценарий и сделайте то, что подходит именно вам.
Я думаю, что я могу опоздать на вечеринку, но вот решение. В блоге команды установщика объясняется, как менеджер перезапуска решает, открывать ли файлы в диалоговом окне. В частности (раздел "Взаимодействие установщика-перезапуска диспетчера Windows в деталях ", пункт 3.b.):
Если пакет создан так , что службы, обнаруженные RM, будут закрыты из-за создания таблиц Service *, тогда эти службы не будут отображаться в диалоговых окнах использования файлов.
(курсив мой). Полезно, но не сразу полезно, потому что такое, что на самом деле не разработано. Но так как мой сервис вызвал ту же проблему, что описана в ОП с
<ServiceControl Stop="uninstall" ... />
Я просто изменил значение на both
<ServiceControl Stop="both" ... />
который был, вероятно, единственной оставшейся вещью, которая могла сделать это "таким, что", и бум, фейерверк, магия:
MSI (s) (50:A0) [21:50:30:352]: RESTART MANAGER: Detected that application with id 6408, friendly name 'XXXX', service short name 'xxxx', of type RmService and status 1 holds file[s] in use.
MSI (s) (50:A0) [21:50:30:352]: RESTART MANAGER: Detected that the service xxxx will be stopped due to a service control action authored in the package before the files are updated. So, we will not attempt to stop this service using Restart Manager
Похоже, что оба флага msidbServiceControlEventStop (0x002) и msidbServiceControlEventUninstallStop (0x020) должны быть установлены в таблице ServiceControl, чтобы RM с радостью пришел к выводу, что служба будет остановлена до обновления файлов.
Оглядываясь назад, это имеет смысл. Поскольку часть удаления во время обновления выполняется с использованием старой кэшированной базы данных MSI, RM не просматривает ее, чтобы увидеть, что произойдет, когда соответствующий продукт будет удален. Строго говоря, может быть несколько продуктов, которые нужно удалить, и установщик нигде не требует, чтобы эти связанные продукты (найденные действием FindRelatedProducts, включая старую версию того же кода обновления) были фактически связаны со службой, которой они являются. контроллинг в текущем пакете. Поэтому он не заботится о действиях службы при удалении, как указано в текущем пакете (в любом случае это не относится к действию установки!). Для согласованности требуется простое и прямое доказательство того, что служба будет остановлена до того, как используемые файлы будут перезаписаны, собирая такие доказательства только из текущего пакета.
Поэтому вполне вероятно, что RM заботится о флаге msidbServiceControlEventStop (0x002) только во время установки.