функция обратного вызова LPHANDLER_FUNCTION_EX (winsvc.h)
Определяемая приложением функция обратного вызова, используемая с функцией RegisterServiceCtrlHandlerEx . Программа-служба может использовать ее в качестве функции обработчика управления определенной службы.
Тип LPHANDLER_FUNCTION_EX определяет указатель на эту функцию. HandlerEx — это заполнитель для имени, определяемого приложением.
Эта функция заменяет функцию обработчика элемента управления Handler , используемую с функцией RegisterServiceCtrlHandler . Служба может использовать любой из обработчиков элементов управления, но новый обработчик элементов управления поддерживает определяемые пользователем контекстные данные и дополнительные расширенные коды элементов управления.
Синтаксис
LPHANDLER_FUNCTION_EX LphandlerFunctionEx;
DWORD LphandlerFunctionEx(
[in] DWORD dwControl,
[in] DWORD dwEventType,
[in] LPVOID lpEventData,
[in] LPVOID lpContext
)
{...}
Параметры
[in] dwControl
Код элемента управления. Этот параметр может принимать одно из указанных ниже значений.
Управляющий код | Значение |
---|---|
|
Уведомляет приостановленную службу о том, что она должна возобновиться. |
|
Уведомляет службу о том, что она сообщает о своем текущем состоянии диспетчеру управления службой.
Обработчик должен просто возвращать NO_ERROR; SCM учитывает текущее состояние службы. |
|
Уведомляет сетевую службу о наличии нового компонента для привязки. Служба должна быть привязана к новому компоненту.
Приложения должны использовать Plug and Play функции. |
|
Уведомляет сетевую службу о том, что одна из ее привязок отключена. Служба должна повторно прочитать сведения о привязке и удалить привязку.
Приложения должны использовать Plug and Play функции. |
|
Уведомляет сетевую службу о том, что отключенная привязка включена. Служба должна повторно прочитать сведения о привязке и добавить новую привязку.
Приложения должны использовать Plug and Play функции. |
|
Уведомляет сетевую службу о том, что компонент для привязки был удален. Служба должна повторно прочитать сведения о привязке и отменить привязку к удаленному компоненту.
Приложения должны использовать Plug and Play функции. |
|
Уведомляет службу о том, что параметры запуска для конкретной службы были изменены. Служба должна повторно прочитать свои параметры запуска. |
|
Уведомляет службу о том, что она должна приостановить работу. |
|
Уведомляет службу о том, что система будет завершаться. Службы, которым требуется дополнительное время для выполнения задач по очистке, превышающие жесткие ограничения по времени при завершении работы системы, могут использовать это уведомление. Диспетчер управления службами отправляет это уведомление приложениям, зарегистрированным для него, прежде чем отправлять уведомление SERVICE_CONTROL_SHUTDOWN приложениям, зарегистрированным для этого уведомления.
Служба, обрабатывающая это уведомление, блокирует завершение работы системы до тех пор, пока служба не остановится или не истечет интервал времени ожидания предварительного завершения, указанный в SERVICE_PRESHUTDOWN_INFO . Так как это влияет на взаимодействие с пользователем, службы должны использовать эту функцию только в том случае, если это абсолютно необходимо, чтобы избежать потери данных или значительного времени восстановления при следующем запуске системы. Windows Server 2003 и Windows XP: Это значение не поддерживается. |
|
Уведомляет службу о том, что система завершает работу, чтобы служба ей возможностями выполняла задачи очистки. Обратите внимание, что службы, которые регистрируются для SERVICE_CONTROL_PRESHUTDOWN уведомлений, не могут получить это уведомление, так как они уже остановлены.
Если служба принимает этот управляющий код, она должна остановиться после выполнения задач очистки и вернуть NO_ERROR. После того как SCM отправит этот управляющий код, он не будет отправлять другие коды управления в службу. Дополнительные сведения см. в разделе Примечания этого раздела. |
|
Уведомляет службу о том, что она должна остановиться.
Если служба принимает этот контрольный код, она должна остановиться после получения и возврата NO_ERROR. После того как SCM отправит этот управляющий код, он не будет отправлять другие коды управления в службу. Windows XP: Если служба возвращает NO_ERROR и продолжает работать, она продолжает получать коды управления. Это поведение изменилось начиная с Windows Server 2003 и Windows XP с пакетом обновления 2 (SP2). |
Этот параметр также может быть одним из следующих расширенных кодов управления. Обратите внимание, что эти коды элементов управления не поддерживаются функцией Handler .
Код элемента управления | Значение |
---|---|
|
Уведомляет службу о событиях устройства. (Служба должна быть зарегистрирована для получения этих уведомлений с помощью функции RegisterDeviceNotification .) Параметры dwEventType и lpEventData содержат дополнительные сведения. |
|
Уведомляет службу о том, что профиль оборудования компьютера изменился. Параметр dwEventType содержит дополнительные сведения. |
|
Уведомляет службу о событиях питания системы. Параметр dwEventType содержит дополнительные сведения. Если параметр dwEventType имеет PBT_POWERSETTINGCHANGE, параметр lpEventData также содержит дополнительные сведения. |
|
Уведомляет службу о событиях изменения сеанса. Обратите внимание, что служба будет получать уведомления о входе пользователя только в том случае, если она будет полностью загружена перед попыткой входа. Параметры dwEventType и lpEventData содержат дополнительные сведения. |
|
Уведомляет службу об изменении системного времени. Параметр lpEventData содержит дополнительные сведения. Параметр dwEventType не используется.
Windows Server 2008, Windows Vista, Windows Server 2003 и Windows XP: Этот код элемента управления не поддерживается. |
|
Уведомляет службу, зарегистрированную для события триггера службы , о том, что событие произошло.
Windows Server 2008, Windows Vista, Windows Server 2003 и Windows XP: Этот код элемента управления не поддерживается. |
|
Уведомляет службу о том, что пользователь инициировал перезагрузку.
Windows Server 2008 R2, Windows 7, Windows Server 2008, Windows Vista, Windows Server 2003 и Windows XP: Этот код элемента управления не поддерживается. |
Этот параметр также может быть пользовательским кодом элемента управления, как описано в следующей таблице.
Код элемента управления | Значение |
---|---|
|
Служба определяет действие, связанное с кодом элемента управления. |
[in] dwEventType
Тип произошедшего события. Этот параметр используется, если параметр dwControl имеет значение SERVICE_CONTROL_DEVICEEVENT, SERVICE_CONTROL_HARDWAREPROFILECHANGE, SERVICE_CONTROL_POWEREVENT или SERVICE_CONTROL_SESSIONCHANGE. В противном случае значение равно нулю.
Если параметр dwControl имеет SERVICE_CONTROL_DEVICEEVENT, этот параметр может иметь одно из следующих значений:
- DBT_DEVICEARRIVAL
- DBT_DEVICEREMOVECOMPLETE
- DBT_DEVICEQUERYREMOVE
- DBT_DEVICEQUERYREMOVEFAILED
- DBT_DEVICEREMOVEPENDING
- DBT_CUSTOMEVENT
Если параметр dwControlSERVICE_CONTROL_SESSIONCHANGE, этот параметр может быть одним из значений, указанных в параметре wParamWM_WTSSESSION_CHANGE сообщения.
[in] lpEventData
При необходимости дополнительные сведения об устройстве. Формат этих данных зависит от значения параметров dwControl и dwEventType .
Если параметр dwControlSERVICE_CONTROL_DEVICEEVENT, эти данные соответствуют параметру lParam , который приложения получают как часть сообщения WM_DEVICECHANGE .
Если параметр dwControl имеет значение SERVICE_CONTROL_POWEREVENT , а dwEventType — PBT_POWERSETTINGCHANGE, эти данные являются указателем на структуру POWERBROADCAST_SETTING .
Если dwControl имеет SERVICE_CONTROL_SESSIONCHANGE, этот параметр является указателем на структуру WTSSESSION_NOTIFICATION .
Если параметр dwControlSERVICE_CONTROL_TIMECHANGE, эти данные являются указателем на структуру SERVICE_TIMECHANGE_INFO .
[in] lpContext
Определяемые пользователем данные, передаваемые из RegisterServiceCtrlHandlerEx. Если несколько служб совместно используют процесс, параметр lpContext может помочь идентифицировать службу.
Возвращаемое значение
Возвращаемое значение для этой функции зависит от полученного кода элемента управления.
В следующем списке указаны правила для этого возвращаемого значения:
- Как правило, если служба не обрабатывает элемент управления, верните ERROR_CALL_NOT_IMPLEMENTED. Однако служба должна возвращать NO_ERROR для SERVICE_CONTROL_INTERROGATE даже если служба не обрабатывает их.
- Если служба обрабатывает SERVICE_CONTROL_STOP или SERVICE_CONTROL_SHUTDOWN, верните NO_ERROR.
- Если служба обрабатывает SERVICE_CONTROL_DEVICEEVENT, верните NO_ERROR , чтобы предоставить запрос, и код ошибки, чтобы отклонить запрос.
- Если служба обрабатывает SERVICE_CONTROL_HARDWAREPROFILECHANGE, верните NO_ERROR , чтобы предоставить запрос, и код ошибки, чтобы отклонить запрос.
- Если служба обрабатывает SERVICE_CONTROL_POWEREVENT, верните NO_ERROR , чтобы предоставить запрос, и код ошибки, чтобы отклонить запрос.
- Для всех остальных кодов управления, обрабатываемых службой, верните NO_ERROR.
Комментарии
При запуске службы ее функция ServiceMain должна немедленно вызвать функцию RegisterServiceCtrlHandlerEx , чтобы указать функцию HandlerEx для обработки запросов управления. Чтобы указать коды элементов управления для принятия, используйте функции SetServiceStatus и RegisterDeviceNotification .
Диспетчер элементов управления в потоке main службы вызывает функцию обработчика элементов управления для указанной службы всякий раз, когда получает запрос на управление от диспетчера управления службой. После обработки запроса элемента управления обработчик элементов управления должен вызвать SetServiceStatus , если состояние службы изменится, чтобы сообщить о новом состоянии диспетчеру управления службами.
Функция обработчика элемента управления предназначена для получения уведомления и немедленного возврата. Функция обратного вызова должна сохранить свои параметры и создать другие потоки для выполнения дополнительной работы. (Перед остановкой службы приложение должно убедиться, что такие потоки завершились.) В частности, обработчику элементов управления следует избегать операций, которые могут блокироваться, таких как блокировка, так как это может привести к взаимоблокировке или перестать отвечать системе.
Когда диспетчер управления службой отправляет код элемента управления в службу, он ожидает возврата функции обработчика перед отправкой дополнительных кодов управления в другие службы. Обработчик элемента управления должен возвращать как можно быстрее; Если он не возвращается в течение 30 секунд, SCM возвращает ошибку. Если служба должна выполнять длительную обработку, когда служба выполняет обработчик элемента управления, она должна создать дополнительный поток для выполнения длительной обработки, а затем вернуться из обработчика элемента управления. Это не позволяет службе привязывать диспетчер управления и блокировать получение кодов управления другими службами.
Код управления SERVICE_CONTROL_SHUTDOWN должен обрабатываться только службами, которые должны полностью очиститься во время завершения работы, так как для завершения работы службы доступно ограниченное время (около 20 секунд). По истечении этого времени завершение работы системы продолжается независимо от того, завершено ли завершение работы службы. Обратите внимание, что если система остается в состоянии завершения работы (не перезапущена или выключена), служба продолжает работать. Если служба регистрируется для принятия SERVICE_CONTROL_SHUTDOWN, она должна обрабатывать код элемента управления и возвращать NO_ERROR. Если вы возвращаете ошибку для этого кода элемента управления и не останавливается своевременно, это может увеличить время, необходимое для завершения работы системы, так как система должна дождаться полного периода времени, необходимого для завершения работы службы, прежде чем продолжить работу системы.
Если службе требуется больше времени для очистки, она должна отправлять STOP_PENDING сообщения о состоянии вместе с указанием ожидания, чтобы контроллер службы знал, сколько времени следует ждать, прежде чем сообщить системе о завершении работы службы. Тем не менее, чтобы предотвратить остановку работы службы, существует ограничение на время ожидания контроллера службы. Если служба завершает работу с помощью оснастки "Службы", ограничение составляет 125 секунд. Если операционная система перезагружается, ограничение времени указывается в значении WaitToKillServiceTimeout следующего раздела реестра:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control
Не забудьте как можно быстрее обрабатывать события Plug and Play устройства; в противном случае система может перестать отвечать на запросы. Если обработчик событий выполняет операцию, которая может блокировать выполнение (например, операции ввода-вывода), рекомендуется запустить другой поток для асинхронного выполнения операции.
Службы также могут использовать функцию SetConsoleCtrlHandler для получения уведомлений о завершении работы. Это уведомление получается при завершении работы работающих приложений, что происходит до завершения работы служб.
Требования
Требование | Значение |
---|---|
Минимальная версия клиента | Windows XP [только классические приложения] |
Минимальная версия сервера | Windows Server 2003 [только классические приложения] |
Целевая платформа | Windows |
Header | winsvc.h (включая Windows.h) |