Коды, требующие оповещения о состоянии

октября 12 2009 by admin in Службы

Действия HandlerEx напрямую зависят от полученного ей управляющего кода. В своих программах вам нужно уделить особое внимание обработке запросов с кодами операций. Когда HandlerEx получает управляющие коды SERVI-CE_CONTROL_STOP, SERVICE_CONTROL_SHUTDOWN, SERVICE_CONTROL_PA-USE или SERVICE_CONTROL_CONTINUE, должна быть вызвана функция SetSer-viceStatus, чтобы подтвердить получение кода и указать, сколько времени может потребоваться службе для изменения своего состояния на запрашиваемое. Вы можете подтвердить получение управляющего кода, например, установив элемент dwCurrentState структуры SERVICE_STATUS равным SERVICE_STOP_PEN-DING, SERVICE_PAUSE_PENDING или SERVICE_CONTINUE_PENDING. Кроме того, HandlerEx должна вернуть управление в течение 30 секунд, иначе SCP-приложение сочтет, что служба не отвечает. Если SCM считает, что служба не отвечает, он не уничтожает службу, а лишь возвращает ошибку той программе SCP, что инициировала запрос с данным управляющим кодом.
Когда выполняется операция останова, отключения, приостановки или продолжения работы службы, вы также должны указать, сколько, по вашему мнению, потребуется времени на ее выполнение. Указывать длительность выполнения операции полезно, так как служба не всегда может изменить свое состояние сразу — возможно, ей нужно дождаться завершения сетевого запроса или завершения записи данных на диск. Вы указываете, сколько времени потребуется для перехода в другое состояние, с помощью элементов dwCheckPoint и divWaitHint структуры SERVICE_STATUS так же, как вы это делали, оповещая о запуске службы. Вы можете оповещать о ходе выполнения операции, увеличивая значение dwCheckPoint и устанавливая значение dwWaitHint так, чтобы оно указывало, когда операция перейдет на следующий шаг.
После того, как служба выполнила все действия, необходимые для ее останова, отключения, приостановки или продолжения работы, надо снова вызвать SetServiceStatus. В этот раз элемент dwCurrentStatus должен быть установлен в SERVICE_STOPPED, SERVICE_PAUSED или SERVICE_RUNNING. Когда вы оповещаете об этих трех состояниях, элементы dwCheckPoint и dwWaitHint должны быть установлены в 0, так как служба перешла в другое состояние.
После того, как служба вызвала SetServiceStatus, чтобы оповестить о состоянии SERVICE_STOPPED, SCM позволяет службе проработать еще 30 секунд. Если служба продолжает работать через 30 секунд, SCM прекращает выполнение процесса службы, если в данном процессе не осталось работающих служб.
Когда HandlerEx получает управляющий код SERVICE_CONTROL_INTERRO-GATE, служба должна лишь подтвердить его получение, указав свое текущее состояние в dwCurrentState и вызвав SetServiceStatus. (Перед этим вызовом значения элементов dwCheckPoint и dwWaitHint опять же должны быть установлены в 0.)
При отключении системы HandlerEx получает код уведомления SERVICE_ CONTROL_SHUTDOWN. Соответствующая служба должна выполнить минимальную совокупность действий, необходимых для сохранения данных и обратиться к SetServiceStatus, указав состояние SERVICE_STOPPED. Чтобы гарантировать корректное отключение машины, любая служба должна обрабатывать этот код только в случае абсолютной необходимости. По умолчанию система выделяет всего 20 секунд всем службам, чтобы они прекратили работу. Через 20 секунд процесс SCM (Services.exe) уничтожается, и продолжается отключение машины. Этот 20-секундный срок определяется значением WaitToKillService-Timeout, которое содержится в следующем подразделе реестра.
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control
При отключении системы SCM уведомляет об этом все службы, которые воспринимают код уведомления SERVICE_CONTROL_SHUT-DOWN. Одни службы могут игнорировать этот код, другие — сохранять данные на диске, а третьи — останавливаться и прекращать работу. Нужно очень внимательно следить за тем, чтобы ваша служба не выполняла операций, требующих участия других служб. Эти службы могут быть в «плохом» состоянии или вообще не работать. Система полностью игнорирует взаимозависимости служб при отключении питания. Целью Microsoft было обеспечить как можно более быстрое отключение системы. Фактически другие службы могут получить уведомление об отключении даже раньше, чем ваша получит от них уведомление. Проблема с порядком получения уведомлений об отключении в том, что службы, от которых вы зависите, могут прекратить работу п любой момент и ваша служба должна безошибочно действовать в таких ситуациях.