Поделиться через


функция обратного вызова LPSERVICE_MAIN_FUNCTIONA (winsvc.h)

Точка входа для службы.

Тип LPSERVICE_MAIN_FUNCTION определяет указатель на эту функцию обратного вызова. ServiceMain — это заполнитель для имени функции, определяемой приложением.

Синтаксис

LPSERVICE_MAIN_FUNCTIONA LpserviceMainFunctiona;

void LpserviceMainFunctiona(
  [in] DWORD dwNumServicesArgs,
  [in] LPSTR *lpServiceArgVectors
)
{...}

Параметры

[in] dwNumServicesArgs

Количество аргументов в массиве lpServiceArgVectors .

[in] lpServiceArgVectors

Строки аргументов, завершающиеся значением NULL, передаются службе путем вызова функции StartService , которая запустила службу. Если аргументы отсутствуют, этот параметр может иметь значение NULL. В противном случае первый аргумент (lpServiceArgVectors[0]) — это имя службы, за которым следуют любые дополнительные аргументы (lpServiceArgVectors[1] через lpServiceArgVectors[dwNumServicesArgs-1]).

Если пользователь запускает службу вручную с помощью оснастки "Службы" из панель управления, строки для параметра lpServiceArgVectors поступают из диалогового окна свойств службы (в оснастке "Службы" щелкните правой кнопкой мыши запись службы, выберите пункт Свойства и введите параметры в разделе Параметры запуска).)

Возвращаемое значение

None

Remarks

Программа обслуживания может запускать одну или несколько служб. Процесс службы имеет SERVICE_TABLE_ENTRY структуру для каждой службы, которую он может запустить. Структура указывает имя службы и указатель на функцию ServiceMain для этой службы.

Когда диспетчер управления службами получает запрос на запуск службы, он запускает процесс службы (если он еще не запущен). Поток main процесса службы вызывает функцию StartServiceCtrlDispatcher с указателем на массив SERVICE_TABLE_ENTRY структур. Затем диспетчер управления службой отправляет запрос на запуск диспетчеру управления службой для этого процесса службы. Диспетчер управления службой создает новый поток для выполнения функции ServiceMain запускаемой службы.

Функция ServiceMain должна немедленно вызвать функцию RegisterServiceCtrlHandlerEx , чтобы указать функцию HandlerEx для обработки запросов управления. Затем необходимо вызвать функцию SetServiceStatus для отправки сведений о состоянии в диспетчер управления службой. После этих вызовов функция должна завершить инициализацию службы. Не пытайтесь запустить другую службу в функции ServiceMain .

Диспетчер управления службами (SCM) ожидает, пока служба не сообщит о состоянии SERVICE_RUNNING. Рекомендуется, чтобы служба сообщала об этом состоянии как можно быстрее, так как другие компоненты в системе, требующие взаимодействия с SCM, будут заблокированы в течение этого времени. Для некоторых функций может потребоваться прямое или косвенное взаимодействие с SCM.

SCM блокирует базу данных управления службой во время инициализации, поэтому если служба попытается вызвать StartService во время инициализации, вызов заблокирует. Когда служба сообщает SCM об успешном запуске, она может вызвать StartService. Если служба требует выполнения другой службы, она должна задать необходимые зависимости.

Кроме того, не следует вызывать системные функции во время инициализации службы. Код службы должен вызывать системные функции только после сообщения о состоянии SERVICE_RUNNING.

Функция ServiceMain должна создать глобальное событие, вызвать функцию RegisterWaitForSingleObject для этого события и выйти. Это приведет к завершению потока, в котором выполняется функция ServiceMain , но не приведет к завершению службы. При остановке службы обработчик управления службой должен вызвать SetServiceStatus с SERVICE_STOP_PENDING и сообщить об этом событии. Поток из пула потоков будет выполнять функцию обратного вызова ожидания; Эта функция должна выполнять задачи очистки, включая закрытие глобального события, и вызывать SetServiceStatus с SERVICE_STOPPED. После остановки службы не следует выполнять дополнительный код службы, так как вы можете ввести состояние гонки, если служба получает элемент управления запуском и ServiceMain вызывается снова. Обратите внимание, что эта проблема с большей вероятностью возникнет, когда несколько служб совместно используют один процесс.

Примеры

Пример см. в разделе Написание функции ServiceMain.

Примечание

Заголовок winsvc.h определяет LPSERVICE_MAIN_FUNCTION как псевдоним, который автоматически выбирает версию ANSI или Юникод этой функции на основе определения константы препроцессора ЮНИКОД. Использование псевдонима, не зависящий от кодирования, с кодом, который не является нейтральным для кодировки, может привести к несоответствиям, которые приводят к ошибкам компиляции или времени выполнения. Дополнительные сведения см. в разделе Соглашения для прототипов функций.

Требования

Требование Значение
Минимальная версия клиента Windows XP [только классические приложения]
Минимальная версия сервера Windows Server 2003 [только классические приложения]
Целевая платформа Windows
Header winsvc.h (включая Windows.h)

См. также раздел

HandlerEx

RegisterServiceCtrlHandlerEx

RegisterWaitForSingleObject

SERVICE_TABLE_ENTRY

Функции службы

Функция Service ServiceMain

SetServiceStatus

StartServiceCtrlDispatcher