Compartilhar via


Função manipulador de controle de serviço

Cada serviço tem um manipulador de controle, a funçãomanipulador de, que é invocada pelo dispatcher de controle quando o processo de serviço recebe uma solicitação de controle de um programa de controle de serviço. Portanto, essa função é executada no contexto do dispatcher de controle. Para obter um exemplo, consulte Gravando uma função de manipulador de controle.

Um serviço chama a função RegisterServiceCtrlHandler ou RegisterServiceCtrlHandlerEx para registrar sua função de manipulador de controle de serviço.

Quando o manipulador de controle de serviço é invocado, o serviço deve chamar a função SetServiceStatus para relatar seu status ao SCM somente se o tratamento do código de controle fizer com que o status do serviço seja alterado. Se o tratamento do código de controle não fizer com que o status do serviço seja alterado, não será necessário chamar SetServiceStatus.

Um programa de controle de serviço pode enviar solicitações de controle usando a funçãoControlService. Todos os serviços devem aceitar e processar o código de controle SERVICE_CONTROL_INTERROGATE. Você pode habilitar ou desabilitar a aceitação dos outros códigos de controle chamando SetServiceStatus. Para receber o código de controle SERVICE_CONTROL_DEVICEEVENT, você deve chamar a funçãoRegisterDeviceNotification. Os serviços também podem lidar com códigos de controle definidos pelo usuário adicionais.

Se um serviço aceitar o código de controle SERVICE_CONTROL_STOP, ele deverá parar após o recebimento, indo para o estado SERVICE_STOP_PENDING ou SERVICE_STOPPED. Depois que o SCM enviar esse código de controle, ele não enviará outros códigos de controle.

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 o Service Pack 2 (SP2).

O manipulador de controle deve retornar dentro de 30 segundos ou o SCM retorna 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 retornar do manipulador de controle. Isso impede que o serviço acione o dispatcher de controle. Por exemplo, ao lidar com a solicitação de parada para um serviço que leva muito tempo, crie outro thread para lidar com o processo de parada. O manipulador de controle deve simplesmente chamar SetServiceStatus com a mensagem SERVICE_STOP_PENDING e retornar.

Quando o usuário desliga o sistema, todos os manipuladores de controle que chamaram SetServiceStatus com o código de controle SERVICE_ACCEPT_PRESHUTDOWN recebem o código de controle SERVICE_CONTROL_PRESHUTDOWN. O gerenciador de controle de serviço aguarda até que o serviço pare ou o valor de tempo limite de pré-redução especificado expire (esse valor pode ser definido com a função ChangeServiceConfig2). Esse código de controle deve ser usado apenas em circunstâncias especiais, pois 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é-redução expire.

Depois que as notificações de pré-autenticação tiverem sido concluídas, todos os manipuladores de controle que chamaram SetServiceStatus com o código de controle SERVICE_ACCEPT_SHUTDOWN receberão o código de controle SERVICE_CONTROL_SHUTDOWN. Eles são notificados na ordem em que aparecem no banco de dados dos serviços instalados. Por padrão, um serviço tem aproximadamente 20 segundos para executar tarefas de limpeza antes que o sistema seja desligado. 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 exigir mais tempo para limpeza, ele enviará STOP_PENDING mensagens de status, 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 está 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 ou 125.000 milissegundos. Se o sistema operacional estiver sendo reinicializado, o limite de tempo será especificado no valor WaitToKillServiceTimeout (em milissegundos) da seguinte chave do Registro:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control

Importante

Um serviço não deve tentar aumentar o limite de tempo modificando esse valor. Se você precisar definir WaitToKillServiceTimeout manualmente, o valor deverá estar em milissegundos.

Os clientes exigem desligamento rápido do sistema operacional. Por exemplo, se um computador em execução na energia UPS não puder concluir o desligamento antes que o UPS fique sem energia, os dados poderão ser perdidos. Portanto, os serviços devem concluir suas tarefas de limpeza o mais rápido possível. É uma boa prática minimizar dados não salvos salvando dados regularmente, mantendo o controle dos dados salvos no disco e salvando apenas os dados não salvos no desligamento. Como o computador está sendo desligado, não gaste tempo liberando memória alocada ou outros recursos do sistema. Se você precisar notificar um servidor de que está saindo, minimize o tempo gasto aguardando uma resposta, pois os problemas de rede podem atrasar o desligamento do serviço.

Observe que, durante o desligamento do serviço, por padrão, o SCM não leva em consideração as dependências. O SCM enumera a lista de serviços em execução e envia o comando SERVICE_CONTROL_SHUTDOWN. Portanto, um serviço pode falhar porque outro serviço do qual ele depende já foi interrompido.

Para definir a ordem de desligamento dos serviços manualmente, crie um valor de registro de várias cadeias de caracteres que contenha os nomes de serviço na ordem em que eles devem ser desligados e atribua-o ao valor PreshutdownOrder da chave de controle, da seguinte maneira:

deHKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\PreshutdownOrder="Shutdown Order

Para definir a ordem de desligamento de serviços dependentes de seu aplicativo, use a função SetProcessShutdownParameters. O SCM usa essa função para dar prioridade 0x1E0 ao manipulador. O SCM envia SERVICE_CONTROL_SHUTDOWN notificações quando seu manipulador de controle é chamado e aguarda a saída dos serviços antes de retornar de seu manipulador de controle.

gravando uma função de manipulador de controle