Artigo Clube Delphi 102 - Services Applications

Você precisa estar logado para dar um feedback. Clique aqui para efetuar o login
Para efetuar o download você precisa estar logado. Clique aqui para efetuar o login
Confirmar voto
0
 (6)  (0)

Artigo da Revista Clube Delphi Edição 102.

Esse artigo faz parte da revista Clube Delphi Edição 102. Clique aqui para ler todos os artigos desta edição

EasyDelphi

Criando service application

Crie aplicações e faça as rodar como Serviços no Windows

 

Neste artigo veremos

·         Criação de um serviço de backup de arquivos;

·         Cópia e compactação dos arquivos para backup;

·         Criação e instalação do serviço;

·         Gerenciamento do serviço no painel de controle.

Qual a finalidade?

·         Entender os processos e implementação de serviços no Windows.

Quais situações utilizam esses recursos?

·         Em situações onde se faz necessário que o aplicativo esteja sempre em execução, não dependendo da ação de usuários para iniciar o processo.

 

Resumo do DevMan

A criação de serviços no Windows é um recurso bastante útil na execução de processos de forma automática sem intervenção de usuários. Podemos citar como exemplos de serviços os itens Horário do Windows, Log de eventos do Windows, e uma série de outros.

Nesse artigo veremos a criação de um serviço de backup automatizado com opção de compactação usando WinRAR e Winzip.

 

Quando desenvolvemos aplicações Win32 ou.net, estas são executadas sempre a partir de solicitações voluntárias de usuários que fazem as chamadas ao sistema. Mas há situações em que necessitamos criar aplicações capazes de funcionarem sem a interação do usuário e de forma independente, ou seja, que sejam executadas de forma automática, como os serviços do Windows. As Service Applications como também podem ser chamadas, iniciam juntamente com o sistema operacional, independente de haver ou não algum usuário logado no computador ou mesmo interagindo com o sistema. Ao acessarmos o ícone Serviços dentro de Ferramentas Administrativas encontrado no Painel de Controle do Windows podemos ver que diversos serviços são listados, uns em execução e outros não. Todos esses são considerados Service Applications.  Perceba que temos serviços de tudo que é jeito, como por exemplo, Horário do Windows.

Neste artigo veremos criaremos um pequeno utilitário para backup de arquivos comuns. Primeiramente, faremos a criação de uma aplicação simples Win32 e em seguida faremos a conversão transformando-a em uma Service Application.

 

ClubeDelphi PLUS!

Acesse agora o mesmo o portal do assinante ClubeDelphi e assista a uma vídeo aula de Jefferson Junglaus que mostra como trabalhar com serviços no Windows.  

http://www.devmedia.com.br/articles/viewcomp.asp?comp=3381

 

Nota DevMan

Você sabia que o Windows possui uma série de serviços automatizados para realizar as mais diversas tarefas do dia-a-dia? Pois bem, algumas das tarefas mais importantes para o bom funcionamento do sistema operacional são na verdade serviços que ficam executando em BackGround, ou seja, ocultos sem que o usuário perceba. Um exemplo bastante claro disso é a detecção automática de atualizações, que encontramos no painel de Serviços com o nome Windows Update. Esse serviço é responsável por verificar qual a versão atual de nosso Windows bem como seus componentes e compará-los com as versões presentes no servidor da Microsoft. Quando uma atualização é detectada o serviço avisa o usuário que pode optar ou não pela instalação do Update.

 

Desenvolvendo o aplicativo

Como mencionado criaremos uma aplicação Win32 para backup manual e compactação dos arquivos. Para isso usaremos o Delphi 7, porém nada impede que seja utilizado outro Delphi a sua escolha. Vamos iniciar criando a aplicação usando o menu File>New>Application e salvando sua Unit principal como uBackup.pas e o projeto como prjBackup.dpr em um diretório do seu computador. Altere a propriedade Name do formulário para frmServiceBackup e o Caption para Configuração de Serviço de Backup. Para melhor entender e organizar nossa aplicação de backup, utilizaremos quatro componentes GroupBox da paleta Standard que deverão ser arrastados para o formulário.

No primeiro GroupBox (gbBackup), altere a propriedade Caption para Backup e arraste para dentro deste um Label com o Caption de Localizar arquivos de Origem para identificar a busca dos arquivos. Ao lado deste, adicione um Button (btnSelFiles) que fará a chamada de um diálogo de pesquisa dos arquivos. Adicione também dentro do gbBackup um componente ListBox (lbListaBackup) no qual iremos exibir os arquivos da lista. Por último, inclua mais dois componentes Button (btnRemover e btnBkpManual) alterando a propriedade Caption dos mesmos seguindo a ordem para Remover da Lista e para Backup Manual. Arraste ainda ao formulário um componente OpenDialog(dlgAddFiles) da paleta Dialogs que será utilizado para exibir o diálogo de busca para inclusão dos arquivos na lista, alterando sua propriedade Options>ofAllowMultiSelect para True possibilitando que vários arquivos sejam selecionados de uma única vez.

Proporcionaremos nesta aplicação uma configuração onde o usuário poderá optar em apenas copiar os arquivos da lista para um novo diretório ou a compactação dos mesmos utilizando os compactadores WinRAR ou WinZip armazenando os arquivos compactados também no diretório a ser definido. Para esta opção adicione um novo GroupBox(gbConf) alterando também sua propriedade Caption para Configurações e arraste para dentro do mesmo um componente CheckBox(ckbUsarCompact) que deverá alterar o Caption para Usar Compactação dos Arquivos?.

Para a configuração de escolha dos tipos de compactação, adicione imediatamente abaixo ao gbConf um componente RadioGroup(rgTipoCampact) alterando sua propriedade Caption para Tipo de Compactação e a propriedade Items onde deverá incluir as duas opções disponíveis, sendo uma em cada linha da caixa de texto que será exibida: WinRAR e WinZip. Altere ainda o ItemIndex para zero fazendo com que o primeiro item permaneça selecionado e defina Visible para False.

No último GroupBox(gbDestino) a ser adicionado, deverás alterar a propriedade Caption para Destino do Backup e para dentro do mesmo arraste um componente Edit(edtDestino) que irá armazenar o diretório destino onde será realizado o backup da aplicação, podendo ser fixado na propriedade Text informando um caminho de diretório, como por exemplo C:\Backup\.

Pelo fato de estarmos criando um aplicativo com a idéia de deixá-lo automatizado e mais tarde transformá-lo em um serviço, precisamos utilizar alguma forma onde o usuário faça a configuração do sistema uma única vez e estas permaneçam gravadas para que no momento de start do serviço, ele saiba todas as rotinas a serem executadas sem que haja intervenção do usuário. Para isto utilizaremos arquivos de configuração, ou arquivos INI como são comumente chamados.

Mais precisamente, um arquivo INI é um arquivo de texto onde definimos regras que serão carregadas e reescritas pelo sistema, regras estas que serão utilizadas para a configuração automática do sistema. Faremos a configuração destas regras em um Button(btSalvarConfs) que deverá ser adicionado ao final do formulário com sua propriedade Caption alterada para Salvar Configurações, que irá concluir o processo da criação do visual do aplicativo de backup (Figura 1).

 

Figura 1. Visual da aplicação de backup

 

Para criar um arquivo INI iremos utilizar o bloco de notas (notepad) que deverá ser aberto e digitar a seguinte estrutura:

[BACKUP]

COMPACTAR=S

TIPO=Z

DESTINO=C:\Backup\tmp

ULTIMO=28/08/2008

 

Nesta estrutura estamos criando um novo bloco chamado de Backup para armazenar as informações de configuração do sistema. Neste bloco criamos itens, onde o primeiro item identificado como Compactar diz respeito à compactação dos arquivos, variando de acordo com as opções do usuário:

 

S: habilitar compactação;

N: desabilitar a mesma.

 

Para o item Tipo, caso tenha optado pela compactação dos arquivos, irá definir se o compactador a ser utilizado é o WinZIP (armazenado como W) ou o WinRAR (armazenado como R). No item Destino ficará por sua vez armazenado o diretório de destino dos arquivos e a opção Ultimo será a responsável por armazenar a data do último backup, evitando assim que o mesmo seja repetido em um único dia. Salve agora o arquivo do bloco de notas como backup.ini no mesmo diretório onde se encontram os arquivos fontes da aplicação onde posteriormente será localizado.

Bom, até o momento entendemos como o sistema cliente (assim o iremos chamar) irá funcionar, e iniciaremos agora o processo de codificação do aplicativo. Nesta codificação direcionaremos nessa primeira etapa a construção de processos simples que formarão uma lista de arquivos, opções e formas de compactação. Criaremos um processo manual para cópia dos arquivos, que depois iremos implementar no aplicativo de serviço, que fará a leitura destas configurações e acionará um processo automático.

A primeira codificação que iremos desenvolver será o processo de montagem dos arquivos na lista de backup, ou seja, utilizaremos o componente dlgAddFiles para buscar os arquivos e adicioná-los a lista adicionando o código da Listagem 1 ao evento OnClick do btnSelFiles. Logo após a execução do componente de diálogo, percorremos por meio de um comando for todos os arquivos selecionados adicionando-os um a um ao  componente ListBox formando a lista de arquivos do backup.

 

Listagem 1. Adicionando arquivos selecionados à lista.

procedure TfrmServiceBackup.btnSelFilesClick(Sender: TObject);

var

  i : integer;

begin

  if dlgAddFiles.FileName <> '' then

    for i := 0 n dlgAddFiles.Files.Count -1 do

      lbListaBackup.Items.Add(dlgAddFiles.Files[i]);

end;

 

No próximo passo do processo de codificação, veremos como excluir arquivos adicionados indesejadamente a lista de backup, lembrando que apenas temos uma lista em memória formada. Isso significa que podemos excluir pelo próprio componente ListBox apenas adicionando o código a seguir ao evento OnClick do btnRemover, que irá executar o comando Delete no índice selecionado do componente.

 

lbListaBackup.Items.Delete(lbListaBackup.ItemIndex);

 

Nesse ponto já estamos criando e editando a lista dos arquivos para o backup e precisamos codificar as opções disponibilizadas nele, ou seja, quanto ao uso de compactação. No inicio do artigo, enquanto criávamos o layout do aplicativo definimos como False a propriedade Visible das opções de compactação (WinZIP ou WinRAR), mas que deverão ser exibidas ao selecionarmos a opção de compactação, para a qual se faz necessário adicionar o código seguinte no evento OnClick do componente ckbUsarCompact que irá habilitar ou desabilitar a visibilidade do componente rgTipoCampact de acordo com sua propriedade Checked.

 

rgTipoCampact.Visible := ckbUsarCompact.Checked;

 

Como próximo passo na continuação de criação da nossa aplicação, codificaremos a rotina responsável por salvar as configurações do sistema no arquivo Backup.ini criado anteriormente. Nosso primeiro passo será declarar nas Uses do Delphi a Unit IniFiles, responsável pelo acesso e leitura dos arquivos de configurações. Realizada a declaração, adicione ao evento OnClick do botão btSalvarConfs o código da Listagem 2 iniciando pela declaração de uma variável. É interessante que todas as variáveis de objetos criadas durante a programação sejam inicializadas com o nil, que faz com que as mesmas sejam criadas sem nenhum tipo de valor, assim não provocando Warnings (avisos) durante a compilação do aplicativo.

Na criação dos objetos recuperamos o caminho do executável do aplicativo, lugar onde obviamente encontraremos o arquivos *.INI. Criado e conectado ao arquivo, utilizaremos a função WriteString para reescrever os valores no arquivo. Realizadas estas operações de gravação, limpamos o objeto criado na memória e em seguida iniciamos o salvamento da lista de arquivos do backup, estes de forma bem mais simples a serem tratados por já estarem distribuídos em linhas e bastando apenas aplicar o SaveToFile do próprio ListBox para salvar todas as linhas em um novo arquivo de configurações *.INI.

 

Listagem 2. Salvando as configurações do sistema

procedure TfrmServiceBackup.btSalvarConfsClick(

  Sender: TObject);

var

  Confs : TIniFile;

begin

  Confs := nil;

  try

    Confs := TIniFile.Create(ExtractFilePath(Application.ExeName)

      + 'backup.ini');   

    if ckbUsarCompact.Checked then

    begin

      Confs.WriteString('BACKUP','COMPACTAR','S');

      if rgTipoCampact.ItemIndex = 0 then

        Confs.WriteString('BACKUP','TIPO','R')

      else

        Confs.WriteString('BACKUP','TIPO','Z');

    end

    else

      Confs.WriteString('BACKUP','COMPACTAR','N');

    Confs.WriteString('BACKUP','DESTINO',edtDestino.Text); 

  finally

    Confs.Free;

  end;

lbListaBackup.Items.SaveToFile(ExtractFilePath(Application.ExeName)

  +'lista.ini');

end;

 

Salvando todas as configurações em arquivos *.INI faz-se também necessário que estas mesmas configurações sejam carregadas quando o sistema for aberto novamente, ou seja, todas as opções que você salvou precisam voltar no mesmo estado na próxima vez que abrir o sistema. Para este procedimento, codificaremos o evento OnCreate do formulário (Listagem 3), para o qual definiremos um objeto do tipo TIniFile que será criado em runtime e fará a leitura do arquivo backup.ini que contém as configurações do sistema. Na medida em que os blocos de registros são lidos, combinamos as informações e realizamos a configuração do sistema, e logo em seguida a liberação do objeto criado da memória. No último segmento do código, utilizamos o LoadFromFile do componente ListBox e carregamos a lista de arquivos para backup, escrevendo-os da mesma forma como foram salvos dentro do componente.

 

Listagem 3. OnCreate do formulário

procedure TfrmServiceBackup.FormCreate(Sender: TObject);

var

  Confs : TIniFile;

begin

  Confs := nil;

  try

    Confs := TIniFile.Create(ExtractFilePath(Application.ExeName)

      +'backup.ini');

    if Confs.ReadString('BACKUP','COMPACTAR','') = 'S' then

    begin

      ckbUsarCompact.Checked := True;

      if Confs.ReadString('BACKUP','TIPO','') = 'R' then

        rgTipoCampact.ItemIndex := 0

      else

        rgTipoCampact.ItemIndex := 1;

    end

    else

      ckbUsarCompact.Checked := False;

    edtDestino.Text := Confs.ReadString('BACKUP','DESTINO','');

  finally

    Confs.Free;

  end;

  lbListaBackup.Items.LoadFromFile(ExtractFilePath(Application.ExeName)

    +'lista.ini');

end;

 

Só para entendermos bem o código-fonte, estamos instanciando/criando o arquivo .INI em memória através do método Create da classe TIniFiles.Criaremos agora uma função que fará um backup manual de todos os arquivos da lista, a mesma função que utilizaremos logo mais para criação do serviço automatizado. Esta função será baseada nas atuais opções selecionadas no sistema, e de acordo com as mesmas tratará a lista de backup.

Acessando o código da aplicação, declare na seção private da Uses a procedure Backup a seguir que receberá como parâmetro o caminho dos arquivos a serem adicionados no backup.

 

procedure Backup(CaminhoArquivo: string);

 

Declarada a função na seção private da uses utilize o atalho Shift+Ctrl+C para que o Delphi no crie o cabeçalho da procedure. Adicione o código da Listagem 4. O código fará uma primeira verificação quanto ao campo de compactação, se a mesma será necessária ou apenas a cópia de arquivos será o suficiente. Para o caso da opção de compactação não estar habilitada, a rotina apenas fará a cópia dos arquivos para o diretório de destino do backup. Caso a opção de compactação esteja como Checked = True o sistema fará uma nova verificação, a fim de saber se o tipo de compactação será com o WinZIP ou WinRAR. Para qualquer uma das duas situações de compactação o processo será muito semelhante, montamos uma lista temporária, editamos o nome do arquivo e atribuímos a ele a extensão correspondente e criamos uma linha de comando para fazer referência aos diretórios de instalação.

Com o destino do backup, nome do arquivo e linha de comando invocamos a função WinExec da API do Windows. Esse comando é capaz de executar programas externos. Para melhor facilitar o entendimento da função, o código encontra-se comentado de acordo com as funcionalidades executadas em cada linha do comando.

 

Listagem 4. Procedure que fará o backup

procedure TfrmServiceBackup.Backup(CaminhoArquivo: string);

var                          

  NomeArquivo: string;

  Temp: string;

  LinhadeComando: string;

  Destino: string;

begin

  if ckbUsarCompact.Checked then 

  begin

    if rgTipoCampact.ItemIndex = 0 then   

    begin     

      Temp := ChangeFileExt(CaminhoArquivo, '.rar');     

      NomeArquivo := PASTA_DESTINO_BKP + ExtractFileName(temp);

      LinhadeComando := 'C:\Program Files (x86)\WinRAR\WINRAR.EXE a "' +  

        NomeArquivo + '" ' + CaminhoArquivo ;

    End

    else

    begin

      Temp := ChangeFileExt(CaminhoArquivo, '.zip');     

      NomeArquivo := PASTA_DESTINO_BKP + ExtractFileName(temp);

      LinhadeComando := 'C:\Program Files (x86)\WinZip\WINZIP32.EXE -A "' +

        NomeArquivo + '" ' + CaminhoArquivo;

    end;   

    try

      WinExec(Pchar(LinhadeComando),1);

    except

    end;

  end

  else

  begin       

    Destino := PASTA_DESTINO_BKP + ExtractFileName(CaminhoArquivo);   

    if not CopyFile(PChar(CaminhoArquivo), PChar(Destino), true) then           

       ShowMessage('Erro ao copiar ' + CaminhoArquivo + ' para ' + Destino); 

  end;

end;

 

A princípio criamos algumas variáveis para diversas tarefas ao longo do procedimento. Em seguida verificamos o estado do CheckBox referente a compactação. Caso esteja checado, o sistema fará a verificação de qual compactador está selecionado e então montará uma LinhaDeComando para ser executada mais adiante. Por fim o procedimento chama o método WinExec passando o comando montado para ser executado.

Criada a procedure veremos como chamar ela a partir do backup manual. Digite o código da Listagem 5, no qual evento OnClick do botão btnBkpManual, no qual realizamos novamente uma verificação quanto a compactação dos arquivos, onde se habilitada fará um laço entre todos os arquivos da lista de backup adicionando-os um ao lado do outro e separados por aspas duplas, a fim de que a compactação seja realizada em um único arquivo.

 

Listagem 5. Executando um backup manual

procedure TfrmServiceBackup.btnBkpManualClick(Sender: TObject);
var

  I: Integer;

  CaminhoArquivo: string;

begin

  if ckbUsarCompact.Checked then

  begin

    for I := 0 to lbListaBackup.Count - 1 do   

      CaminhoArquivo := '"'+lbListaBackup.Items.Strings[I] + '" ' +

        CaminhoArquivo;

    Backup(CaminhoArquivo);

  end

  else

  begin

    for I := 0 to lbListaBackup.Count - 1 do

    begin

      CaminhoArquivo := lbListaBackup.Items.Strings[I];

      Backup(CaminhoArquivo);

    end;

  end;

end;

 

Perceba que o processo é bastante simples. Apenas testamos novamente o CheckBox de compactação e percorremos o ListBox montando uma única linha de comando. Finalizada esta etapa da codificação, execute o sistema e teste quanto ao funcionamento de salvar e abrir o sistema com as configurações e da mesma forma a adição de arquivos na lista e o backup manual dos mesmos. Concluídos os testes, passaremos enfim para a criação do serviço, que verá ser um aplicativo simples com poucas codificações.

 

Criando o serviço

Agora faremos a parte mais importante do nosso sistema. Faremos sua conversão para Service Application. No Delphi 7, e outras versões, um tipo específico de projeto que pode ser criado. Acessamos essa opção através do menu File>New>Other>Delphi Projects>Service Application (Figura 2). Serão criados automaticamente pelo Delphi duas Units, uma referente ao Source Code e outra ao Project. Salve os respectivos documentos como uServico.pas e prjService.dpr no mesmo diretório onde criamos o aplicativo cliente do backup, pois faremos uma referência em runtime para localizar, ler e executar os arquivos já criados.

 

Figura 2. Criando Service Application

 

Nos documentos criados pelo Delphi, selecione também o serviço propriamente dito e altere sua propriedade Name para mServico. Podemos observar um diferencial no código do projeto, onde já nas declarações das Uses não temos mais presente a Unit Forms encontrada em todas as aplicações normais Win32. No lugar notamos a Unit SvcMgr específica para inicialização de serviços, ou seja, a execução do aplicativos acontece antes da autenticação de usuários, além disso, o único objeto que deve ser criado na inicialização é o serviço. Veja um trecho de código no Source do projeto:

 

if not Application.DelayInitialize or Application.Installing then

    Application.Initialize;

Application.CreateForm(TmServico, mServico);

Application.Run;

 

O serviço na verdade não possui form e sim uma espécie de Data Module onde os componentes visuais são colocados e codificados. Selecionado o mServico (nosso Data Module) faremos a configuração das propriedades do serviço propriamente dito. Essas propriedades serão levadas em conta no momento da execução do serviço pelo sistema operacional, tais como: nome de identificação do serviço na lista de serviços do Windows, dependências, permissões, entre outros.

Iniciando pela primeira propriedade disponível, temos duas opções de permissão AllowPause e AllowStop permitindo que por meio de intervenções de usuários ou outros aplicativos o serviço possa ser pausado ou até mesmo parado, respectivamente. Em seguida temos em Dependencies a disponibilidade de adicionar uma lista de outros serviços, ou seja, pré-requisitos para que o serviço seja inicializado, ponto este que apenas acontecerá quando todas suas dependências definidas já estiverem rodando no sistema.

Para adicionar dependências, abra o editor da propriedade e adicione uma nova dependência (Add New(Ins)), selecione a dependência adicionada e na sua propriedade Name marque qual o serviço deverá ser o pré-requisito para execução do sistema, FirebirdServerDefaultInstance para definir o Firebird como pré-requisito (Figura 3).

 

Figura 3. Definindo serviço do Firebird como dependência

 

Na propriedade DisplayName iremos definir uma descrição que identificará o serviço entre os demais da lista de serviço do Windows, defino-o como Serviço de Backup ClubeDelphi. Nas demais propriedades poderíamos ainda definir se o serviço será ou não interativo com o usuário, definir ainda o tipo do serviço, modo de inicialização, entre outras propriedade que poderão ser mantidas como default para este exemplo.

Sendo um sistema baseado em tempo, ou seja, um backup por dia faremos o controle das verificações através de um Timer (TimerBackup) que deverá ser adicionado ao mServico e também o controle da última data de backup que ficará armazenada no documento backup.ini. Defina a propriedade Interval do TimerBackup para 3600000 (três milhões e seiscentos mil) representando um intervalo de verificação de 1h30min.

Na codificação do evento OnTimer do componente criaremos as regras da verificação, onde iremos ler o arquivo das configurações, realizar a comparação de datas e se for necessário, realizar o backup da lista. Acessando a página de códigos do serviço, adicione primeiramente as Units IniFiles e SWSystem.

A Unit IniFiles contém as funções e classes necessárias para se trabalhar com arquivos do tipo INI. Em seguida declare uma procedure chamada Backup recebendo como parâmetro os valores Compactar, Tipo, CaminhoArquivo e Destino, todas do tipo String, assim como podemos ver a seguir:

 

procedure Backup(Compactar, Tipo, CaminhoArquivo, Destino: string)

 

Essa procedure será chamada no momento da cópia e compactação dos arquivos. Utilize as teclas Shift + Ctrl + C para criar o cabeçalho do procedimento e adicione a ela o código da Listagem 6, onde temos um método que receberá alguns parâmetros de entrada utilizados nas verificações e desenvoltura do processo de backup. O código é muito semelhante ao visto no desenvolvimento da aplicação client onde primeiramente verificamos à necessidade de compactação. Em caso negativo, faz-se apenas a cópia dos arquivos compactando-os ou não dependendo do que foi selecionado anteriormente. Definido o método de compactação, uma linha de comando é configurada e executada logo após de uma chamada de comandos externos. Buscamos o caminho absoluto do respectivo compactador seguido por parâmetros que farão a compactação caso necessário. Simplesmente executamos o método CopyFiles do Delphi.

 

Listagem 6. Procedure que executará o backup

procedure TmServico.Backup(Compactar, Tipo, CaminhoArquivo,

  Destino: string);
var                          

  NomeArquivo: string;

  Temp: string;

  LinhadeComando: string;

begin

  if Compactar = 'S' then

  begin

    if Tipo = 'Z' then

    begin

      Temp := ChangeFileExt(CaminhoArquivo, '.rar');

      NomeArquivo := Destino + ExtractFileName(temp);

      LinhadeComando :=

        'C:\Program Files (x86)\WinRAR\WINRAR.EXE a "' +

        NomeArquivo + '" ' + CaminhoArquivo ;

    end

    else

    begin

      Temp := ChangeFileExt(CaminhoArquivo, '.zip');

      NomeArquivo := Destino + ExtractFileName(temp);

      LinhadeComando := 'C:\Program Files (x86)\WinZip\WINZIP32.EXE -A "'

        + NomeArquivo + '" ' + CaminhoArquivo;

    end;

    try

      WinExec(Pchar(LinhadeComando),1);

    except

    end;

  end

  else

  begin

    Destino := Destino + ExtractFileName(CaminhoArquivo);

    if not CopyFile(PChar(CaminhoArquivo), PChar(Destino), true) then

      ShowMessage('Erro ao copiar ' + CaminhoArquivo + ' para ' + Destino);

  end;

end;

 

Finalizada a codificação do procedimento, faremos agora a implementação do evento que irá disparar o procedimento passando-lhe todos os parâmetros necessários para execução da tarefa. No evento responsável pela execução e configuração dos parâmetros, adicionaremos ao evento OnTimer do TimerBackup a leitura dos arquivos de configuração (arquivos *.ini) e também do arquivo que contém a lista de arquivos a serem copiados no backup, para que os mesmos sejam carregados e organizados.

Adicionando ao evento OnTimer o código da Listagem 7, observe que após a declaração das variáveis estamos criando um objeto do tipo TIniFile passando como parâmetro o endereço do arquivo backup.ini. Declare também as Unit IniFiles e SWSystem que serão necessárias para o reconhecimento de ambos os objetos.

 

Listagem  7. Código para start do backup

procedure TmServico.TimerBackupTimer(Sender: TObject);

var

  conf: TIniFile;

  pData: TDate;

  Compactar: string;

  TipoComp: string;

  Destino: string;

  Lista: TStringList;

  I: Integer;

  CaminhoArquivo: string;

begin

  conf := nil;

  Compactar := 'N';

  try

    try

      conf := TIniFile.Create(gsAppPath+'backup.ini');

      pData := StrToDate(conf.ReadString('BACKUP','ULTIMO',''));

      if pData < Date then

      begin

        Compactar := Trim(conf.ReadString('BACKUP','COMPACTAR',''));

        if Compactar = 'S' then

          TipoComp := Trim(conf.ReadString('BACKUP','TIPO',''));

        Destino := conf.ReadString('BACKUP','DESTINO','');

        Lista := TStringList.Create;

        Lista.LoadFromFile(gsAppPath+'lista.ini');

        if Compactar = 'S' then

        begin

          for I := 0 to Lista.Count - 1 do

            CaminhoArquivo := '"' + Lista.Strings[I] +

              '" ' + CaminhoArquivo;

          Backup(Compactar,TipoComp,CaminhoArquivo,Destino);

        end

        else

        begin

          for I := 0 to Lista.Count - 1 do

          begin

            CaminhoArquivo := Lista.Strings[I];

            Backup(Compactar,TipoComp,CaminhoArquivo,Destino);

          end;

        end;

        conf.WriteString('BACKUP','ULTIMO',

          FormatDateTime('dd/MM/yyyy',Date));

      end;

    except

    end;

  finally

    conf.Free;

    Lista.Free;

  end;

end;

 

Para a variável pData, veja que realizamos a leitura do valor armazenado no arquivo de configurações e o comparamos a data atual do sistema. No caso da data atual ser superior a armazenada, a chamada ao backup será executada. O código inicia-se pelo carregamento da lista de arquivos para a cópia e posterior montagem da linha de comando. Para os casos onde a compactação não será necessária, uma contagem da quantidade de arquivos é realizada e por meio do uso de um comando for a cópia é realizada. Finalizado o processo de backup, reescrevemos a data do último serviço nas configurações, fazendo com que para este mesmo dia, nenhuma cópia a mais seja executada.

 

Instalando o serviço

Ao contrário das instalações de sistemas normais como você esta acostumando, com telas dinâmicas, botões de Next ou Avançar, a instalação de serviços é realizada através do Prompt de Comandos do Windows, por meio de linha de comando. Antes de iniciarmos a instalação de fato, vá até o diretório C:\Arquivos de Programas\ e crie uma pasta com o nome Backup ClubeDelphi. Copie para esta os executáveis da aplicação cliente (prjBackup.exe), o executável da Service Application (prjService.exe), além, é claro, dos dois arquivos de texto contendo as configurações que ambos os executáveis (backup.ini e lista.ini).

Abra o Prompt de Comando do Windows digitando cmd no Iniciar>Executar. Entre no diretório que acabamos de criar no C:\Arquivos de Programas. Em seguida digite:

 

C:\>prjService.exe /install

 

Conforme exibido na Figura 4 obtemos a mensagem de o serviço foi instalado com sucesso. A instalação ainda não significa que o serviço esteja rodando, e para tanto precisaremos acessar suas configurações e dar o Start inicial ao processo.

 

Nota: Para desinstalar o serviço, basta primeiramente pará-lo no ícone Serviços que encontra-se dentro de Ferramentas Administrativas no Painel de Controle. Em seguida, abra novamente o prompt e entre na pasta onde o serviço está instalado. Basta então digitar o comando /uninstall seguido do nome do projeto.

 

Figura 4. Instalação de serviço do Windows

 

Configurando e iniciando o serviço

Para dar start na aplicação e com isso fazê-la funcionar, basta entrar no Painel de Controle>Ferramentas Administrativas>Serviços e localizar o nosso serviço que deverá aparecer com o nome que configuramos no projeto, Serviço de Backup ClubeDelphi. Ao encontrar a entrada, utilize o botão direito sobre o mesmo e acesse suas propriedades, observando que várias opções de configuração ainda estão disponíveis. Na guia Logon temos a opção de Permitir que o serviço interaja com a área de trabalho, que seria útil no caso de exibirmos alguma mensagem ou mesmo se tivéssemos a construção de algum formulário em tempo de execução. Não estando habilitada, esta opção rejeita qualquer solicitação do serviço para exibir informações na tela do usuário, permanecendo apenas como processo oculto em execução.

Retornando a guia Geral, mantenha o tipo de inicialização como Automática, fazendo com que o serviço seja iniciado automaticamente a cada inicialização do Sistema Operacional e em seguida, inicie o processo com um clique sobre o botão Iniciar. Pronto, seu serviço de backup já estará em execução no seu computador. Utilize agora o sistema cliente para as configurações necessárias e lista de arquivos do backup e aguarde o período definido no Timer para que o primeiro backup seja realizado.

Por default, os backups serão realizados em modo background, ou seja, não visíveis ao usuário.

 

Conclusão

O desenvolvimento de aplicações Service Application é ideal para que possamos automatizar tarefas. O exemplo aqui realizado é só um dos muitos aplicativos que podemos desenvolver usando esse recurso. Uma boa idéia é criar serviços para os mais variados tipos de tarefas, como fazer a atualização automática do software via internet, como fazem a maiores dos anti-vírus, por exemplo.

Enfim, cabe ao leitor aprimorar seus conhecimentos montando novas aplicações, criando idéias e estudando mais detalhes sobre a criação de serviços. Abraços e até a próxima.

 
Você precisa estar logado para dar um feedback. Clique aqui para efetuar o login
Receba nossas novidades
Ficou com alguma dúvida?