Um Windows Service é um serviço do Windows, ou seja, uma aplicação que inicia quando o Windows é carregado e roda em segundo plano (background) enquanto o Windows estiver em execução, mesmo que você esteja na tela de login do Windows, pois ele fica residente na memória executando as operações na qual foi programado para fazer.

Esse tipo de serviço sempre roda em segundo plano do sistema operacional e são os responsáveis pelas tarefas essenciais, tais como: serviços de impressão, serviços de e-mail e etc.

Quando inicializados corretamente, os serviços do Windows podem ajudar a melhorar o desempenho de sua máquina. É possível acessar determinado serviço, desde que esteja sendo executado, e monitorar desempenho e quais serviços estão sendo executados naquele momento pela CPU. Existem muitos serviços que são conhecidos por todos como, por exemplo, o SQL Server, o Microsoft Exchange e aí por diante.

Veja também o Checklist Programador .NET que a DevMedia preparou para seus leitores.

Após a criação e construção do serviço, podemos instalá-lo e executá-lo e usar o Gerenciador de Serviços de Controle para os comandos ou realiza-los no Server Explorer ou no Service Controller, mas veremos tudo com mais detalhes adiante.

Os Windows services não estão disponíveis nas versões mais antigas do Windows; é preciso ter o Windows NT, Windows 2000, Windows XP, Windows Vista, Windows 7, Windows 8 ou Windows Server para rodar esses serviços.

Através da ferramenta Visual Studio podemos criar um aplicativo que vai ser instalado como um serviço, que deverá definir as instruções antes de compilar o projeto e instalar em determinada máquina. Mas antes de se criar um aplicativo Windows Service é necessário saber como manipular esses aplicativos e executar ações como, por exemplo, Inicializar, Pausar, Parar e Finalizar.

Todas essas ações podem ser desempenhadas via códigos dentro de nosso código fonte da aplicação, mas para quem não conhece um pouco de programação, elas podem ser acessadas através de algumas etapas que serão mostradas logo a seguir.

Precisamos saber antes de tudo que as classes de serviço do Windows suportadas pelo .NET Framework não permitem a interação com estações interativas, ou seja, um usuário conectado.

Um outro item importante é que o .NET Framework também não contém classes que representam estações e áreas de trabalho e, caso o seu serviço do Windows precise interagir com outras estações, vai ser preciso que você acesse a API do Windows não gerenciada.

Acessando os serviços do Windows

Antes de criar um novo serviço, vamos conhecer primeiramente a tela de serviços disponibilizada pelo Windows. Para acessar o Sistema Gerenciador de Serviços do Windows é necessário seguir alguns passos que vamos descrever a seguir.

Começaremos acessando o menu Iniciar e clicando em Painel de Controle > Desempenho e Manutenção. Em seguida vá em Ferramentas Administrativas > Serviços.

Há um outro caminho, bastando clicar em Iniciar e executar o comando (com Windows + R) services.msc, como mostrado na Figura 1.

Formulário
executar, acessado para encontrar e executar algum programa que contenha no Windows

Figura 1. Formulário executar, acessado para encontrar e executar algum programa que contenha no Windows.

Assim a tela de serviços do Windows exibirá a relação dos serviços executados com várias informações como, por exemplo; nome, descrição, Status, Tipo de inicialização e etc., como mostrado na Figura 2.

Tela
de serviços do Windows, acessado para visualizar, inicializar, pausar e
interromper serviços que estão sendo executados pelo sistema operacional

Figura 2.Tela de serviços do Windows, acessado para visualizar, inicializar, pausar e interromper serviços que estão sendo executados pelo sistema operacional.

Métodos OnStart e OnStop

Quando criamos um projeto no Visual Studio, podemos perceber que são implementados dois métodos ao nosso projeto vazio, que são os métodos OnStart e OnStop. Eles são responsáveis por executar e parar determinada ação de acordo com a instrução contida em cada método a partir de uma linguagem de programação. Mas antes, vamos entender um pouco a função de cada um desses métodos:


  • OnStart(); é chamada imediatamente após que se executa o projeto ou quando uma Activity que estava em background volta a ter foco;
  • OnStop(); é chamada quando a Activity fica completamente encoberta por outra Activity, utilizada para interromper um método que esteja sendo utilizado.

Regras Para a Criação do Serviço

Para criar um serviço, é necessário seguir algumas regras, como as apresentadas a seguir:


  • A propriedade ServiceName deve ser definida durante o processo de desenvolvimento;
  • Devemos criar instaladores para chamar determinado serviço;
  • Devemos codificar os métodos OnStart e OnStop, que se encontram vazios.

Uma observação importante: é necessário que antes de declarar essas três propriedades que declare o namespace System.IO.

Desenvolvendo um aplicativo Windows Service para arquivos de “log”

Um windows service não provê meios de interação com o usuário. E irá reportar o resultado e os seus eventos ao usuário através de mensagens no evento log. Essa versão que iremos utilizar já possui algumas classes que incluem algumas funcionalidades para criarmos um Windows Service e essas classes estão sob o namespace System.ServiceProcess. Todo Windows Service roda com a permissão de algum usuário, independente dos usuários ou programas que estão rodando no mesmo computador, ou seja, estas aplicações rodam sob uma identidade de segurança, não necessariamente a que está ligada na máquina no momento. O Visual Studio .NET oferece um template de projeto que automaticamente será a referência para este namespace e também provém alguns códigos de exemplo, mas não será necessário.

Antes de começarmos um novo projeto, vamos entender e aprofundar um pouco mais nosso conhecimento em algumas propriedades dessas classes. A ServiceBaseClass fornece uma classe base para um serviço e pertence a System.ServiceProcess namespace que fornece diversas classes, permitindo instalar, implementar, monitorar os vários aplicativos dos serviços.

A ServiceBase Class possui algumas propriedades, que são as seguintes:


  • AutoLog; esta propriedade é setada para True nos eventos de iniciar, parar, pausar e continuar. Entrará com o registro no Windows Application Evento Log;
  • CanHandlePowerEvent; nesta propriedade, quando estiver com o valor igual a True poderá ser editado um código customizado para o OnPowerEvent. Permitindo executar algumas ações especiais;
  • CanPauseAndContinue; quando o valor estiver True, esta outra propriedade permite que o serviço seja pausado;
  • CanShutdown; já nesta propriedade o valor True permite escrever um código customizado para o método OnShutDown;
  • CanStop; normalmente, o valor desta propriedade é setado para True e permite que o serviço possa ser parado;
  • EventLog; se o AutoLog estiver setado para True, a mensagem será escrita pelo Windows Application Event Log. Se setado para False, poderá ser especificado uma mensagem customizada;
  • ServiceName; esta propriedade seta ou retorna o nome do serviço.

Essa classe também possui alguns métodos, que são os seguintes:

  • OnContinue; este método é usado para continuar rodando o serviço depois que ele for pausado;
  • OnCustomCommand; este outro método é usado quando é necessário implementar ações customizadas pelo objeto ServiceController;
  • OnPause; este método roda quando existir a necessidade de pausar o serviço;
  • OnPowerEvent; este outro método é chamado quando o status de energia do computador for alterado;
  • OnShutdown; este método roda antes do computador ser desligado;
  • OnStart; o código contido neste método roda quando o serviço é inicializado;
  • OnStop; o código implementado neste método roda quando o serviço for parado;
  • OnStop: Esse método é executado quando o comando Stop é acionado;
  • CanHandleSessionChangeEvent: Recebe um boolean determinando se o serviço pode obter eventos de mudança de sessão de um Terminal Server;
  • Run: Esse método é estático e é executado no evento Main da aplicação. Ele tem dois overloads: um recebe uma instância da classe ServiceBase e o outro recebe um array de instâncias da classe ServiceBase. Sua finalidade é iniciar o(s) serviço(s). Caso você esteja utilizando o modelo de projetoServiços do Windows, o método run vai ser gravado automaticamente para você.É importante destacar que carregar um serviço não significa a mesma coisa que iniciá-lo.

Vamos utilizar também a Classe ServiceInstaller, responsável por instalar um serviço, ou seja, uma classe que implementa a classe ServiceBase. Essa é chamada quando o serviço está sendo instalado. Abaixo seguem apenas algumas de suas principais propriedades:


  • Description; esta propriedade recebe uma string contendo a descrição do serviço. Essa descrição é visualizada no SCM;
  • DisplayName; esta outra propriedade recebe uma string onde é definido o nome do serviço;
  • ServiceName; esta serve para indicar ao Windows o nome do serviço. Essa string deve ser exatamente igual à propriedade ServiceName da classe ServiceBase do serviço a ser instalado;
  • StartType; indica como o serviço será iniciado. Essa propriedade recebe uma das três opções do enumerador ServiceStartMode que são os seguintes: Automatic, disabled e manual.

Vamos entender um pouco sobre as opções do enumerador ServiceStartMode:


  • Automatic; o serviço é iniciado automaticamente quando o Windows é iniciado;
  • Disabled; o serviço fica desabilitado não podendo ser inicializado pelo usuário ou pelo Windows;
  • Manual; O serviço deve ser iniciado pelo usuário.

Ao se desenvolver um serviço, devemos saber que existem dois tipos de serviços que podem serem criados no Visual Studio usando o .NET Framework: o primeiro tipo é o Win320wnProcess, para serviços que são o único serviço em processo; e o segundo tipo é o Win32ShareProcess, para serviços que dividem um processo com outro serviço.

Podem ser criados outros tipos de serviços, porém fora do Visual Studio.

Bom, agora que conhecemos um pouco mais sobre a classe que utilizaremos no desenvolvimento dessa nova aplicação, vamos aprimorar o que acabamos de conhecer colocando tudo na prática. Não será necessário trabalhar com todos os métodos nem todas as propriedades que foram citadas acima. Para criar nossa aplicação de arquivos de log vamos utilizar apenas algumas e criarmos uma nova aplicação Windows Service, esse para gravar log em arquivos.

Criação do Serviço

Vamos abrir o Visual Studio e clicar em New Project -> Windows, como mostrado na Figura 3.

Tela
do Visual Studio para criação de um novo projeto.

Figura 3.Tela do Visual Studio para criação de um novo projeto.

Logo em seguida, vamos escolher a opção Windows Service: é necessário definir um nome a esse projeto e escolher um local para guardar esse arquivo. Vamos criar uma variável global, fora de qualquer método, do tipo da classe StreamWriter, que será nosso arquivo de log. Use o seguinte código:

StreamWriter arquivoLog;

Sempre que se desenvolve uma aplicação Windows Service são criados no projeto aqueles dois métodos principais: o "OnStart" e o "OnStop”. Primeiramente, vamos então codificar o método OnStart com o código presente na Listagem 1. Repare que a variável que acabamos de criar receberá como parâmetro o caminho que será o log deste evento do serviço

Listagem 1.Método OnStart

protectedoverridevoid OnStart(string[] args)
  {
  arquivoLog = newStreamWriter(@"C:\\testandlog.txt", true);
  arquivoLog.WriteLine("Serviço iniciado em: " + DateTime.Now);
      arquivoLog.Flush();
  }

Com a linha que atribuiremos dentro do método OnStop, o arquivo será escrito no momento exato que for finalizado e, logo em seguida, vamos fechar o arquivo usando o método Close(). Veja a codificação do Método OnStop na Listagem 2.

Listagem 2. Método OnStop

protectedoverridevoid OnStop()
  {
      arquivoLog.WriteLine("Serviço encerrado em : " + DateTime.Now);
      arquivoLog.Close();
  }

Se mandarmos executar o projeto não irá acontecer absolutamente nada em nossa máquina. Precisamos instalá-lo e iniciá-lo para que o mesmo entre em ação e para isso é necessário que antes se crie um instalador para aquele serviço. Quando você iniciar seu serviço ou quando o sistema operacional for inicializado, irá ser criado um arquivo com o nome de testeLog.txt, que já terá uma linha escrita com a hora em que o serviço foi iniciado.

Depois que um serviço é iniciado, ele vai permanecer ativo até que seja interrompido ou parado manualmente. E esses serviços podem ser configurados para serem inicializados automaticamente, quando o computador é reiniciado ou ligado pela primeira vez após sua instalação, ou também pode ser iniciado manualmente.

Adicionando uma Conta de Sistema

Ao instalar um serviço, o Windows usa um contexto que é o de determinar quais privilégios este serviço vai poder e deverá usar, por isso precisamos incluir em nosso projeto uma conta de sistema, que será o contexto que o Windows necessita para instalar o serviço. Os tipos de contas existentes são as seguintes:


  • Local Service: é a conta que direciona o Windows para rodar o serviço no contexto de uma conta no sistema local que pode ter privilégios estendidos;
  • Network Service: direciona o Windows para rodar o serviço no contexto de uma conta sem privilégios no sistema local. O serviço apresentará as credenciais a um servidor remoto (usado com vários computadores em uma rede, por exemplo);
  • Local System: é a conta que direciona o Windows para rodar o serviço no contexto de uma conta sem privilégios no sistema local. O serviço apresentará credenciais anônimas para o servidor remoto;
  • User: esta outra conta direciona o Windows para rodar o serviço no contexto que solicita ao usuário um nome e senha válidos a cada momento que o serviço rodar.
  • Nessa aplicação iremos usar a conta Local System e teremos que seguir alguns passos para configurar nossa aplicação:
  • Primeiramente, pressione a tecla F4 em cima do serviceInstaller1 e vamos alterar as propriedades DisplayName e ServiceName para ExemploServico, que será o nome do nosso serviço que será exibido no gerenciador de serviços;
  • Agora pressione novamente a tecla F4 em cima do serviceProcessInstaller1 e altere a propriedade Account para Local System, que será o tipo de conta que explicamos anteriormente. Vamos compilar nossa aplicação apertando CTRL + SHIFT + B.

Em seguida, para instalarmos nosso serviço, teremos que usar o InstallUtil, um utilitário específico do .NET para instalar serviços no Windows. Ele se encontra na pasta do .NET Framework.

Então, vá em Iniciar e clique em Executar e digite cmd para abrirmos o prompt de comando do MS-DOS. Nele digite cd\ para irmos à raiz de nossa unidade. Ao ser digitado o comando 'cd' + o caminho para se chegar a pasta em que está meu utilitário InstallUtil, na linha de baixo digitei o nome do arquivo logo em seguida pressione Enter. Será apresentada logo em seguida uma lista de opções deste utilitário.

Para instalarmos nosso serviço, temos que ir a pasta em que o mesmo foi compilado, dentro da pasta Debug, que por sua vez fica dentro da pasta Bin, localizada dentro da pasta do seu projeto do Visual Studio, que nesse exemplo é a ExemploWindowsService. Dentro desta pasta arraste o executável para a janela de comando, não podendo esquecer de digitar installutil antes do caminho do arquivo. Seu prompt deverá ficar conforme mostrado na Figura 4.

Tela
de nossa aplicação no momento que é instalado o serviço no Windows a partir da
descrição feita anteriormente

Figura 4. Tela de nossa aplicação no momento que é instalado o serviço no Windows a partir da descrição feita anteriormente.

Agora com a aplicação criada, caso queira inicializá-la, basta ir ao Gerenciador de Serviços e procurar pelo nome de seu serviço. Quando você encontrar, clique com o botão direito em cima do serviço e por último clique em Iniciar, como foi mostrado na Figura 5.

Tela
de Gerenciador de Serviços do Windows com a aplicação recém criada pronta para ser
inicializada

Figura 5.Tela de Gerenciador de Serviços do Windows com a aplicação recém criada pronta para ser inicializada.

Depois de inicializado nosso serviço vamos agora verificar se ele foi executado corretamente: então basta ir em C: ->testeLog.txt que foi o arquivo criado no serviço, conforme mostrado na Figura 6.

Tela
do arquivo .txt criado a partir do serviço Windows Service com a data e hora
que o aplicativo foi finalizado

Figura 6.Tela do arquivo .txt criado a partir do serviço Windows Service com a data e hora que o aplicativo foi finalizado.

O Windows já disponibiliza vários serviços para satisfazer as diversas necessidades da máquina e garantir que ela funcione corretamente, mas agora de uma forma simples entendemos como funciona e também como criar um serviço do Windows e que não é complicado o desenvolvimento de um serviço de acordo com sua própria necessidade. Esses serviços, embora o usuário não perceba sua execução, são essenciais para o bom funcionamento da máquina e facilita o monitoramento da mesma.

Os serviços bem desenvolvidos funcionam perfeitamente em sintonia com o sistema operacional, e existem alguns serviços que são inicializados para que o sistema operacional possa ser executado, então é extremamente importante relembrarmos que é essencial que quando se desejar excluir algum serviço do Windows por não estar sendo muito utilizado, confira sua relevância no sistema, para que não se comprometa o funcionamento de algo ou que depois faça alguma falta ou, caso você deseje recuperá-lo, dependendo do tipo do serviço, não haverá mais maneiras de recuperá-lo.

Alguns pontos são importantes de se destacar quando se tratada criação de uma aplicação do Windows Service:


  1. Deve-se levar em conta que devemos sempre evitar usar qualquer tipo de interface com o usuário, já que o serviço é feito exclusivamente para ser rodado em segundo plano “background”, ou seja, totalmente oculto da visão do usuário;
  2. Para visualizar esses serviços é necessário acessar o Gerenciador de Serviço do Windows;
  3. Não é necessário um banco de dados para se criar um serviço;
  4. Antes de testar qualquer serviço criado, é necessário primeiramente adicionar um instalador.

Bom, espero que tenham gostado desse artigo. Bom desenvolvimento a todos e até a próxima.