Выбрать главу

Таблица 13.2. Значения параметра состояния службы

Значение Описание SERVICE_STOPPED Служба не выполняется. SERVICE_START_PENDING Служба находится на стадии запуска, но пока не готова отвечать на запросы. Например, могут еще не быть запущены рабочие потоки. SERVICE_STOP_PENDING Служба находится на стадии остановки, но еще не завершила своего выполнения. Например, мог быть установлен глобальный флаг завершения, но рабочие потоки еще не успели на это отреагировать. SERVICE_RUNNING Служба выполняется. SERVICE CONTINUE_PENDING Служба переходит в состояние выполнения после нахождения в состоянии паузы. SERVICE_PAUSE_PENDING Служба переходит в состояние паузы, но ее безопасное нахождение в этом состоянии пока не обеспечено. SERVICE PAUSED Служба находится в состоянии паузы. Воспринимаемые управляющие коды

Параметр dwControlsAccepted определяет управляющие коды, которые служба будет воспринимать и обрабатывать с помощью своего обработчика (см. следующий раздел). В табл. 13.3 указаны четыре возможных значения, которые могут объединяться посредством операции поразрядного "или" (|). Версия программы serverSK, которую мы впоследствии разработаем, будет воспринимать лишь три первых значения. Дополнительные значения приведены в разделе MSDN, содержащем описание структуры SERVICE_STATUS.

Таблица 13.3. Коды, воспринимаемые службой (неполный перечень) 

Значение Описание SERVICE_ACCEPT_STOP Разрешает посылку команды SERVICE_CONTROL_STOP. SERVICE_ACCEPT_PAUSE_CONTINUE Разрешает посылку команд SERVICE_CONTROL_PAUSE и SERVICE_CONTROL_CONTINUE. SERVICE_ACCEPT_SHUTDOWN Уведомляет службу о прекращении работы системы. Это дает системе возможность послать службе команду SERVICE_CONTROL_SHUTDOWN. SERVICE_ACCEPT_PARAMCHANGE Требуется NT5. Обеспечивает изменение параметров запуска без выполнения самого перезапуска. Соответствующей командой является SERVICE_CONTROL_PARAMCHANGE 

Специфический для службы код

После того как обработчик зарегистрирован и для службы установлено состояние SERVICE_START_PENDING, служба может инициализировать себя и вновь установить свое состояние. Если говорить о преобразованной версии serverSK, то сразу же после того, как сокеты будут инициализированы, а сервер готов к работе с клиентами, должно быть установлено состояние SERVICE_RUNNING.

Обработчик управляющих команд службы

Обработчик управляющих команд службы, то есть функция косвенного вызова, определяемая с помощью функции RegisterServiceCtrlHandlerEx, имеет следующий прототип: 

DWORD WINAPI HandlerEx(DWORD dwControl, DWORD dwEventType, LPVOID lpEventData, LPVOID lpContext) 

dwControl — обозначает фактическую управляющую команду, поступившую в обработчик от SCM. До появления NT5 и введения функции RegisterServiceCtrlHandlerEx этот параметр был единственным параметром обработчика.

Всего существует 14 возможных значений параметра dwControl, включая те, которые перечислены в табл. 13.3, хотя некоторые команды поддерживаются только в NT5 или XP. Нас будут интересовать следующие значения, которые используются в примере:

SERVICE_CONTROL_STOP

SERVICE_CONTROL_PAUSE

SERVICE_CONTROL_CONTINUE

SERVICE_CONTROL_INTERROGATE

SERVICE_CONTROL_SHUTDOWN

Разрешены также пользовательские значения, определяемые в интервале 128-255, однако нам они не понадобятся.

dwEventType — обычно принимает значение 0, в то время как ненулевые значения используются для управления устройствами, но рассмотрение этого вопроса выходит за рамки данной книги. Параметр dwEventType определяет дополнительную информацию, которая требуется соответствующим событиям.

Наконец, lpContext — пользовательские данные, передаваемые в функцию RegisterServiceCtrlHandlerEx во время регистрации обработчика.

Обработчик активизируется SCM в том же потоке, что и основная программа, и обычно содержит ряд операторов switch, как будет показано в приведенных ниже примерах.

Пример: "интерфейсная оболочка" службы

Программа 13.2 реализует преобразованный вариант программы serverSK, который мы перед этим обсуждали. Преобразование сервера в службу сопряжено с решением всех ранее описанных задач. После внесения незначительных изменений существующий код сервера помещается в функцию ServiceSpecific. Поэтому представленный ниже код, по сути, является оболочкой (wrapper) существующей программы сервера, точка входа которой main заменена на ServiceSpecifiс.

Другим дополнением, которое здесь не представлено, но включено в вариант программы, находящийся на Web-сайте книги, является использование журнала службы, поскольку службы часто запускаются без интерактивной консоли, никак себя видимо не проявляя. 

Программа 13.2. SimpleService: оболочка службы