Escrevendo programa de serviço Win2000 usando Delphi
Resumo: Este artigo apresenta o uso do Delphi para escrever programas de serviço Win2000. As classes envolvidas são TServiceApplicatoin, TService, TServiceThread, etc.
Palavras-chave: Serviço/serviço
1. Introdução aos serviços Win2000
O aplicativo de serviço é um programa em segundo plano executado no WinNT. Cada aplicativo de serviço pode conter vários serviços e cada serviço é um dos threads (o serviço também pode criar vários subserviços). Ao usar serviços, os aplicativos podem obter permissões especiais, e o usuário não encerrará o programa diretamente por meio do Gerenciador de Tarefas do Win2000, portanto, os serviços são frequentemente usados para atingir alguns objetivos especiais.
Através da ferramenta de gerenciamento de serviços no painel de controle do Win2000, podemos definir/visualizar as características do serviço:
(1) Nome do serviço; (2) Nome de exibição; (4) Tipo de inicialização;
Entre eles, o nome do serviço identifica o serviço.
Tomemos como exemplo o programa C:/WINNT/System32/services.exe do Win2000. Este arquivo Exe corresponde a um Aplicativo de Serviço e é a entidade visível do programa de serviço, o exe contém vários serviços (Serviço), como Alerter, Cliente DHCP (DHCP), Messenger, etc. Quando encerramos um serviço, outros serviços no Aplicativo de Serviço onde o serviço está localizado não são encerrados.
No Delphi, os engenheiros da Borland nos fornecem TServiceApplication, TService, TServiceThread e outras classes, que encapsulam um grande número de detalhes e simplificam o desenvolvimento de programas de serviço.
2. Aplicação TService
No Delphi, a classe TServiceApplication corresponde ao ServiceApplication mencionado acima. Utilizando o ambiente de desenvolvimento Delphi, criamos um novo PRoject de Aplicação de Serviço e criamos uma classe herdada de TService. O objeto Application no arquivo de projeto é uma instância de TServiceApplication. Cada TServiceApplication contém vários objetos TService, que correspondem exatamente à relação quantitativa acima mencionada entre programas de serviço e serviços.
Lendo as definições das classes TServiceApplication e TService, podemos saber que TServiceApplication herda da classe TComponent, TService vem da classe TDataModule e o objeto Application é responsável por Criar e Destruir cada objeto TService. Acompanhe o seguinte código
Application.CreateForm(TService1, Serviço1);
Pode-se descobrir que os proprietários dos objetos TService criados são todos objetos Application no VCL FrameWork, o Owner é sempre responsável por destruir cada objeto Component (a classe TComponent da VCL adota o modo Composite), então TServiceApplication também destruirá cada objeto TService.
Seguindo o código de TServiceApplication.Run, você pode descobrir que TServiceApplication primeiro analisa os parâmetros de execução e implementa a instalação e desinstalação do serviço. Em seguida, inicialize um array ServiceStartTable, que contém o nome do serviço e a entrada em execução de cada objeto de serviço; finalmente, crie um objeto TServiceStartThread, que é um objeto de thread, e chame a API: StartServiceCtrlDispatcher do thread para iniciar vários serviços especificados em ServiceStartTable; O thread principal do ServiceApplication mantém o loop e o processamento de mensagens, como o recebimento de solicitações para parar/pausar um serviço.
3. Serviço T
A classe TService herda da classe TDataModule, o que significa que podemos adicionar um grande número de controles VCL para obter funções ricas. Além disso, também podemos lidar com OnStart, OnPause, OnStop, OnContinue, OnCreate, OnShutDown e outros eventos. O que precisa ser explicado é: OnStop significa que o serviço foi interrompido e OnShutDown significa que o ServiceApplication parou de funcionar, o que significa que outros serviços também foram encerrados;
Conforme mencionado anteriormente, ServiceApplication inicia cada serviço chamando StartServiceCtrlDispatcher. StartServiceCtrlDispatcher inicia a entrada do TService, que é TService.Main. TService.Main primeiro registra o serviço e depois chama TService.DoStart. TService.DoStart cria um objeto membro TServiceThread interno, que é um objeto thread; examinando TServiceThread.Execute, podemos saber que quando processamos TService1.OnExecute, então TService delegará todas as solicitações ao objeto membro TServiceThread para processamento. O método padrão lida com todas as solicitações.
TService. ServiceExecute é o conteúdo principal do TService. Para que um serviço funcione normalmente, além de lidar com os objetivos nos quais ele precisa se concentrar (como escutar uma determinada porta, executar uma determinada tarefa, etc.), ele também precisa responder a comandos/solicitações externas: como encerrar, pausar e retomar o serviço. Portanto, você pode considerar a criação de um thread dedicado para concluir esta tarefa e lidar com comandos/solicitações externas em ServiceExecute. Então o código é o seguinte:
enquanto não estiver terminado, comece
ServiceThread.ProcessRequests(Falso);
fim;
Claro, você também pode lidar com certas tarefas no OnExecute, como escutar uma determinada porta, mas isso geralmente faz com que o Serviço não seja capaz de responder a Parada/Pausa e outras solicitações em tempo hábil. Quando OnExecute for concluído, o serviço realmente concluiu sua tarefa e está prestes a terminar (terminar).
Referências:
MSDN, código-fonte Delphi VCL, documentação de ajuda do Delphi