Главная (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);
}
} |
Если ваша сервисная программа поддерживает несколько служб, то выполнение главной функции немного будет отличаться. Названия дополнительных служб должны быть добавлены в координирующую таблицу, таким образом они могут быть проверены потоком - диспетчером.