Nota
O acesso a esta página requer autorização. Podes tentar iniciar sessão ou mudar de diretório.
O acesso a esta página requer autorização. Podes tentar mudar de diretório.
Cada serviço tem um manipulador de controle, a funçãoHandler, 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 despachante de controle. Para obter um exemplo, consulte Escrevendo uma função do manipulador de controle.
Um serviço chama o RegisterServiceCtrlHandler ou função de 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çãoSetServiceStatus dopara relatar seu status ao SCM somente se a manipulação do código de controle fizer com que o status do serviço seja alterado. Se a manipulação 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 adicionais definidos pelo usuário.
Se um serviço aceitar o código de controle SERVICE_CONTROL_STOP, ele deve parar após o recebimento, indo para o estado SERVICE_STOP_PENDING ou SERVICE_STOPPED. Depois que o SCM envia 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á a receber códigos de controle. Esse comportamento foi alterado a partir do Windows Server 2003 e Windows XP com Service Pack 2 (SP2).
O manipulador de controle deve retornar dentro de 30 segundos ou o SCM retorna um erro. Se um serviço deve fazer processamento demorado quando o serviço está executando o manipulador de controle, ele deve criar um thread secundário para executar o processamento demorado e, em seguida, retornar do manipulador de controle. Isso evita que o serviço amarre o despachante de controle. Por exemplo, ao lidar com a solicitação stop para um serviço que leva muito tempo, crie outro thread para manipular o processo stop. 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é-desligamento especificado expire (esse valor pode ser definido com a funçãoChangeServiceConfig2). Esse código de controle deve ser usado somente em circunstâncias especiais, porque um serviço que lida com essa notificação bloqueia o desligamento do sistema até que o serviço pare ou o intervalo de tempo limite de pré-desligamento expire.
Após a conclusão das notificações de pré-desligamento, todos os manipuladores de controle que chamaram SetServiceStatus com o código de controle SERVICE_ACCEPT_SHUTDOWN recebem o código de controle SERVICE_CONTROL_SHUTDOWN. Eles são notificados na ordem em que aparecem no banco de dados de serviços instalados. Por padrão, um serviço tem aproximadamente 20 segundos para executar tarefas de limpeza antes que o sistema seja desligado. Após esse tempo expirar, o desligamento do sistema prossegue, independentemente de o desligamento do serviço estar concluído. Observe que, se o sistema for deixado no estado de desligamento (não reiniciado ou desligado), o serviço continuará a ser executado.
Se o serviço exigir mais tempo para limpeza, ele enviará mensagens de status STOP_PENDING, juntamente com uma dica de espera, para que o controlador de serviço saiba quanto tempo esperar antes de informar ao sistema que o desligamento do serviço foi concluído. No entanto, para evitar que um serviço pare o desligamento, há um limite para quanto tempo o controlador de serviço espera. Se o serviço estiver sendo desligado por meio do snap-in Serviços, o limite é de 125 segundos ou 125.000 milissegundos. Se o sistema operacional estiver reinicializando, 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 deve ser em milissegundos.
Os clientes exigem o desligamento rápido do sistema operacional. Por exemplo, se um computador com UPS não conseguir concluir o encerramento antes de a UPS ficar sem energia, os dados podem ser perdidos. Portanto, os serviços devem concluir suas tarefas de limpeza o mais rápido possível. É uma boa prática minimizar os 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 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 as dependências em consideração. 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á parou.
Para definir a ordem de desligamento dos serviços manualmente, crie um valor de registro multistring 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:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\PreshutdownOrder="Shutdown Order"
Para definir a ordem de desligamento dos serviços dependentes do seu aplicativo, use a funçãoSetProcessShutdownParameters. O SCM usa essa função para dar prioridade ao manipulador 0x1E0. O SCM envia notificações de SERVICE_CONTROL_SHUTDOWN quando seu manipulador de controle é chamado e aguarda a saída dos serviços antes de retornar de seu manipulador de controle.
Tópicos relacionados