Написание сервисов Windows NT на WinAPI Страница 3. Функция Handler
|
Страница 3 из 4 Функция Handler Функция Handler будет вызываться менеджером сервисов при передаче сообщений сервису. Опять же название функции - любое. Адрес функции передается с помощью функции RegisterServiceCtrlHandler (см. выше). Функция имеет один параметр типа DWORD (Cardinal) - сообщение сервису. Если в одном процессе несколько сервисов - для каждого из них должна быть своя функция. procedure ServiceCtrlHandler(Opcode : Cardinal);stdcall; Опять не забываем про stdcall. Итак, функция получает код сообщения, который мы и проверяем. Начинаем вспоминать, что мы писали в ServiceStatus.dwControlsAccepted. У меня это SERVICE_ACCEPT_STOP и SERVICE_ACCEPT_PAUSE_CONTINUE, значит, мне надо проверять сообщения SERVICE_CONTROL_PAUSE, SERVICE_CONTROL_CONTINUE, SERVICE_CONTROL_STOP и выполнять соответствующие действия. Остальные сообщения: ServiceStatus.dwControlsAccepted | Обрабатываемые сообщения | SERVICE_ACCEPT_PAUSE_CONTINUE | SERVICE_CONTROL_PAUSE и SERVICE_CONTROL_CONTINUE | SERVICE_ACCEPT_STOP | SERVICE_CONTROL_STOP | SERVICE_ACCEPT_SHUTDOWN | SERVICE_CONTROL_SHUTDOWN | SERVICE_ACCEPT_PARAMCHANGE | SERVICE_CONTROL_PARAMCHANGE | Также надо обрабатывать SERVICE_CONTROL_INTERROGATE. Что это такое - непонятно, но обрабатывать надо :) Передаем новый статус сервиса менеджеру сервисов функцией SetServiceStatus.
Пример функции Handler: procedure ServiceCtrlHandler(Opcode : Cardinal);stdcall; var Status : Cardinal; begin case Opcode of SERVICE_CONTROL_PAUSE : begin ServiceStatus.dwCurrentState := SERVICE_PAUSED; end; SERVICE_CONTROL_CONTINUE : begin ServiceStatus.dwCurrentState := SERVICE_RUNNING; end; SERVICE_CONTROL_STOP : begin ServiceStatus.dwWin32ExitCode:=0; ServiceStatus.dwCurrentState := SERVICE_STOPPED; ServiceStatus.dwCheckPoint :=0; ServiceStatus.dwWaitHint :=0;
if not SetServiceStatus (ServiceStatusHandle,ServiceStatus) then begin Status:=GetLastError; LogError('SetServiceStatus'); Exit; end; exit; end;
SERVICE_CONTROL_INTERROGATE : ; end;
if not SetServiceStatus (ServiceStatusHandle, ServiceStatus) then begin Status := GetLastError; LogError('SetServiceStatus'); Exit; end; end; |