Serviços Interativos
Normalmente, os serviços são aplicativos de console projetados para serem executados sem supervisão sem uma GUI (interface gráfica do usuário). No entanto, alguns serviços podem exigir interação ocasional com um usuário. Esta página discute as melhores maneiras de interagir com o usuário de um serviço.
Importante
Os serviços não podem interagir diretamente com um usuário a partir do Windows Vista. Portanto, as técnicas mencionadas na seção intitulada Usando um serviço interativo não devem ser usadas em um novo código.
Interagir com um usuário de um serviço indiretamente
Você pode usar as seguintes técnicas para interagir com o usuário de um serviço em todas as versões com suporte do Windows:
Exibir uma caixa de diálogo na sessão do usuário usando a função WTSSendMessage .
Crie um aplicativo de GUI oculto separado e use a função CreateProcessAsUser para executar o aplicativo dentro do contexto do usuário interativo. Projete o aplicativo gui para se comunicar com o serviço por meio de algum método de comunicação entre processos (IPC), por exemplo, pipes nomeados. O serviço se comunica com o aplicativo gui para informar quando exibir a GUI. O aplicativo comunica os resultados da interação do usuário de volta ao serviço para que o serviço possa executar a ação apropriada. Observe que o IPC pode expor suas interfaces de serviço pela rede, a menos que você use uma ACL (lista de controle de acesso) apropriada.
Se esse serviço for executado em um sistema multiusuário, adicione o aplicativo à seguinte chave para que ele seja executado em cada sessão: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run. Se o aplicativo usar pipes nomeados para IPC, o servidor poderá distinguir entre vários processos de usuário, dando a cada pipe um nome exclusivo com base na ID da sessão.
A seguinte técnica também está disponível para Windows Server 2003 e Windows XP:
- Exiba uma caixa de mensagem chamando a função MessageBox com MB_SERVICE_NOTIFICATION. Isso é recomendado para exibir mensagens status simples. Não chame MessageBox durante a inicialização do serviço ou da rotina HandlerEx , a menos que você a chame de um thread separado, para que você retorne ao SCM em tempo hábil.
Usando um serviço interativo
Por padrão, os serviços usam uma estação de janela não interativa e não podem interagir com o usuário. No entanto, um serviço interativo pode exibir uma interface do usuário e receber a entrada do usuário.
Cuidado
Os serviços em execução em um contexto de segurança elevado, como a conta LocalSystem, não devem criar uma janela na área de trabalho interativa porque qualquer outro aplicativo em execução na área de trabalho interativa pode interagir com essa janela. Isso expõe o serviço a qualquer aplicativo executado por um usuário conectado. Além disso, os serviços em execução como LocalSystem não devem acessar a área de trabalho interativa chamando a função OpenWindowStation ou GetThreadDesktop .
Para criar um serviço interativo, faça o seguinte ao chamar a função CreateService :
- Especifique NULL para o parâmetro lpServiceStartName para executar o serviço no contexto da conta LocalSystem.
- Especifique o sinalizador SERVICE_INTERACTIVE_PROCESS .
Para determinar se um serviço está em execução como um serviço interativo, chame a função GetProcessWindowStation para recuperar um identificador para a estação de janela e a função GetUserObjectInformation para testar se a estação de janela tem o atributo WSF_VISIBLE .
No entanto, observe que a seguinte chave do Registro contém um valor , NoInteractiveServices, que controla o efeito de SERVICE_INTERACTIVE_PROCESS:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Windows
O valor NoInteractiveServices assume como padrão 1, o que significa que nenhum serviço tem permissão para ser executado interativamente, independentemente de ter SERVICE_INTERACTIVE_PROCESS. Quando NoInteractiveServices é definido como um 0, os serviços com SERVICE_INTERACTIVE_PROCESS têm permissão para serem executados interativamente.
Windows 7, Windows Server 2008 R2, Windows XP e Windows Server 2003: O valor NoInteractiveServices assume como padrão 0, o que significa que os serviços com SERVICE_INTERACTIVE_PROCESS têm permissão para serem executados interativamente. Quando NoInteractiveServices é definido como um valor diferente de zero, nenhum serviço iniciado depois disso tem permissão para ser executado interativamente, independentemente de ter SERVICE_INTERACTIVE_PROCESS.
Importante
Todos os serviços são executados na sessão 0 dos Serviços de Terminal. Portanto, se um serviço interativo exibir uma interface do usuário, ele ficará visível apenas para o usuário que se conectou à sessão 0. Como não há como garantir que o usuário interativo esteja conectado à sessão 0, não configure um serviço para ser executado como um serviço interativo em Serviços de Terminal ou em um sistema que dê suporte à troca rápida de usuários (a alternância rápida de usuário é implementada usando os Serviços de Terminal).