Системное программирование в среде Windows
Шрифт:
Значение параметра dwCurrentState указывает на текущее состояние службы. Возможные значения этого параметра перечислены в табл. 13.2.
Таблица 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, имеет следующий прототип:
dwControl — обозначает фактическую управляющую
команду, поступившую в обработчик от SCM. До появления NT5 и введения функции RegisterServiceCtrlHandlerEx этот параметр был единственным параметром обработчика.Всего существует 14 возможных значений параметра dwControl, включая те, которые перечислены в табл. 13.3, хотя некоторые команды поддерживаются только в NT5 или XP. Нас будут интересовать следующие значения, которые используются в примере:
Разрешены также пользовательские значения, определяемые в интервале 128-255, однако нам они не понадобятся.
dwEventType — обычно принимает значение 0, в то время как ненулевые значения используются для управления устройствами, но рассмотрение этого вопроса выходит за рамки данной книги. Параметр dwEventType определяет дополнительную информацию, которая требуется соответствующим событиям.
Наконец, lpContext — пользовательские данные, передаваемые в функцию RegisterServiceCtrlHandlerEx во время регистрации обработчика.
Обработчик активизируется SCM в том же потоке, что и основная программа, и обычно содержит ряд операторов switch, как будет показано в приведенных ниже примерах.
Пример: "интерфейсная оболочка" службы
Программа 13.2 реализует преобразованный вариант программы serverSK, который мы перед этим обсуждали. Преобразование сервера в службу сопряжено с решением всех ранее описанных задач. После внесения незначительных изменений существующий код сервера помещается в функцию ServiceSpecific. Поэтому представленный ниже код, по сути, является оболочкой (wrapper) существующей программы сервера, точка входа которой main заменена на ServiceSpecifiс.
Другим дополнением, которое здесь не представлено, но включено в вариант программы, находящийся на Web-сайте книги, является использование журнала службы, поскольку службы часто запускаются без интерактивной консоли, никак себя видимо не проявляя.