LPHANDLER_FUNCTION_EX função de retorno de chamada (winsvc.h)

Uma função de retorno de chamada definida pelo aplicativo usada com a função RegisterServiceCtrlHandlerEx . Um programa de serviço pode usá-lo como a função de manipulador de controle de um serviço específico.

O tipo LPHANDLER_FUNCTION_EX define um ponteiro para essa função. HandlerEx é um espaço reservado para o nome definido pelo aplicativo.

Essa função substitui a função manipuladora de controle Handler usada com a função RegisterServiceCtrlHandler . Um serviço pode usar qualquer manipulador de controle, mas o novo manipulador de controle dá suporte a dados de contexto definidos pelo usuário e códigos de controle estendidos adicionais.

Sintaxe

LPHANDLER_FUNCTION_EX LphandlerFunctionEx;

DWORD LphandlerFunctionEx(
  [in] DWORD dwControl,
  [in] DWORD dwEventType,
  [in] LPVOID lpEventData,
  [in] LPVOID lpContext
)
{...}

Parâmetros

[in] dwControl

O código de controle. Esse parâmetro pode usar um dos valores a seguir.

Código de controle Significado
SERVICE_CONTROL_CONTINUE
0x00000003
Notifica um serviço em pausa de que ele deve ser retomado.
SERVICE_CONTROL_INTERROGATE
0x00000004
Notifica um serviço para relatar suas informações de status atuais para o gerenciador de controle de serviço.

O manipulador deve simplesmente retornar NO_ERROR; o SCM está ciente do estado atual do serviço.

SERVICE_CONTROL_NETBINDADD
0x00000007
Notifica um serviço de rede de que há um novo componente para associação. O serviço deve ser associado ao novo componente.

Em vez disso, os aplicativos devem usar Plug and Play funcionalidade.

SERVICE_CONTROL_NETBINDDISABLE
0x0000000A
Notifica um serviço de rede de que uma de suas associações foi desabilitada. O serviço deve ler novamente suas informações de associação e remover a associação.

Em vez disso, os aplicativos devem usar Plug and Play funcionalidade.

SERVICE_CONTROL_NETBINDENABLE
0x00000009
Notifica um serviço de rede de que uma associação desabilitada foi habilitada. O serviço deve ler novamente suas informações de associação e adicionar a nova associação.

Em vez disso, os aplicativos devem usar Plug and Play funcionalidade.

SERVICE_CONTROL_NETBINDREMOVE
0x00000008
Notifica um serviço de rede de que um componente para associação foi removido. O serviço deve ler novamente suas informações de associação e desassociar do componente removido.

Em vez disso, os aplicativos devem usar Plug and Play funcionalidade.

SERVICE_CONTROL_PARAMCHANGE
0x00000006
Notifica um serviço de que os parâmetros de inicialização específicos do serviço foram alterados. O serviço deve ler novamente seus parâmetros de inicialização.
SERVICE_CONTROL_PAUSE
0x00000002
Notifica um serviço de que ele deve pausar.
SERVICE_CONTROL_PRESHUTDOWN
0x0000000F
Notifica um serviço de que o sistema será desligado. Os serviços que precisam de tempo adicional para executar tarefas de limpeza além da restrição de tempo apertado no desligamento do sistema podem usar essa notificação. O gerenciador de controle de serviço envia essa notificação para aplicativos que se registraram para ele antes de enviar uma notificação de SERVICE_CONTROL_SHUTDOWN para aplicativos que se registraram para essa notificação.

Um serviço que manipula essa notificação bloqueia o desligamento do sistema até que o serviço pare ou o intervalo de tempo limite de pré-desligamento especificado por meio de SERVICE_PRESHUTDOWN_INFO expire. Como isso afeta a experiência do usuário, os serviços devem usar esse recurso somente se for absolutamente necessário evitar perda de dados ou tempo de recuperação significativo no próximo início do sistema.

Windows Server 2003 e Windows XP: Não há suporte para esse valor.

SERVICE_CONTROL_SHUTDOWN
0x00000005
Notifica um serviço de que o sistema está sendo desligado para que o serviço possa executar tarefas de limpeza. Observe que os serviços que se registram para SERVICE_CONTROL_PRESHUTDOWN notificações não podem receber essa notificação porque já foram interrompidos.

Se um serviço aceitar esse código de controle, ele deverá parar depois de executar suas tarefas de limpeza e retornar NO_ERROR. Depois que o SCM enviar esse código de controle, ele não enviará outros códigos de controle para o serviço.

Para obter mais informações, confira a seção Comentários deste tópico.

SERVICE_CONTROL_STOP
0x00000001
Notifica um serviço de que ele deve parar.

Se um serviço aceitar esse código de controle, ele deverá parar após o recebimento e retornar NO_ERROR. Depois que o SCM enviar esse código de controle, ele não enviará outros códigos de controle para o serviço. Windows XP: Se o serviço retornar NO_ERROR e continuar a ser executado, ele continuará recebendo códigos de controle. Esse comportamento mudou a partir do Windows Server 2003 e do Windows XP com SP2.

 

Esse parâmetro também pode ser um dos seguintes códigos de controle estendidos. Observe que esses códigos de controle não são compatíveis com a função Handler .

Código de controle Significado
SERVICE_CONTROL_DEVICEEVENT
0x0000000B
Notifica um serviço de eventos de dispositivo. (O serviço deve ter se registrado para receber essas notificações usando a função RegisterDeviceNotification .) Os parâmetros dwEventType e lpEventData contêm informações adicionais.
SERVICE_CONTROL_HARDWAREPROFILECHANGE
0x0000000C
Notifica um serviço de que o perfil de hardware do computador foi alterado. O parâmetro dwEventType contém informações adicionais.
SERVICE_CONTROL_POWEREVENT
0x0000000D
Notifica um serviço de eventos de energia do sistema. O parâmetro dwEventType contém informações adicionais. Se dwEventType for PBT_POWERSETTINGCHANGE, o parâmetro lpEventData também conterá informações adicionais.
SERVICE_CONTROL_SESSIONCHANGE
0x0000000E
Notifica um serviço de eventos de alteração de sessão. Observe que um serviço só será notificado de um logon de usuário se ele for totalmente carregado antes da tentativa de logon ser feita. Os parâmetros dwEventType e lpEventData contêm informações adicionais.
SERVICE_CONTROL_TIMECHANGE
0x00000010
Notifica um serviço de que a hora do sistema foi alterada. O parâmetro lpEventData contém informações adicionais. O parâmetro dwEventType não é usado.

Windows Server 2008, Windows Vista, Windows Server 2003 e Windows XP: Não há suporte para esse código de controle.

SERVICE_CONTROL_TRIGGEREVENT
0x00000020
Notifica um serviço registrado para um evento de gatilho de serviço de que o evento ocorreu.

Windows Server 2008, Windows Vista, Windows Server 2003 e Windows XP: Não há suporte para esse código de controle.

SERVICE_CONTROL_USERMODEREBOOT
0x00000040
Notifica um serviço de que o usuário iniciou uma reinicialização.

Windows Server 2008 R2, Windows 7, Windows Server 2008, Windows Vista, Windows Server 2003 e Windows XP: Não há suporte para esse código de controle.

 

Esse parâmetro também pode ser um código de controle definido pelo usuário, conforme descrito na tabela a seguir.

Código de controle Significado
Intervalo de 128 a 255.
O serviço define a ação associada ao código de controle.

[in] dwEventType

O tipo de evento que ocorreu. Esse parâmetro será usado se dwControl for SERVICE_CONTROL_DEVICEEVENT, SERVICE_CONTROL_HARDWAREPROFILECHANGE, SERVICE_CONTROL_POWEREVENT ou SERVICE_CONTROL_SESSIONCHANGE. Caso contrário, será zero.

Se dwControl for SERVICE_CONTROL_DEVICEEVENT, esse parâmetro poderá ser um dos seguintes valores:

Se dwControl for SERVICE_CONTROL_HARDWAREPROFILECHANGE, esse parâmetro poderá ser um dos seguintes valores: Se dwControl for SERVICE_CONTROL_POWEREVENT, esse parâmetro poderá ser um dos valores especificados no parâmetro wParam da mensagem WM_POWERBROADCAST .

Se dwControl for SERVICE_CONTROL_SESSIONCHANGE, esse parâmetro poderá ser um dos valores especificados no parâmetro wParam da mensagem WM_WTSSESSION_CHANGE .

[in] lpEventData

Informações adicionais do dispositivo, se necessário. O formato desses dados depende do valor dos parâmetros dwControl e dwEventType .

Se dwControl for SERVICE_CONTROL_DEVICEEVENT, esses dados corresponderão ao parâmetro lParam que os aplicativos recebem como parte de uma mensagem de WM_DEVICECHANGE .

Se dwControl for SERVICE_CONTROL_POWEREVENT e dwEventType for PBT_POWERSETTINGCHANGE, esses dados serão um ponteiro para uma estrutura POWERBROADCAST_SETTING .

Se dwControl for SERVICE_CONTROL_SESSIONCHANGE, esse parâmetro será um ponteiro para uma estrutura WTSSESSION_NOTIFICATION .

Se dwControl for SERVICE_CONTROL_TIMECHANGE, esses dados serão um ponteiro para uma estrutura SERVICE_TIMECHANGE_INFO .

[in] lpContext

Dados definidos pelo usuário passados de RegisterServiceCtrlHandlerEx. Quando vários serviços compartilham um processo, o parâmetro lpContext pode ajudar a identificar o serviço.

Retornar valor

O valor retornado para essa função depende do código de controle recebido.

A lista a seguir identifica as regras para esse valor retornado:

  • Em geral, se o serviço não manipular o controle, retorne ERROR_CALL_NOT_IMPLEMENTED. No entanto, seu serviço deve retornar NO_ERROR para SERVICE_CONTROL_INTERROGATE mesmo que o serviço não o manipule.
  • Se o serviço manipular SERVICE_CONTROL_STOP ou SERVICE_CONTROL_SHUTDOWN, retorne NO_ERROR.
  • Se o serviço lidar com SERVICE_CONTROL_DEVICEEVENT, retorne NO_ERROR para conceder a solicitação e um código de erro para negar a solicitação.
  • Se o serviço lidar com SERVICE_CONTROL_HARDWAREPROFILECHANGE, retorne NO_ERROR para conceder a solicitação e um código de erro para negar a solicitação.
  • Se o serviço manipular SERVICE_CONTROL_POWEREVENT, retorne NO_ERROR para conceder a solicitação e um código de erro para negar a solicitação.
  • Para todos os outros códigos de controle que seu serviço manipula, retorne NO_ERROR.

Comentários

Quando um serviço é iniciado, sua função ServiceMain deve chamar imediatamente a função RegisterServiceCtrlHandlerEx para especificar uma função HandlerEx para processar solicitações de controle. Para especificar os códigos de controle a serem aceitos, use as funções SetServiceStatus e RegisterDeviceNotification .

O dispatcher de controle no thread main de um serviço invoca a função de manipulador de controle para o serviço especificado sempre que recebe uma solicitação de controle do gerenciador de controle de serviço. Depois de processar a solicitação de controle, o manipulador de controle deverá chamar SetServiceStatus se o estado do serviço for alterado para relatar seu novo status para o gerenciador de controle de serviço.

A função do manipulador de controle destina-se a receber notificação e retornar imediatamente. A função de retorno de chamada deve salvar seus parâmetros e criar outros threads para executar trabalho adicional. (Seu aplicativo deve garantir que esses threads tenham sido encerrados antes de interromper o serviço.) Em particular, um manipulador de controle deve evitar operações que possam ser bloqueadas, como tomar um bloqueio, pois isso pode resultar em um deadlock ou fazer com que o sistema pare de responder.

Quando o gerenciador de controle de serviço envia um código de controle para um serviço, ele aguarda o retorno da função de manipulador antes de enviar códigos de controle adicionais para outros serviços. O manipulador de controle deve retornar o mais rápido possível; se ele não retornar dentro de 30 segundos, o SCM retornará um erro. Se um serviço precisar fazer processamento longo quando o serviço estiver executando o manipulador de controle, ele deverá criar um thread secundário para executar o processamento longo e, em seguida, retornar do manipulador de controle. Isso impede o serviço de associar o dispatcher de controle e impedir que outros serviços recebam códigos de controle.

O código de controle SERVICE_CONTROL_SHUTDOWN só deve ser processado por serviços que devem limpo durante o desligamento, pois há um tempo limitado (cerca de 20 segundos) disponível para desligamento do serviço. Depois que esse tempo expirar, o desligamento do sistema continuará independentemente de o desligamento do serviço ser concluído. Observe que, se o sistema for deixado no estado de desligamento (não reiniciado ou desligado), o serviço continuará sendo executado. Se o serviço se registrar para aceitar SERVICE_CONTROL_SHUTDOWN, ele deverá manipular o código de controle e retornar NO_ERROR. Retornar um erro para esse código de controle e não parar em tempo hábil pode aumentar o tempo necessário para desligar o sistema, pois o sistema deve aguardar o tempo total permitido para o desligamento do serviço antes que o desligamento do sistema possa continuar.

Se o serviço exigir mais tempo para limpo, ele deverá enviar STOP_PENDING status mensagens, juntamente com uma dica de espera, para que o controlador de serviço saiba quanto tempo aguardar antes de relatar ao sistema que o desligamento do serviço foi concluído. No entanto, para impedir que um serviço pare o desligamento, há um limite para quanto tempo o controlador de serviço aguarda. Se o serviço estiver sendo desligado por meio do snap-in Serviços, o limite será de 125 segundos. Se o sistema operacional estiver sendo reinicializado, o limite de tempo será especificado no valor WaitToKillServiceTimeout da seguinte chave do Registro:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control

Certifique-se de lidar com Plug and Play eventos de dispositivo o mais rápido possível; caso contrário, o sistema pode ficar sem resposta. Se o manipulador de eventos for executar uma operação que possa bloquear a execução (como E/S), é melhor iniciar outro thread para executar a operação de forma assíncrona.

Os serviços também podem usar a função SetConsoleCtrlHandler para receber notificação de desligamento. Essa notificação é recebida quando os aplicativos em execução estão sendo desligados, o que ocorre antes de os serviços serem desligados.

Requisitos

Requisito Valor
Cliente mínimo com suporte Windows XP [somente aplicativos da área de trabalho]
Servidor mínimo com suporte Windows Server 2003 [somente aplicativos da área de trabalho]
Plataforma de Destino Windows
Cabeçalho winsvc.h (incluir Windows.h)

Confira também

POWERBROADCAST_SETTING

RegisterDeviceNotification

RegisterServiceCtrlHandlerEx

Função do manipulador do controle de serviço

Funções de serviço

ServiceMain

SetServiceStatus

WM_DEVICECHANGE

WM_POWERBROADCAST

WM_WTSSESSION_CHANGE

WTSSESSION_NOTIFICATION