2011-03-16 2 views
2

Иногда, когда я удаляю установку (сделанную с помощью WIX), служба остается помеченной для удаления, и пользователь должен перезагрузить компьютер для установки снова. Как я могу проверить, что служба помечена для удаления, и сообщить пользователю перезагрузить компьютер перед другой установкой?Проверьте, отмечена ли служба для удаления

+0

Не уверен, что вы можете найти его из 'ServiceController':' ServiceController.GetServices() ', но стоит попробовать. –

ответ

3

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

Для обнаружения я предлагаю вам ознакомиться с CreateService и другими Service API. Например, вы получите ERROR_SERVICE_MARKED_FOR_DELETE при вызове CreateService, если служба помечена для удаления.

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

+1

Как вы можете определить, загружен ли сервисный апплет в mmc? – vkrzv

2

Вот сообщение, которое может вам помочь. Хотя исходный вопрос касается установки сервиса, ответ также касается удалений и статусов.

How to install a windows service programmatically in C#?

Вот статья, которая объясняет, почему вы можете получить «помеченные для удаления» сообщение в первую очередь и как получить вокруг него.

http://weblogs.asp.net/avnerk/archive/2007/09/05/windows-services-services-msc-and-the-quot-this-service-is-marked-for-deletion-quot-error.aspx

EDIT

комментария Пер Кристофер Художника, я обновляю этот ответ на намерение распространения передового опыта. Хотя получение сообщения «помечено для удаления» чаще всего было (по моему опыту) результатом того, что консоль services.msc, а не нереализованные ресурсы, запись пользовательского действия для перезагрузки - это не самый лучший способ.

Чтобы запланировать перезагрузку после обработки WiX, использовать WiX XML (объясняется, как с Wix # here) следующим образом:

<?xml version='1.0' encoding='windows-1252'?> 
<Wix xmlns='http://schemas.microsoft.com/wix/2006/wi'> 
    ... 
    <InstallExecuteSequence> 
     <ScheduleReboot After="InstallFinalize"/> 
    <InstallExecuteSequence> 
</Wix> 
+0

Было бы хорошо, если бы был объяснен -1. – bitxwise

+0

WiX использует установщик Windows, который поддерживает установку/удаление служб. Любая попытка написать пользовательские действия в установщике считается плохой практикой. См.: Http://robmensching.com/blog/posts/2007/8/17/Zataoca-Custom-actions-are-generally-an-admission-of-failure –

+0

Спасибо за объяснение. Я согласен со многими моментами, сделанными в сообщении в блоге, которое вы связали, однако я не совсем согласен с вашей интерпретацией сообщения. Не пытайтесь начать войну, но автор сообщения подчеркнул, что пользовательские действия GENERALLY обескуражены из-за перечисленных причин того, почему разработчики будут писать пользовательские действия. При этом OP, вероятно, должен использовать в теге через WiX XML вместо написания пользовательского действия для лучшей практики. Я обновлю ответ, чтобы отразить это. – bitxwise

0

Вы используете элемент/таблицу ServiceControl для остановки службы во время удаления? Если да, прекращается ли ваше обслуживание? Если нет, ознакомьтесь с тем, что происходит внутри вашего сервиса, чтобы убедиться, что он освобождает все его ресурсы и изящно отключается по запросу.

Вам не нужно писать какие-либо пользовательские действия для программного вызова API SCM. Установщик Windows должен иметь возможность справиться с этим для вас.

+0

Это не отвечает на вопрос. Некоторые службы просто не могут быть остановлены, например. когда служба принадлежит драйверу устройства, который нельзя безопасно выгружать. – Ilya

+0

Точка зрения, которую вы пропустили, заключается в том, что это не проблема с установщиком и просмотр кода службы. Если служба не может быть остановлена, не просите установщика ее остановить. –

+0

Целью вашего деинсталлятора является удаление службы. Деинсталлятор должен сначала остановить его, но если он не остановить, то он все равно должен удалить его (что будет означать его удаление при остановке системы). Если пользователь решил не перезапускаться в конце вашего деинсталлятора, а затем переустанавливается, он может столкнуться с проблемой, когда установщик попытается снова создать службу. – Ilya

1

Я не могу найти API способ сделать это (который не предполагает вызова либо CreateService или DeleteService, оба имеют нежелательные побочные эффекты), но HKLM\SYSTEM\CurrentControlSet\Services\ServiceName содержащий значение DeleteFlag=1 (REG_DWORD), кажется, довольно свидетельствует о это несчастливое состояние.

0

В моем случае служба была отмечена для удаления после ее удаления, потому что я не располагал объект должным образом (соединение rabbitmq в моем случае).

Это не прямой ответ на вопрос, но может помочь решить корень проблемы.

Смежные вопросы