Vous êtes sur la page 1sur 6

Criando um serviço e importando XML com .

NET

O Visual Studio .NET possui muitos novos recursos, possibilitando que realizemos tarefas
antes muito difíceis de serem realizadas com VB 6.0.

Vamos então fazer uma aplicação de exemplo para demonstrar alguns desses recursos.
Em nossa aplicação vamos fiscalizar um determinado diretório (c:\dados, por exemplo),
identificando a criação de novos arquivos neste diretório. Ao ser criado um novo arquivo,
iremos ler seu conteúdo (que estará em formato XML) para um DataSet e importar seu
conteúdo para uma tabela do banco.

A tabela terá a seguinte estrutura:

Nome varchar(40)
cargo varchar(30)

Apenas para o exemplo não importa muito quando campos iremos utilizar, isso não irá
alterar a forma de construir o código.

Para começar precisaremos criar uma nova aplicação. Mas não criaremos uma
WindowsApplication comum, para garantir que a aplicação possa estar sempre rodando e
que possa ser iniciada de imediato quando o sistema iniciar deveremos criar a aplicação
como Windows Service, ou seja, um serviço do Windows.

Vamos chamar o serviço de ImportacaoDados. Além de criar o projeto com esse nome
devemos alterar o ServiceName da classe Service1 que é criada para nós. Podemos
Também alterar o nome da classe, name, para ImportacaoDados, por exemplo. Devemos
usar a janela de propriedades, não o código, pois este nome aparece em vários locais do
código de inicialização do serviço.

As propriedades da classe ImportacaoDados (que herda as características da classe


ServiceBase) possui várias propriedades que determinam os eventos do sistema que o
serviço pode tratar. A configuração default já é adequada, com a propriedade CanStop
definida como true, indicando que o serviço trata o evento de stop, e a propriedade autolog
como true, indicando que o serviço irá automaticamente logar os eventos de stop, start que
ocorrerem.

Todo serviço precisa de um instalador, que é criado dentro do mesmo Assembly do serviço.
Mas o VB.NET pode inserir o instalador no projeto automaticamente, basta que na janela
de propriedades, com a classe ImportacaoDados selecionada, cliquemos na instrução Add
Instaler, na parte inferior da janela de propriedades.

Fazendo isso será criado um novo arquivo .VB chamado ProjectInstaller.VB . Neste arquivo
são criados os componentes ServiceInstaller1 e ServiceProcessInstaller1. Precisamos
configurar esses dois componentes :

No ServiceInstaller1 vamos alterar o starType para Automatic. Isso determina que o serviço
deverá ser configurado para se iniciar automaticamente sempre que o Windows se iniciar.
É interessante observar que poderíamos também configurar as dependencias do serviço,
determinando que para se iniciar o serviço precisará que outros já estejam iniciados. No
nosso exemplo, porém, não precisamos configurar isso.
No ServiceProcessInstaller1 deveremos alterar a propriedade Account para LocalSystem,
determinando assim que no momento de instalação o serviço deve ser configurado para
rodar na LocalSystemAccount, conta local do sistema.

Voltando ao Service1.vb, vamos inserir um componente chamado FileSystemWatcher. Este


objeto nos permite fazer uma tarefa que antes era extremamente complexa : Vigiar o
sistema de arquivos para identificar alterações em arquivos, deleção, criação de novos
arquivos, ou outros eventos no sistema.

Vamos alterar o nome do FileSystemWatcher, chamando-o apenas de FSW. Existem 3


propriedades que determinam quais arquivos serão vigiados : Filter, determina o filtro de
arquivos, configurado como "*.*" por default. Path determina o caminho da pasta que será
vigiada e NotifyFilter determina os eventos que serão checados.

Em nosso exemplo iremos verificar apenas a criação de arquivos, então podemos alterar
notifyFilter para Filename. Iremos também configurar o Path como "C:\dados" e manter o
filter da forma que está. Um recurso interessante que devemos utilizar são as Dynamic
Properties. Filter e Path são ótimos candidatos a serem configurados como Dynamic
Properties. A configuração de Dynamic Properties nos permite vincular uma propriedade de
um determinado objeto a uma configuração no manifesto da aplicação. Desta forma
podemos manter os valores de filter e path gravados em um arquivo externo, o que fará
com que estas propriedades sejam facilmente alteradas mesmo com a aplicação já
compilada.

Basta para isso selecionarmos na janela de propriedades o item Dynamic Properties e


darmos um nome que será utilizado para a gravação das propriedades Filter e Path. Ao
fazermos isso o janela de propriedades passa a sinalizar o fato das propriedades estarem
sendo lidas de um arquivo de configuração, enquanto no solution explorer podemos
observar que é adicionado o arquivo de configuração, inicialmente com o nome de
APP.config.

A propriedade EnableRaisingEvents do FileSystemWatcher funciona como um on/off,


determinando se ele estará ou não vigiando o sistema de arquivos e disparando eventos
para nos alertar do ocorrido.

Como estamos desenvolvendo um serviço, vamos inicialmente configurar a


EnableRaisingEvents como False e vamos habilita-la/desabilita-la no start/stop do serviço.
Para isso basta entrarmos no código do service1.vb e começarmos o desenvolvimento,
veja :

Protected Overrides Sub OnStart(ByVal args() As String)


' Add code here to start your service. This method should set things
' in motion so your service can do its work.
FSW.EnableRaisingEvents = True
End Sub
Protected Overrides Sub OnStop()
' Add code here to perform any tear-down necessary to stop your service.
FSW.EnableRaisingEvents = False
End Sub

No Service1.vb, deveremos criar um objeto OledbConnection e um objeto OledbCommand


que servirão para fazermos a conexão com o banco de dados e atualizarmos os dados no
banco. Vamos chama-los de CN e CMD, para ficar mais fácil trabalhar com eles.
Precisaremos definir a string de conexão no objeto CN. A string de conexão é outra
excelente candidata a se transformar em Dynamic Properties, não apenas neste exemplo
mas eu diria que em toda aplicação, desta forma permitindo que a localização do banco de
dados possa ser facilmente alterada, apenas corrigindo a string dentro do manifesto da
aplicação.

Já no objeto CMD vamos liga-lo com o objeto CN e definir o commandText. Podemos


montar o CommandText dinâmicamente através do query Builder, basta termos o cuidado
de alterar o tipo da query para insert into e utilizarmos ? nos valores que deverão ser
preenchidos por parâmetros.

O objeto OLEDBCOMMAND sempre pergunta, após a montagem da query, se podem


redefinir a coleção de parâmetros do Command. Devemos permitir e ele irá criar a
definição dos parâmetros nome e cargo para nós. Podemos ver o que foi feito através da
coleção parameters, mas não iremos alterar nada.

Chegou a hora então de programarmos o evento Created do FSW, que é disparado


sempre que um novo arquivo é criado no diretório que está sendo vigiado. Nosso objetivo
é criar um DataSet e carregar para dentro do DataSet os dados do novo arquivo. Veja
como fica o inicio deste código :

Private Sub FSW_Created(ByVal sender As Object, ByVal e As


System.IO.FileSystemEventArgs) Handles FSW.Created

Dim ds As New DataSet()

ds.ReadXml(e.FullPath)

End Sub

Assim, com apenas duas linhas de código carregamos para um DataSet o conteúdo do
novo arquivo. Agora precisamos atualizar o banco. Isso exigiria normalmente que
fizessemos um algorítimo como loop para jogarmos os dados no banco executando o
Command. Bem, não no .NET. Podemos apenas criar um DataAdapter, liga-lo ao
Command e utiliza-lo para atualizar o banco automaticamente. Veja como fica o código:

Private Sub FSW_Created(ByVal sender As Object, ByVal e As


System.IO.FileSystemEventArgs) Handles FSW.Created

Dim ds As New DataSet()


Dim da As OleDb.OleDbDataAdapter

ds.ReadXml(e.FullPath)

da = New OleDb.OleDbDataAdapter()
da.InsertCommand = cmd

da.Update(ds, "funcionario")

ds.Dispose()
ds = Nothing
da.Dispose()
da = Nothing
End Sub

Observem que este data adapter nem ao menos possui um selectCommand. Isso não é
necessário já que estamos apenas inserindo registros no banco.

Pronto. Está feito. Isso mesmo. Com Poquissimas linhas de código, praticamente um
desenvolvimento todo visual, conseguimos montar uma aplicação que será instalada
como serviço do Windows, monitorar os arquivos criados em um diretório, ler o conteúdo
destes arquivos e jogar os dados para uma tabela de banco.

O próximo passo é instalar esse serviço. Para isso o framework nos traz um utilitário
chamado installutil. Executando no prompt InstallUtil este utilitário dispara o instalador que
criamos em nosso assembly e o instalador por sua vez se encarrega de fazer as
configurações do serviço na máquina.

Você agora só precisa agora ter cuidado com a montagem do arquivo XML, pois o
dataSet é um pouco temperamental na leitura deste arquivo. Veja um exemplo de como
ele fica :

<cadfunc>
<funcionario>
<nome>Joao</nome>
<cargo>faxineiro</cargo>
</funcionario>
</cadfunc>

Observe a forma como os dados estão montados : Nome e cargo estão colados a suas
respectivas tags. Veja um exemplo do que sereia uma montagem ERRADA :

<cadfunc>
<funcionario>
<nome>
Joao
</nome>
<cargo>
faxineiro
</cargo>
</funcionario>
</cadfunc>

Você pode pensar a principio que não existe nada errado neste XML e, realmente, ele é um
XML válido. Mas se olhar mais atentamente poderá observar que dentro do campo nome e
dentro do campo cargo temos 2 CR (Enter, código ASC=13). Isso será lido como parte dos
dados e inserido como informação nestes campos, dentro do banco de dados. Desta forma
devemos tomar cuidado com o que inserimos nas tags de dados do XML.

Tendo esse cuidado, você poderá montar vários arquivos e joga-los, um por um, no diretório
que está sendo vigiado por sua aplicação. Poderá observar como a aplicação lê o conteúdo
do XML e executa o insert na base de dados.

Vous aimerez peut-être aussi