Desenvolvimento - ASP. NET
Turbinando ASP.NET com Windows Services
A idéia deste artigo, é demonstrar as novas possibilidades vislumbradas em uma solução desenvolvida na plataforma .net, com a facilidade de criação dos Windows Services.
por Marco Aurélio Péres1. Abstração
A idéia deste artigo, é demonstrar as novas possibilidades
vislumbradas em uma solução desenvolvida na plataforma .net, com a facilidade de
criação dos Windows Services.
É aconselhável que o leitor tenha um
conhecimento mínimo sobre aplicações Web.
Não se assuste com o tamanho do artigo, ele
está bem separado e didático.
Tenho certeza que você vai gostar, e durante a
leitura você terá a oportunidade de criar seu primeiro Windows Service (caso
nunca tenha criado).
Conteúdo:
- Novos limite dados às
aplicações Web
- Conceito de solução
- Windows Services
- Criando
Windows Service
- Instalando o Windows Service
- Testando o Windows
Service
- Sumário
2. Novos limites dados às aplicações Web
Hoje vemos várias empresas, inclusive multi-nacionais, migrando
suas aplicações desktop para aplicações em ambiente Web.
Queria dizer que as
vantagens são inúmeras:
1 – Trata-se de uma solução Thin-client, ou seja, o
computador cliente não precisa ter grandes recursos, pois a aplicação é
“executada” no servidor, como um “terminal burro” um pouco mais inteligente,
pois temos um processamento de scripts no cliente.
2 – A manutenção da
aplicação, isto é, a instalação de novas versões fica muita mais simplificada e
rápida, pois novamente, a aplicação está instalada e sendo executada no
servidor, portanto, apenas 1 local requer alteração.
Poderia ficar
durante todo o artigo, enumerando as vantagens que uma aplicação Web tem sobre
uma desktop, inclusive econômicas, mas também é importante citar 2 pontos
fracos.
1 – Interface gráfica e usabilidade.
Até antes da
chegada da plataforma .net + Visual Studio .net (VS.net), as aplicações Web
sofriam por ter interfaces “feias, cinzas e etc..”, além de não ter controles
ricos como as aplicações Desktop (Visual Basic, Delphi, etc…)
possuiam.
Com isto, o resultado era um site difícil de ser operado, e que
muitas vezes tornava o trabalho do usuário um pouco mais lento.
Este
problema já passa a ser resolvido com a chegada da nova frente de tecnologias
ASP.net, incluindo Server Controls, UserControls, Caching, Automatic Browser
Detection, entre outros.
Portanto, interface gráfica e usabilidade
deixam de ser problemas.
2 – Ciclo de vida natural de aplicações
Web.
Toda aplicação Web roda sobre os protocolo TCP/IP e HTTP, que formam
um cenário, digamos, desconectado e que não mantém estado sobre os
usuários.
Podemos dizer que a aplicação Web fica “parada” no servidor, até
que algum cliente efetue uma requisição http , digitando
http://url_da_aplicacao.
Apartir deste momento, o servidor é acionado e
começa a processar sua requisição até montar a página de resposta (html,scripts
de cliente,imagens e etc..).
Quando a resposta é enviada, o servidor volta ao
seu estado normal (stand by) até chegar outra requisição e o ciclo de ser
re-iniciado.
Novamente, a plataforma .net chegou para ajudar a resolver
estes problemas.
Em relação ao protocolo sem estado, temos o recurso de
ViewState do ASP.net, que sem nos aprofundarmos (por não ser o foco deste
artigo), podemos dizer que resolve este problema.
Agora, temos um
problema crítico sobre o ciclo de vida natural das aplicações web,
concedido pelos protocolos TCP/IP e HTTP, o que vou discutir no próximo
tópico.
Quero agora passar o conceito de uma solução, envolvendo vários
projetos dependentes entre si.
3. Conceito de Solução
Os projetos web estão ficando cada vez mais complexos, então,
deixamos de ter simplesmente páginas ASP sendo executadas, e dizemos que temos
uma solução.
Se pegarmos uma visão geral (big picture) de um completo projeto
Web, teremos o que chamamos de “Solução”, pois pode envolver:
- Interface
visual com páginas asp.net.
- Segunda opção de Interface visual concedida por
smart devices.
- Regras de negócio em .net Serviced Components gerenciados
pelo COM+
- Regras de negócio compartilhadas em XML Web Services
- Fonte
de dados heterogêneas, isto é, parte em SQL Server, outra em Oracle e outros
dados de sistemas legados.
- Enterprise Services paralelos que permitem a
integração de uma nova aplicação com sistemas legados. Tal serviço é facilmente
realizado com o Microsoft Biztalk Server, que tem como transporte de dados, o
XML.
- Agentes computacionais que devem ficar monitorando toda a solução
durante 24 horas, por uma série de motivos.
Acho que agora está
claramente visível o motivo do nome Solução, pois existem tantos elementos que
precisam trabalhar juntos, para formar o que os nossos usuários, leigamente,
chamam de “Este aqui é o programa da empresa”.
Eles não fazem
idéia da estrutura que está montada por trás para dar a eles o resultado
esperado.
Na listagem de elementos que uma solução pode ter (obviamente
não citei todos), dei um destaque ao último.
“Agentes computacionais
que devem ficar monitorando toda a solução durante 24 horas, por uma série de
motivos.”
Muitos sistemas precisam ser monitorados 24 horas por
dia, por uma série de motivos, sendo técnicos ou simplesmente por fazerem parte
da regra de negócio da empresa.
Obviamente, você não vai criar uma
solução deste tamanho e obrigar que tenha uma pessoa, ou pior, uma equipe de
pessoas que fique 24 horas olhando para monitores para ver se algo ruim
acontece. Isto simplesmente não existe!
E é ai que o ciclo de vida
natural das aplicações Web não nos dá o suporte desejado, isto é, a aplicação
fica por padrão “parada”, e só é “iniciada” quando existe uma requisição.
Não
existe um recurso em uma aplicação Web que fique sendo executado sempre, 24
horas por dia.
Para contornar este problema, algumas pessoas (eu por
exemplo, já fiz isso..) criam Stored Procedures e agendam Jobs no SQL
Server. Este método até que resolve, mas muitas vezes, pode ser encarado como um
“recurso técnico” (para não dizer outra coisa), porque além de tornar a sua
aplicação 100% dependente do SQL Server, você está colocando sua regra de
negócio em um banco de dados, o que na maioria dos casaos não é muito
legal.
Outros, criam uma aplicação em paralelo e utilizam até o
Agendador de Tarefas do windows para executá-los.
Sabemos que isto
também funciona, mas quanto mais longe você vai, mais passível de erros sua
aplicação fica, sem falar da manutenção.
Novamente, a plataforma .net
está ai para nos ajudar a resolver os problemas de maneira
profissional.
Você pode facilmente encapsular toda a regra do agente
computacional em um Windows Service.
Nos próximos tópicos, espero
conseguir convencê-lo de que esta é a maneira mais profissional, e relativamente
rápida de resolver este problema.
4. Windows Services
Apenas os usuários do Windows NT, Windows 2000, 2003 , Longhorn
e geralmente, pessoas técnicas conhecem os Windows Services.
Trata-se de
“programas” que são executados em “background” no sistema operacional.
A
grande vantagem desses “programas”, é que eles não precisam ser executados por
algum usuário, ou seja, quando você liga o computador, ele começa a ser
executado e pode fazer qualquer tarefa como um outro aplicativo no
sistema.
Mas você pode me perguntar..
Mas como ele é executado sem
ninguém dar 2 cliques no “.exe” dele ? Ou ainda mais, quais são as permissões
que ele terá?
É simples, basta pensar em um SQL Server.. nenhum
administrador de rede dá um duplo clique em um arquivo “sqlserver.exe”, e sim,
ele “inicia”(no jargão apropriado, diríamos, “startar o SQL Server”) o serviço
SQL Server.
Podemos pensar logicamente, no seguinte…”tudo que inicia,
pode ser parado, ou até pausado, e se, pode ser pausado, pode ser então,
continuado”.. simples como um CD Player.
Quanto à segunda pergunta, faz
sentido perguntar qual permissão ele terá.. o que ele pode fazer ??
Todo
Windows Service é executado no contexto de uma conta Windows e isso é facilmente
configurado utilizando as próprias ferramentas do sistema
operacional.
Para acessar o gerenciador de serviços do Windows, acesse o
menu
Start -> Programs -> Administrative Tools -> Services,
trata-se de um snap-in do MMC (Microsoft Management Console), o que torna a
administração mais fácil.
(Figura 1: Janela gerenciadora dos Windows Services
exibindo os serviços do computador local)
Neste snap-in, você irá
visualizar a lista de todos os serviços instalados no sistema operacional, com o
auxílio de 5 colunas.
Coluna | Descrição da Coluna |
Name | Nome do serviço. |
Description | Descrição do serviço. |
Status | Significa o estado atual do serviço. Pode estar [“” = Serviço não iniciado, “Started” = Serviço sendo executado, “Paused” = Serviço paradao] |
Statup Type | Significa a maneira como este serviço é iniciado, quando o Windows é iniciado. Pode estar [“Automatic”= sempre que o Windows iniciar, este serviço será iniciado, ”Disabled”= este serviço nunca será iniciado,”Manual”=este serviço só será iniciado quando o administrador inicia-lo.] |
Log On As | Quer dizer as credenciais que o serviço terá para executar suas ações no
sistema. Estas credenciais podem ser mínimas ou até máximas, dependendo do tipo
de serviço. Ele tem 3 opções: “Local System Account”= Quer dizer que o serviço vai ser executado como se fosse o próprio sistema operacional, isto é, NÃO EXISTE RESTRIÇÃO DE SEGURANÇA, obviamente no escopo da máquina local. Porém se este serviço estiver sendo executado com estas permissões sobre um Domain Controller, quer dizer que o serviço terá permissões sobre todo o domínio. “Local Service Account”= O serivço será executado com as permissões da conta built-in do Windows, chamada NT AUTHORITY\Local Service . Esta conta possui os mesmos recursos que o grupo de usuário Users possui, ou seja, um acesso restrito. Isto ajuda a manter seu OS seguro. Se o serviço instalado tentar acessar recursos da rede, ele estará acessando como se fosse uma sessão nula, sem credenciais, o que quer dizer com bem menos permissões. “Network Service Account”= Funciona da mesma maneira que o Local Service Account, porém é executado no contexto da conta NT AUTHORITY\Network Service, e, quando acessa algum recurso da rede, ele utilizará as credenciais do computador no qual ele está instalado. Obs.: Tanto em Local Serice Account quanto em Network Service Account, você pode especificar uma conta de usuário do Windows, porém o valor da coluna Log On As será o nome do usuário que você configurou. Ex.: .\Administrator quando o serviço for ser executado na conta Administrator do computador local. |
Será interessante e muito valioso se você acessar as propriedades de um Windows Service, bastanto para isso, clicar com o botão direito e ir na opção Properties.
O gerenciamentor dos Windows Services é muito interessante, porém o foco deste artigo é como cria-los e não gerencia-los.
5. Criando Windows Services
Se você é desenvolvedor de Visual Basic (6.0 para trás), isto é
novo para você, porque agora você também pode criar Windows Services utilizando
sua linguagem preferida, o Visual Basic .net.
Antigamente, era necessário
o uso de ferramentas de terceiros, para criar Windows Services, o VB não dava
este suporte.
Neste tópico, criaremos um Windows Services do
zero!
1º Passo -> Abra o Visual Studio .net
2º Passo
-> File -> New Project
3º Passo -> Selecione sua
linguagem preferida (qualquer uma que seja CLS-.net Common Language
Specification Compliant)
4º Passo -> Selecione o tipo de projeto
Windows Service, preencha o nome com MeuServiceDotNet
(Figura
2: Janela de criação de projetos do VS.net.Tipo de projeto: Windows
Service) Neste momento, o VS.net criará para você o arquivo
Service1.vb.
Note que ele não tem interface gráfica, óbvio, pois é um
código que será executado no background do seu sistema operacional.
Repare
também que a janela Toolbox está habilitada e você tem, como principal
Tab, a Components, porque ali estão ricos controles que encaixam muito
bem com as tarefas que um Windows Service pode precisar, como por
exemplo:
FileSystemWatcher | Você pode com este controle, especificar uma pasta, e dizer para executar
determinada ação caso algum arquivo seja alterado, deletado, inserido, e você
ainda pode especificar os Wildcards para o arquivo, por exemplo… *.txt, ou
PEDIDO*.txt.. Muito interessante e fácil de ser usado. |
EventLog | Já pensou em escrever entradas no Log de Eventos do próprio OS ?!?!? Agora estamos ficando profissionais, com poucos cliques, você adiciona entradas. |
DirectoryEntry e DirectorySearcher | Este é muito bom, permite manipular serviços de diretório, assim como o Active Directory da Microsoft. Para aplicações distribuídas e complexas, vez e outra, você vai encontrar essa necessidade. |
Timer | Este é muito interessante, é como o velho Timer do Visual Basic e de outras linguagens visuais. Você determina o intervalo em que ele deve ser acionado, quando atingir este período, um procedimento de evento é acionado e você pode colocar sua regra lá dentro. |
Vamos acessar as propriedades deste Service1.vb, pressione F4 ou acesse o menu View -> Properties Window. Na tabela abaixo você as identificará e saberá seu significado e aplicação.
Com exceção da ServiceName, todas elas são Booleanas, isto é, True ou False.
AutoLog | Esta propriedade informa ao Windows, para escrever entradas no EventLog, quando eventos normais acontecerem, por exemplo, quando este serviço é iniciado, pausado, continuado, parado e etc.. Não é o melhor dos feedbacks não, mas já ajuda a saber o comportamento do seu serviço. |
CanHandlePowerEvent | Quando existem variações no gerenciamento de energia do computador, o
Windows possui um recurso de avisar aos serviços sobre a mudança de status de
energia. Nesta propriedade você define se deseja que seu serviço seja
acionado. Se colocar como True, você deverá implementar a Function OnPowerEvent. Caso esta propriedade esteja como True e você não tiver implementado a Function, o OnPowerEvent da classe pai, ou seja, ServiceBase() será chamada, mas ela não executa nada. Exemplo de aplicação seria você adiconar um código que salva algumas informações na sua fonte de dados, apenas por segurança. Sobre uma eventual queda de energia. |
CanPauseAndContinue | Como o próprio nome diz, determina se o usuário, talvez o administrador do sistema, poderá dar um “Pause” no seu serviço. Muitas vezes, não é interessante dar este controle ao usuário. |
CanShutdown | Da mesma maneira que o Windows avisa quando há uma variação no gerenciamento
de energia, o Windows também avisa quando está sendo desligado. Se a propriedade CanShutDown estiver como True, o Windows avisará o serviço quando do desligamento, e será chamada a Sub OnShutDown. Podemos fazer uma analogia ao Application_OnEnd() do global.asax |
CanStop | se esta propriedade estiver True, o usuário poderá “Parar” seu serviço. Caso contrário, ele não poderá. |
ServiceName | Este é o nome que o Windows trata o serviço. |
Em algumas propriedades, você pode estar se perguntando, mas porque eu iria querer impedir o usuário de dar um “pause” ou “stop” no meu serviço ??
A razão é simples, tudo depende da importância que este serviço apresenta para sua solução como um todo.
Imagine por exemplo, se o service Remote Procedure Call (RPC) pudesse receber um “pause” ou “stop”? Seria uma loucura, simplesmente seu Windows começaria dar erros e erros.
Portanto, é de extrema importância ter um bom senso na criação de Windows Services.
No nosso exemplo, vamos criar um serviço que ficará monitorando uma determinada pasta, esperando por arquivos com a extensão .txt.
Quando este arquivo for criado, nós vamos escrever uma entrada no EventLog.
Também vamos brincar um pouco com o Timer, pois criaremos a regra de que a cada 4 minutos, é esperado que pelo menos 1 arquivo seja recebido, caso contrário será adicionada outra entrada no EventLog.
5º Passo -> Coloque as seguintes propriedades:
AutoLog = False
CanHandlePowerEvent = False
CanPauseAndContinue = True
CanShutdown = False
CanStop = True
ServiceName = “DetArquivosDotNet”
6º Passo -> Vá para o código, pressioinando F7 ou pelo menu View -> Code
Observe o seguinte código
Imports System.ServiceProcess
Public Class Service1
Inherits System.ServiceProcess.ServiceBase
#Region " Component Designer generated code "
...
#End Region
Protected Overrides Sub OnStart(ByVal args() As String)
End Sub
Protected Overrides Sub OnStop()
End Sub
End Class
Imports System.ServiceProcess
Este namespace possui classes que permitem a implementação e controle de Windows Services. Além do que, a classe base para serviços está neste namespace, é a ServiceBase().
Public Class Service1 Inherits System.ServiceProcess.ServiceBase
É necessário herdar a classe ServiceBase(), pois ela possui todos os métodos responsáveis pelo comportamento do serviço.
Por padrão, o VS.net já deixa criado 2 métodos, o OnStart e OnStop, ambos explicados anteriormente.
7º Passo -> Criar os outros métodos para termos o comportamento total do serviço.
Va até a barra com 2 dropdowns que exibe, classes e seus membros.
(Figura 3: Visualização da barra de classes[vermelha] e membros da classe[azul])
Seleciona a opção (Overrides) abaixo do item Service1 na barra de classes, e clique nas seguintes opções na barra de membros.
1 – OnContinue
2 – OnPause8º Passo -> Vá para o design pressionando Shift + F7 ou View -> Designer
Va até a Toolbox, arraste os seguintes controles da Tab Components e preencha suas respectivas propriedades, de acordo com a tabela abaixo.
1 – FileSystemWatcher
EnableRaisingEvents | False |
Filter | *.txt |
NotifyFilter | CreationTime |
Path | C:\MeuServicoDotNet |
2 – EventLog
EnableRaisingEvents | False |
Log | Application |
MachineName | . |
Source | MeuServicoDotNet |
3 – Timer
AutoReset | True |
Enabled | False |
Interval | 240000 (4 minutos ou 240.000 milisegundos) |
Não é possível, explicar todas as propriedades destes controles neste artigo, por não ser o foco principal, e depois, acabariamos criando um eBook, ao invés de artigo. :-))
9º Passo -> Vá para o código pressionando F7 ou View -> Code
Você terá que alterar seu código para deixar como o meu abaixo.
Observe os comentários
Imports System.ServiceProcess Public Class Service1 Inherits System.ServiceProcess.ServiceBase #Region " Component Designer generated code " ... #End Region Shared Sub Main() Dim ServicesToRun() As System.ServiceProcess.ServiceBase " Change the following line to match. ServicesToRun = New System.ServiceProcess.ServiceBase() _ {New Service1} System.ServiceProcess.ServiceBase.Run(ServicesToRun) End Sub Private bolArquivoCriado As Boolean = False Private datUltimoArquivoCriado As DateTime = Nothing Protected Overrides Sub OnStart(ByVal args() As String) "Ativando o Timer Timer1.Enabled = True "Ativando o FileSystemWatcher FileSystemWatcher1.EnableRaisingEvents = True "Escrevendo no EventLog que o serviço foi iniciado AdicionaEntradaLog("Atenção: Serviço Detector de " _ & "Arquivos .NET foi iniciado!") End Sub Protected Overrides Sub OnStop() "Desativando os controles de Temporizador e FileSystemWatcher Timer1.Enabled = False FileSystemWatcher1.EnableRaisingEvents = False AdicionaEntradaLog("Atenção: Serviço Detector " _ & "de Arquivos .NET foi parado!") End Sub Protected Overrides Sub OnContinue() Timer1.Enabled = True FileSystemWatcher1.EnableRaisingEvents = True bolArquivoCriado = False AdicionaEntradaLog("Atenção: Serviço Detector " _ & "de Arquivos .NET foi re-iniciado!") End Sub Protected Overrides Sub OnPause() "Desativando os controles de Temporizador e FileSystemWatcher Timer1.Enabled = False FileSystemWatcher1.EnableRaisingEvents = False AdicionaEntradaLog("Atenção: Serviço Detector de Arquivos .NET " _ & "foi parado temporariamente (Pause)!") End Sub Public Sub AdicionaEntradaLog(ByVal parMensagem As String) "Esta sub foi criada para centralizar o acesso ao EventLog. "Apenas para facilitar a futura manutenção EventLog1.WriteEntry(parMensagem) End Sub Private Sub FileSystemWatcher1_Created(ByVal sender As Object, _ ByVal e As System.IO.FileSystemEventArgs) Handles FileSystemWatcher1.Created AdicionaEntradaLog("Atenção: Arquivo criado na pasta " _ & FileSystemWatcher1.Path & "." & vbNewLine & "Nome do Arquivo: " & e.FullPath) bolArquivoCriado = True datUltimoArquivoCriado = DateTime.Now() Timer1.Enabled = True End Sub Private Sub Timer1_Elapsed(ByVal sender As Object, _ ByVal e As System.Timers.ElapsedEventArgs) Handles Timer1.Elapsed If bolArquivoCriado = False Then If datUltimoArquivoCriado = Nothing Then "No caso de nenhum arquivo ter sido criado AdicionaEntradaLog("Atenção:Nenhum arquivo criado no " _ & "intervalo de " & CType((Timer1.Interval / 60000), String) _ & " minutos." & vbNewLine & "Nenhum arquivo criado desde que o serviço foi iniciado.") Else "No caso de algum arquivo já ter sido criado AdicionaEntradaLog("Atenção:Nenhum arquivo criado no intervalo de " _ & CType((Timer1.Interval / 60000), String) & " minutos." & vbNewLine _ & "Data do último arquivo criado: " & datUltimoArquivoCriado.ToString) End If End If "Colocando o valor iniciado da flag que diz que um arquivo foi criado no período do Timer bolArquivoCriado = False End Sub End Class
6. Instalando Windows Service
Após ter criado o Windows Service, será necessário criar um instalador do serviço.
Graças ao VS.net, esta tarefa é bem simplificada.
1º Passo -> Vá até o design pressionando Shift F7 ou View -> Designer.
2º Passo -> Clique com o botão direito sobre a área de trabalho e clique na opção “Add Installer”.
Ao efetuar o segundo passo, repare que o arquivo ProjectInstaller.vb foi criado.
O objetivo deste arquivo é manter as classes de serviço que serão responsáveis por instalar o serviço, podendo já deixar valores padrões de configuração, para que a instalação seja a mais rápida o possível, sem o administrador ter que acessar o Gerenciador de Serviços.
3º Passo -> Repare que neste arquivo, existem 2 controles criados:
1 –ServiceProcessInstaller1
Este controle manterá as configurações sobre a autenticação do serviço no sistema. Pode guardar o tipo de conta (.Account = [Enumeração ServiceAccount]), o usuario (.Username) e a senha (.Password)
2 - ServiceInstaller
Este controle manterá as configurações de StartupType e ServiceName do serviço, acessíveis pelas propriedades StartType (Enumeração ServiceStartMode) e ServiceName respectivamente.
Estas propriedades devem ser preenchidas, portanto pressione F4.
ServiceProcessInstaller1
Account | LocalSystem |
ServiceInstaller1
StartType | Manual |
DisplayName | Detector de Arquivos .NET (Este nome é exibido no gerenciador de serviços, de acordo com a figura 1) |
ServiceName | DetArquivosDotNet |
Nota Importante: A propriedade “ServiceName” do controle ServiceInstaller1 deve ser idêntica à propriedade “ServiceName” do Windows Service que você está criando.
A propriedade “DisplayName” serve apenas para ser um nome mais amigável.
Ufa! Depois de tudo isso preparado, estamos realmente prontos para instalar o serviço.
Vamos lá!Falta pouco.
4º Passo -> Compile seu projeto utilizando o modo “Release”, por questões de performance. Para compilar use Ctrl + Shit + B ou pelo menu Build -> Build Menu.
5º Passo -> Vá até a pasta do seu projeto e acesse o diretório obj\Release. Copie o arquivo MeuServiceDotNet.exe e cole-o na pasta C:\MeuServiceDotNet.
6º Passo -> Agora você irá chamar o instalador propriamente dito, o nome da fera é “InstallUtil.exe” e está localizado no caminho
“X:\%Windows Folder%\Microsoft .NET\Framework\v1.1.4322\InstallUtil.exe”.Você precisa chamar este executável passando o caminho do MeuServiceDotNet.exe.
Para isso, existem 2 opções:
1º - Chamando o Prompt de comando normal
Start -> Run
Digite “cmd”
Digite “cd X:\%Windows Folder%\Microsoft .NET\Framework\v1.1.4322”
Digite “InstallUtil.exe “C:\MeuServicoDotNet\MeuServiceDotNet.exe” ”
Digite “Exit”
2º - Chamando o Prompt de comando do VS.net
Start -> Programs -> Visual Studio .net 2003 -> Visual Studio .net Tools -> Visual Studio .net 2003 Command Prompt
Digite “InstallUtil.exe “C:\MeuServicoDotNet\MeuServicoDotNet.exe” ”
Digite “Exit”
Para desinstalar o serviço, execute o InstallUtil.exe, porém passando o switch “/u”.
InstallUtil.exe /u “C:\MeuServicoDotNet\MeuServiceDotNet.exe”
Ao chamar o InstallUtil.exe, ele verificará se as classes ServiceProcessInstaller já está com as propriedades Username e Password estão preenchidas, caso contrário abrirá uma janela, onde o serviço é configurado.
7º Passo -> Configuração do usuário que este serviço utilizará para ser executado.
A seguinte tela irá aparecer.
(Figura 4: Esta tela o administrador configura o usuário que o serviço utilizará para ser executado)
No campo “Username”, é importante utilizar a notação COMPUTADOR ou DOMÍNIO\Usuario.
É importante digitar correto, seguindo o case-sensitive, para o instalador rodar corretamente.
Para que esta janela não seja exibida ao usuário, você deve ir até o arquivo ProjectInstaller.vb, e preencher as propriedades Username e Password como strings.
Importante Nota: Não se preocupe se ocorrer algum erro durante a utilização do InstallUtil.exe, isto porque, a instalação de serviços é transacional, ou seja, ele só finaliza se tudo tiver ocorrido corretamente, caso contrário, ele efetua um RollBack.
Geralmente, os erros que podem acontecer ao chama-lo, é por causa de nome de usuário e senha incorreto.
A figura abaixo exibe o InstallUtil.exe em ação.
(Figura 5: InstallUtil.exe instalando o Windows Service)
Caso tudo ocorra de maneira correta, teremos 2 principais mensagens.
“The Commit phase completed successfully.”
“The transacted install has completed”
Se aparecer estas 2 mensagens ao final, que dizer que o serviço já está instalado, basta testar agora.
7. Testando o Windows Service
Agora que já sabemos o conceito do Windows Service, criamos um
e instalamos, precisamos vê-lo em ação.
Utilizaremos o seguinte plano de
teste:
1º Passo -> Abra o gerenciador de serviços. (Start ->
Programs -> Administrative Tools -> Services)
2º Passo ->
Procure o serviço “Detector de Arquivos .NET” e selecione-o.
(Figura 6: Gerenciador de Serviços com o Windows Service
recém-criado, selecionado.)
3º Passo -> Repare que ele
está “parado” atualmente e seu Startup Type está como “Manual”, da maneira que
configuramos a classe.
Agora clique com o botão direito e selecione
“Start”
4º Passo -> O serviço será “iniciado”. Não sei se você
lembra, mas nós adicionamos um código que insere uma entrada no Log de Eventos
do Windows, vamos ver se funcinou ?
Abra o “Event Viewer” pelo menu “Start
-> Programs -> Administrative Tools -> Event Viewer”
(Figura 7: Event Viewer com 1 registro de entrada do
Windows Service criado)
5º Passo -> Repare que já existe 1
registro de entrada com o Source=MeuServicoDotNet. Dê um duplo-clique
para analizar a informação. Você verá que a mensagem é a que colocamos na sub
OnStart, que é, “Atenção: Serviço Detector de Arquivos .NET foi
iniciado!”
6º Passo -> Repare que a coluna Time=4:25:03
AM, este foi o horário de inicialização do serviço no meu computador. No
seu, certamente o horário será diferente, mas é interessante, aguardar 4
minutos. Quando passar os 4 minutos, ou seja, quando chegar em 4:29:03 AM
(no meu caso), volte para o EventViewer e vá no menu “Action -> Refresh”.
Você verá que um novo registro foi adicionado.
Verificando a mensagem
deste novo registro, você verá:
“Atenção:Nenhum arquivo criado no
intervalo de 4 minutos.
Nenhum arquivo criado desde que o serviço foi
iniciado”
Nós configuramos esta mensagem na sub
Timer1_Elapsed, que é acionada de 4 em 4 minutos. Ela verifica se algum
arquivo já foi recebido. Se nenhum foi recebido, ele escreve este registro que
acabamos de ver.
7º Passo -> Agora, vá ao Gerenciador de
Serviços, clique com o botão direito sobre o serviço criado e vá em “Pause”. O
serviço será paralizado, e a coluna Status=Paused.
Volte ao
EventViewer, e dê outro Refresh.
Verá um 3º registro, com a
mensagem
“Atenção: Serviço Detector de Arquivos .NET foi parado
temporariamente (Pause)!”
Esta mensagem nós configuramos na Sub
OnPause
8º Passo -> Volte ao Gerenciador de Serviços,
clique com o botão direito sobre o serviço criado e vá em “Resume”. O serviço
voltará em execução, e a coluna Status=Started.
Volte ao EventViewer,
e dê outro Refresh.
Um novo registro deverá ter sido criado. Você verá que a
mensagem dele é:
“Atenção: Serviço Detector de Arquivos .NET foi
re-iniciado!”.
Esta mensagem foi configurada na sub
OnContinue.
9º Passo -> Volte ao Gerenciador de
Serviços, clique com o botão direito sobre o serviço criado e vá em “Stop”. O
serviço será finalizado, e a coluna Status=””, que representa um serviço
parado.
Se você for ao EventViewer, verá um novo registro com a seguinte
mensagem:
“Atenção: Serviço Detector de Arquivos .NET foi
parado!”.
Esta mensagem foi configurada na sub OnStop.
Volte ao
Gerenciado de Serviços, e dê um “Start” para fazermos o teste colocando 1
arquivo .txt na pasta rastreada. Não esqueça de dar um Start
!!
Importante Nota -> No Windows 2000 para frente, o
Gerenciador de Serviços possui uma nova funcionalidade, chamada Restart.
Quando você clica nesta ação, ele executará o código da sub OnStop e
imediatemente o OnStart. É apenas uma facilidade para um
administrador.
10º Passo -> Com o serviço inicializado
novamente (o que gerará um novo registro no Event Viewer), abra o seu “poderoso”
Bloco de Notas ou Notepad. Escreva qualquer coisa dentro do arquivo e salve-o
dentro da pasta “C:\MeuServicoDotNet” com o nome “WinService.txt“.
Agora
vá até o Event Viewer e dê um novo Refresh.
Você verá um novo registro, com a
seguinte mensagem:
“Atenção: Arquivo criado na pasta
C:\MeuServicoDotNet.
Nome do Arquivo:
C:\MeuServicoDotNet\WinService.txt”
Isto que dizer o Timer
funcionou corretamente.
11º Passo -> Espere 4 minutos passarem,
e volte ao EventViewer.
Você verá um novo registro com a seguite
mensagem:
“Atenção:Nenhum arquivo criado no intervalo de 4 minutos.
Data
do último arquivo criado: 1/18/2004 4:49:13 AM”
Esta mensagem deveria ser
exibida quando passava-se o tempo esperado e nenhum arquivo tinha sido recebido
neste intervalo, porém o serviço já havia recebido outro em um tempo
atrás.
Muito bom! Isto quer dizer que nossos testes funcionaram
perfeitamente.
Parabéns! Você finalizou o seu Windows Service.
8. Sumário
Neste artigo, podemos ver o conceito de uma solução, os
problemas de uma aplicação em ambiente Web.
Vimos também a necessidade de
termos agentes computacionais sendo executados 24 horas/dia e que antigamente,
criávamos este agente de diversas maneiras, não sendo a melhor
maneira.
Conheçemos então o conceito de Windows Service, vimos como criar,
instalar e testar.
Cabe a vocês agora, aprodundar ainda mais este assunto e
tornar as soluções que criamos, cada vez mais profissionais.
Vale lembrar
que para este artigo, utilizei o Windows Service com 3 controles, mas poderiamos
fazer diversas coisas, adicionando recursos de envio de email, acesso a dados e
por ai vai..Temos toda a .net Class Library para criar coisas
interessantes.
Os arquivos do projeto que eu criei como exemplo podem ser
baixados aqui.
Um
abraço e até a próxima!!