Fórum Criar uma aplicação que rode como Serviço no WinXP #235698

02/06/2004

0

Como faço p/ criar uma aplicação no delphi q rode como serviço no WinXP?









[color=red:eb34d40f57]Título alterado pelo Moderador oTTo. Removido: ´Serviço´.[/color:eb34d40f57]


Aamorim

Aamorim

Responder

Posts

10/06/2004

Lbcosta

primeiramente vc dever criar um novo projeto usando ´Service Application´. Vou colar abaixo um exemplo simples de serviço.

-------------------------------------------------------------------------------------

unit Unit1;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, SvcMgr, Dialogs;

type
TServiceThread = class(TThread)
private
{ Private declarations }
protected
procedure Execute; override;
end;

TService1 = class(TService)
procedure ServiceContinue(Sender: TService; var Continued: Boolean);
procedure ServicePause(Sender: TService; var Paused: Boolean);
procedure ServiceStart(Sender: TService; var Started: Boolean);
procedure ServiceStop(Sender: TService; var Stopped: Boolean);
private
{ Private declarations }
ServiceThread: TServiceThread;
public
function GetServiceController: TServiceController; override;
{ Public declarations }
end;

var
Service1: TService1;

implementation

{$R *.DFM}

procedure ServiceController(CtrlCode: DWord); stdcall;
begin
Service1.Controller(CtrlCode);
end;

function TService1.GetServiceController: TServiceController;
begin
Result := ServiceController;
end;

{ TServiceThread }

procedure TServiceThread.Execute;
begin
while not (Terminated) do
begin
// coloque aki o codigo que o serviço deve executar
end;
end;

{ TService1 }

procedure TService1.ServiceContinue(Sender: TService;
var Continued: Boolean);
begin
ServiceThread.Resume;
Continued := True;
end;

procedure TService1.ServicePause(Sender: TService; var Paused: Boolean);
begin
ServiceThread.Suspend;
Paused := True;
end;

procedure TService1.ServiceStart(Sender: TService; var Started: Boolean);
begin
ServiceThread := TServiceThread.Create(False);
Started := True;
end;

procedure TService1.ServiceStop(Sender: TService; var Stopped: Boolean);
begin
ServiceThread.Terminate;
Stopped := True;
end;

end.

-------------------------------------------------------------------------------------

Se o seu serviço tiver que obter alguma ação do usuário ou exibir alguma msg na tela a propriedade Interactive deve ser setada para True;

Para instalar o serviço vc deve digitar project1.exe /install
Para deinstalar o serviço vc deve digitar project1.exe /uninstall

Para rodar o serviço: net start ´nome do seu serviço´
Para parar o serviço: net stop ´nome do seu serviço´

O serviço tb pode ser iniciado e parado no ´gerenciador do computador´

O nome do serviço é definido no propriedade DisplayName

Espero que tenha ajudado.


Responder

Gostei + 0

05/09/2005

Ariovaldo

Senhores já estou a alguns dias tentando criar uma aplicação como Serviço e não estou conseguindo já encontrei alguns exemplos mas continuo sem solução, acontece o seguinte:

Este Serviço deve conectar-se ao Banco de Dados SQL Server não estou conseguindo conectar com o Banco pois já coloquei a Conexão em varios eventos em todos os casos a CPU da Maquina vai a 100¬ já coloquei o comando Slep más o problema persiste.

o Outro Problema é o seguinte meu serviço funciona atraves do componente Timer conforme o Exemplo Abaixo Meu código deveria ser locado dentro desta procedura porém preciso colocar no evento On timer do Componente Time como poderia fazer isso?

procedure TServiceThread.Execute;
begin
while not (Terminated) do
begin
// coloque aki o codigo que o serviço deve executar
end;
end;


Responder

Gostei + 0

05/09/2005

Massuda

Este Serviço deve conectar-se ao Banco de Dados SQL Server não estou conseguindo conectar com o Banco pois já coloquei a Conexão em varios eventos em todos os casos a CPU da Maquina vai a 100¬...
Talvez o serviço esteja tentando mostrar o dialog box pedindo nome de usuário e senha. Se for isso, o serviço está travado, pois por default um serviço não pode ter janelas (no sentido Windows).

Outra coisa que pode estar ocorrendo é que como os serviços são iniciados no boot do Windows, pode ser que sua conexão com o BD dependa de uma conexão de rede que ainda não está pronta para uso logo depois que o Windows boota.

...meu serviço funciona atraves do componente Timer...
O componente TTimer não funciona dentro de um serviço; isso acontece porque todo TTimer precisa criar uma janela (no sentido Windows) e por default um serviço não pode ter janelas. Você precisa usar outra forma, por exemplo fazendo o código esperar por um evento (usando, por exemplo, WaitForSingleObject) que nunca ocorrerá; nesse caso, o timeout de espera deve ser o tempo que você utilizaria no TTimer.


Responder

Gostei + 0

05/09/2005

Ariovaldo

Senhores com relação ao Processo da CPU eu aparentemente eu aparentemente solucionar aumentando o Sleep ao invés de colocar 1 eu coloquei 50 ainda não sei qual efeito Colateral que isso pode trazer.

Com relação ao Componente TTimer o Colega Massuda nos informou que não pode ser usado porém só para teste eu havia colocado esta Rotina abaixo para simplesmente a cada 1 Minuto ela escreva a data e a Hora em um arquivo texto para mim e aparentemente esta funcionando, más como o Massuda Informou o TTimer não deve ser Utilizado portanto gostaria de solicitar se alguém tiver uma rotina para escrever este mesmo Arquivo só que usando [b:2b5c494f13]WaitForSingleObject[/b:2b5c494f13] que foi a sugestão do Massuda.

procedure TFormServico.Timer1Timer(Sender: TObject);
Var
ArqTXT : TextFile;
Arq : String;
begin
Arq := extractFilePath(ParamStr(0)) + ´Arq\´ + ´Arq´ + FormatDateTime(´dd-mm-yyyy´,Date) + ´.TXT´;

AssignFile(ArqTXT,Arq);
If not FileExists(Arq) then
Rewrite(ArqTXT,Arq);

Append(ArqTXT);
WriteLn(ArqTXT, ´Data: ´ + FormatDateTime(´dd/mm/yyyy´,Date) + ´ Hora:´ + FormatDateTime(´hh:nn:ss´,Time));
CloseFile(ArqTXT);
end;


Responder

Gostei + 0

06/09/2005

Ariovaldo

Sobe .........


Responder

Gostei + 0

06/09/2005

Massuda

...TTimer ... não pode ser usado porém só para teste ... aparentemente esta funcionando...
Qual a versào do seu Delphi? Você alterou alguma configuração do serviço em Painel de Controle|Ferramentas Administrativas|Serviços?


Responder

Gostei + 0

06/09/2005

Ariovaldo

Não Massuda, apenas startei o serviço nem aquela opção interação com o usuario esta marcada. Estou com tres TTimer no serviço escrevendo em um arquivo só para teste e esta funcionando.


Responder

Gostei + 0

06/09/2005

Ariovaldo

Desculpa Massuda a Versão do Delphi é 7.0


Responder

Gostei + 0

06/09/2005

Ariovaldo

.Sobe


Responder

Gostei + 0

08/09/2005

Massuda

...tiver uma rotina para escrever este mesmo Arquivo só que usando [b:e58e97b525]WaitForSingleObject[/b:e58e97b525]...
Um jeito menos API e mais VCL de fazer isso seria (não testei)...
type 
  TServiceThread = class(TThread) 
  protected 
    procedure Execute; override; 
  end; 
....
uses
  SyncObjs,
...
procedure TServiceThread.Execute; 
var
  E: TEvent;
  ArqTXT: TextFile;
  Arq: String;
begin
  E := TEvent.Create(nil, False, False, ´´);

  while not (Terminated) do begin 
    
    E.WaitFor(1000);

    Arq  := ExtractFilePath(...
    AssignFile(ArqTXT, Arq);
    ....
    CloseFile(ArqTXT);
  end; 

  E.Free;
end;



Responder

Gostei + 0

26/09/2005

Ariovaldo

Senhores no caso que eu tenho 3 TTimer como eu faria isso, tentei criar mais uma Trhead mas não funcionaou.

Abraços


Responder

Gostei + 0

26/10/2005

Marioguedes

Olá! Gostaria de saber se continuam com problemas pois eu já tenho alguma experiência com serviços do windows, mas como o tópico é antigo não sei se eu vou chover no molhado...


Responder

Gostei + 0

18/01/2006

Ariovaldo

[quote:fd72a882b3=´Ariovaldo´]...tiver uma rotina para escrever este mesmo Arquivo só que usando [b:fd72a882b3]WaitForSingleObject[/b:fd72a882b3]...
Um jeito menos API e mais VCL de fazer isso seria (não testei)...
type 
  TServiceThread = class(TThread) 
  protected 
    procedure Execute; override; 
  end; 
....
uses
  SyncObjs,
...
procedure TServiceThread.Execute; 
var
  E: TEvent;
  ArqTXT: TextFile;
  Arq: String;
begin
  E := TEvent.Create(nil, False, False, ´´);

  while not (Terminated) do begin 
    
    E.WaitFor(1000);

    Arq  := ExtractFilePath(...
    AssignFile(ArqTXT, Arq);
    ....
    CloseFile(ArqTXT);
  end; 

  E.Free;
end;
[/quote:fd72a882b3]


Pessoal conforme o Exemplo acima escrito pelo Massuda eu consegui fazer funcionar as rotinas que precisam aguardar 1 Hora ou seja a cada 60 minutos a rotina é executada. agora eu tenho outra rotina que é executada a cada 10 Minuros neste caso como poderia ser feito? tenho que criar outro serviço ou existe como adicionar outra Thread e escrever o código nesta nova Thread?

Obrigado a todos


Responder

Gostei + 0

18/01/2006

Ariovaldo

Sobe


Responder

Gostei + 0

18/01/2006

Massuda

Você pode criar uma segunda thread que é executada a cada 10 minutos, basta usar a thread que você já tem como modelo.


Responder

Gostei + 0

Utilizamos cookies para fornecer uma melhor experiência para nossos usuários, consulte nossa política de privacidade.

Aceitar