Я наткнулся серьезной проблема в моей/сервисной программе клиента, которая работает следующим образом:SetServiceStatus устанавливает SERVICE_STOPPED, но QueryServiceStatusEx возвращает SERVICE_STOP_PENDING
- Клиентское приложение использует
ControlService(... SERVICE_CONTROL_STOP ...)
, чтобы остановить службу. - Пока служба останавливается, приложение периодически вызывает
QueryServiceStatusEx
, чтобы проверить,dwCurrentState
isSERVICE_STOPPED
. Он также проверяетdwWaitHint
на время ожидания.
Тем временем служба делает это:
- Перед чисткой вверх, он вызывает
SetServiceStatus
сdwCurrentState
=SERVICE_STOP_PENDING
иdwWaitHint
=3000
. - После очистки, он вызывает
SetServiceStatus
сdwCurrentState
=SERVICE_STOPPED
иdwWaitHint
=0
.
После воспроизведения и протоколирование вопрос, который я придумал это:
Все работает, как и ожидалось кроме в последний раз, когда клиент вызывает QueryServiceStatusEx
, который возвращает dwCurrentState
= SERVICE_STOP_PENDING
и dwWaitHint
= 0
! Это приводит к тому, что он ведет себя так, как будто время ожидания операции.
Я не знаю, как это может произойти, я четко вижу в журналах, что служба устанавливает dwCurrentState
= SERVICE_STOPPED
перед выходом.
Это известная проблема? У вас есть какая-то подсказка, что может произойти здесь?
Update:
Вот логи клиентского приложения:
24437 ssStatus.dwWaitHint: 3000, ssStatus.dwCurrentState: 3
24546 ssStatus.dwWaitHint: 0, ssStatus.dwCurrentState: 3
24609 ssStatus.dwWaitHint: 0, ssStatus.dwCurrentState: 3
...
26000 ssStatus.dwWaitHint: 0, ssStatus.dwCurrentState: 3
26062 ssStatus.dwWaitHint: 0, ssStatus.dwCurrentState: 3
26218 Stopped
Как вы можете видеть, служба остановленные между 24437 и 24546 (GetTickCount
), и это состояние было изменено на 26218. Это означает, что он был помечен как SERVICE_STOP_PENDING
за дополнительные 1,672 секунды. Может быть, Windows изменяет состояние? Почему он был помечен так долго?
Update 2:
Больше наблюдения:
- вызова
SetServiceStatus
влияет на все, кромеdwCurrentState
, которая остается вSERVICE_STOP_PENDING
до тех пор, как процесс обслуживания работает. Это особенность Windows? Документировано? - Мой сервисный процесс остается висящим более чем на одну секунду после возвращения с
LPSERVICE_MAIN_FUNCTION
и перед возвратом сStartServiceCtrlDispatcher
. Почему это происходит? (P.S. это происходит при загрузке Windows). - Попытка написать исполняемый файл службы иногда возвращает
ERROR_SHARING_VIOLATION
, хотя это состояниеSERVICE_STOPPED
. Есть ли надежный способ убедиться, что процесс полностью завершен?
Может кто-нибудь объяснить это? Раймонд Чен?
Update 3:
Более интересная информация: QueryServiceStatusEx
возвращает dwWaitHint: 0, dwCurrentState: 3, dwCheckPoint: 0, даже если я никогда не ставил dwWaitHint
и dwCheckPoint
к нулю! Что тут происходит?
Ну, вы ничего не можете с этим поделать, чтобы просто решить проблему. dwWaitHint не имеет смысла для остановленного состояния, поэтому просто не меняйте его. –
Это то, что MS делает в своем [пример] (http://msdn.microsoft.com/en-us/library/windows/desktop/bb540475%28v=vs.85%29.aspx) («ReportSvcStatus (SERVICE_STOPPED, NO_ERROR, 0); "), и мое приложение основано на нем, следовательно, поведение. Я сделал несколько дополнительных протоколов и обновил вопрос. – Paul
Я подозреваю, что ваша служба выполняет некоторую работу между настройкой статуса на SERVICE_STOPPED и выходом ServiceMain. Возможно, у вас есть куча состояния, внедренного в локальную переменную в вашей функции ServiceMain, поэтому она очищается в деструкторе, когда функция, по-видимому, завершена? – arx