Часть нашего приложения включает в себя регистрацию плагина для стороннего продукта. Во время работы сторонней службы наша DLL загружена, поэтому файлы на диске заблокированы.
Поэтому, когда мы удаляем наш продукт, нам нужно начать с остановки сторонней службы, а затем перезапустить ее, когда мы закончим удаление. (Мы также делаем то же самое для остановки / перезапуска во время установки, потому что, если это обновление, тогда существующие файлы снова блокируются.)
WiX имеет команду, которая обрабатывает счастливый путь, без проблем:
<ServiceControl Id="SomeUniqueId" Name="NameOfTheirService"
Start="both" Stop="both"/>
Т.е., остановите службу в начале как установки, так и удаления, и перезапустите ее в конце установки и удаления. Пока все хорошо.
Проблема возникает, если конечный пользователь сначала удаляет стороннее приложение, а затем пытается удалить наше приложение. Наше приложение не будет работать со сторонней службой, но если пользователь хочет удалить их обоих, ничто не заставит их сделать это в определенном порядке. Однако если сторонняя служба больше не установлена, тогда наш деинсталлятор:
- Пытается остановить стороннюю службу, происходит сбой, потому что служба больше не существует, решает, что сбой не важен, и продолжает работу.
- Удаляет наш продукт.
- Пытается перезапустить стороннюю службу, происходит сбой, потому что служба больше не существует, решает эту ошибку важно и выдает диалоговое окно с сообщением об ошибке «Служба NameOfTheirService (NameOfTheirService) начать. Убедитесь, что у вас достаточно прав для запуска системных служб. " (Повторить / отменить)
- Если пользователь нажимает «Повторить», перейдите к 3.
- Если пользователь нажимает кнопку Отмена, откат и удаление.
Другими словами, обработка ошибок WiX неверна. Остановка службы должна быть отказоустойчивой, и это так. Запуск службы после установки может быть непереносимым; это нормально: не удастся установить, если служба не запустится. Но запуск службы после uninstall должен быть отказоустойчивым, а это не так.
Как перезапустить службу после удаления, не прерывая удаление, если эта служба больше не существует?