функция обратного вызова 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 поступают из диалогового окна свойств службы (в оснастке "Службы" щелкните правой кнопкой мыши запись службы, щелкните Свойстваи введите параметры в параметров запуска.)
Возвращаемое значение
Никакой
Замечания
Программа службы может запустить одну или несколько служб. Процесс службы имеет SERVICE_TABLE_ENTRY структуру для каждой службы, которую он может запустить. Структура задает имя службы и указатель на функцию serviceMain ServiceMain для этой службы.
Когда диспетчер управления службами получает запрос на запуск службы, он запускает процесс службы (если он еще не запущен). Основной поток процесса службы вызывает функцию 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 [только классические приложения] |
целевая платформа | Виндоус |
заголовка | winsvc.h (включая Windows.h) |
См. также
Функция ServiceMain serviceMain