Функция main()

Функция main()

Задачей новой функции main(), которая вызывается SCM, является регистрация службы в SCM и запуск диспетчера службы (service control dispatcher). Для этого необходимо вызвать функцию StartServiceControlDispatcher, передав ей имя (имена) и точку (точки) входа одной или нескольких логических служб.

BOOL StartServiceCtrlDispatcher(LPSERVICE_TABLE_ENTRY lpServiceStartTable)

Эта функция принимает единственный аргумент lpServiceStartTable, являющийся адресом массива элементов SERVICE_TABLE_ENTRY, каждый из которых представляет имя и точку входа логической службы. Конец массива обозначается двумя последовательными значениями NULL.

Функция возвращает значение TRUE, если регистрация службы прошла успешно. Если служба уже выполняется или возникают проблемы с обновлением записей реестра (HKEY_LOCAL_MACHINESYSTEMCurrentControlSetServices), функция завершается с ошибками, обработка которых может осуществляться обычным путем.

Основной поток процесса службы, которая вызывает функцию StartService-ControlDispatcher, связывает поток с SCM. SCM регистрирует службу с вызывающим потоком в качестве потока диспетчера службы. SCM не осуществляет возврата в вызывающий поток до тех пор, пока не завершат выполнение все службы. Заметьте, однако, что фактического запуска логических служб в этот момент не происходит; запуск службы требует вызова функции StartService, которая описывается далее в этой главе.

Типичная основная программа службы, соответствующая случаю единственной логической службы, представлена в программе 13.1.

Программа 13.1. main: точка входа main службы 

#include "EvryThng.h"

void WINAPI ServiceMain(DWORD argc, LPTSTR argv[]);

static LPTSTR ServiceName = _T("SocketCommandLineService");

/* Главная программа запуска диспетчера службы. */

VOID _tmain(int argc, LPTSTR argv[]) {

 SERVICE_TABLE_ENTRY DispatchTable[] = {

  { ServiceName, ServiceMain },

  { NULL, NULL }

 };

 if (!StartServiceCtrlDispatcher(DispatchTable)) ReportError(_T("Ошибка при запуске диспетчера службы."), 1, TRUE);

 /* ServiceMain() начнет выполняться только после того, как ее */

 /* запустит SCM. Возврат сюда осуществляется только после того, */

 /* как завершится выполнение всех служб. */

 return;