Главная (main) функция сервисной программы вызывает функцию StartServiceCtrlDispatcher, чтобы установить связь с Диспетчером управления службами (SCM) и запустить поток диспетчера управления. Циклы потока диспетчера, ждущие поступающих запросов на управление для служб, задаются в координирующей таблице. Этот поток не возвращает значения до тех пор, пока не появится ошибка или пока все службы в процессе не завершат работу. Когда все службы в процессе завершили работу, Диспетчер управления службами (SCM) отправляет управляющий запрос потоку - диспетчеру, который указывает ему выключиться. Поток может затем возвратить значение из вызова StartServiceCtrlDispatcher и процесс может завершить работу.
Пример ниже - это процесс службы, который поддерживает только одну службу. Требуется два параметра: строка, которая может включать в себя один форматированный символ и числовое значение, которое используется как форматированный символ. Функция SvcDebugOut отображает на экране информационные сообщения и ошибки для отладчика. Информацию о записи функций MyServiceStart и MyServiceInitialization, см. в статье Запись функции ServiceMain. Информацию о записи функции MyServiceCtrlHandler, см в статье. Запись функции обрабатывающей программы управления.
Чтобы выводить информацию отладки, этот код вызывает SvcDebugOut. Исходный текст для SvcDebugOut дается в статье Запись главной функции сервисной программы.
#include <windows.h> SERVICE_STATUS MyServiceStatus; SERVICE_STATUS_HANDLE MyServiceStatusHandle; VOID SvcDebugOut(LPSTR String, DWORD Status); VOID WINAPI MyServiceCtrlHandler (DWORD opcode); VOID MyServiceStart (DWORD argc, LPTSTR *argv); DWORD MyServiceInitialization (DWORD argc, LPTSTR *argv, DWORD *specificError); void main( ) { SERVICE_TABLE_ENTRY DispatchTable[] = { { "MyService", MyServiceStart }, { NULL, NULL } }; if (!StartServiceCtrlDispatcher( DispatchTable)) { SvcDebugOut(" [MY_SERVICE] StartServiceCtrlDispatcher (%d)\n", GetLastError()); } } VOID SvcDebugOut(LPSTR String, DWORD Status) { CHAR Buffer[1024]; if (strlen(String) < 1000) { sprintf(Buffer, String, Status); OutputDebugStringA(Buffer); } } |
Если ваша сервисная программа поддерживает несколько служб, то выполнение главной функции немного будет отличаться. Названия дополнительных служб должны быть добавлены в координирующую таблицу, таким образом они могут быть проверены потоком - диспетчером.