Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- unit unServicoThread;
- interface
- uses Windows, Messages, SysUtils, Classes, Graphics, Controls, SvcMgr, Dialogs, Registry, DB, ZAbstractRODataset, ZAbstractDataset, ZDataset,
- ZAbstractConnection, ZConnection, DateUtils, unThreadCrons, ActnList, BotLibrary, ExtCtrls, uWin32_Process, uWmiDelphiClass, Variants, ActiveX;
- type
- TServicoCron = class(TService)
- ActionList1: TActionList;
- procedure ServiceCreate(Sender : TObject);
- procedure ServiceExecute(Sender : TService);
- procedure ServiceStop(Sender : TService; var Stopped : Boolean);
- procedure ServiceStart(Sender : TService; var Started : Boolean);
- procedure ServiceDestroy(Sender: TObject);
- procedure ServiceShutdown(Sender: TService);
- procedure ServiceAfterInstall(Sender: TService);
- procedure ServiceContinue(Sender: TService; var Continued: Boolean);
- private
- function ExecutaCron(Comando : string): Cardinal;
- public
- function GetServiceController : TServiceController; override;
- function GetHora: TDateTime;
- procedure ServiceStopShutDown;
- procedure GravaLog;
- procedure Log(x : String);
- // procedure AdicionaItem(Item: ThreadCrons);
- // procedure VerificaStatus;
- { Public declarations }
- end;
- var
- ServicoCron : TServicoCron;
- Servidor : String;
- IDServidor : Integer;
- CronQuery , Query: TZQuery;
- Conexao : TZConnection;
- Thread : ThreadCrons;
- ListaThread : TList;
- Log : TStringList;
- Loop : Boolean;
- FThread, PID : integer;
- Lista : Tlist;
- DataHoraAnt : TDateTime;
- implementation
- {$R *.DFM}
- procedure ServiceController(CtrlCode : DWord); stdcall;
- begin
- ServicoCron.Controller(CtrlCode);
- end;
- function TServicoCron.ExecutaCron(Comando: string): Cardinal;
- Var
- Process : TWin32_Process;
- PID,Resultado : Cardinal;
- begin
- try
- Result := 0;
- Process := TWin32_Process.Create(True);
- Resultado := Process.Create(Comando, 'C:\Windows' ,Unassigned, PID);
- result := PID;
- except
- on e : exception do
- Log('Erro: ' + e.message + ' Comando: '+Comando+' '+TimeToStr(Now) );
- end;
- end;
- function TServicoCron.GetHora: TDateTime;
- begin
- Query.SQL.Text := 'select current_timestamp + interval '+QuotedStr('1 minutes');
- Query.Open;
- Result := Query.Fields[0].AsDateTime;
- Query.Close;
- end;
- function TServicoCron.GetServiceController : TServiceController;
- begin
- Result := ServiceController;
- end;
- procedure TServicoCron.GravaLog;
- begin
- Query.SQL.Clear;
- Query.SQL.Add('update servidores set atualizacao_cron = clock_timestamp() where servidor = :pID');
- Query.ParamByName('pID').AsInteger := IDServidor;
- Query.ExecSQL;
- end;
- procedure TServicoCron.Log(x : String);
- var
- Lista : TStringList;
- Arquivo : string;
- begin
- Arquivo := 'C:\Errolog.txt';
- Lista := TStringList.Create;
- if not FileExists(Arquivo) then
- Lista.SaveToFile(Arquivo);
- Lista.LoadFromFile(Arquivo);
- Lista.Add( DateTimeToStr(Now)+ ' - ' + x);
- Lista.SaveToFile(Arquivo);
- Lista.Free;
- end;
- procedure TServicoCron.ServiceAfterInstall(Sender: TService);
- var
- Reg: TRegistry;
- begin
- Reg := TRegistry.Create(KEY_READ or KEY_WRITE);
- try
- Reg.RootKey := HKEY_LOCAL_MACHINE;
- if Reg.OpenKey('\SYSTEM\CurrentControlSet\Services\ServicoCron', false) then
- begin
- Reg.WriteString('Description', 'Controle de Crons');
- Reg.CloseKey;
- end;
- finally
- Reg.Free;
- end;
- end;
- procedure TServicoCron.ServiceContinue(Sender: TService; var Continued: Boolean);
- begin
- GetServiceController;
- end;
- procedure TServicoCron.ServiceCreate(Sender : TObject);
- var Registro : TRegistry;
- begin
- try
- Registro := TRegistry.Create;
- Registro.RootKey := HKEY_LOCAL_MACHINE;
- Registro.OpenKey('SOFTWARE\WebGlobal', true);
- Servidor := Registro.ReadString('Servidor');
- IDServidor := Registro.ReadInteger('ServidorID');
- Log('Servidor definido: '+Servidor);
- Conexao := TZConnection.Create(nil);
- Conexao.DataBase := 'WebBot';
- Conexao.HostName := 'webglobaldb1.com.br';
- Conexao.LoginPrompt := false;
- Conexao.Password := 'botcron123';
- Conexao.Protocol := 'postgresql-9';
- Conexao.User := 'BotCron';
- Conexao.Connect;
- Log('Conectou Banco');
- CronQuery := TZQuery.Create(nil);
- CronQuery.Connection := Conexao;
- Query := TZQuery.Create(nil);
- Query.Connection := Conexao;
- DataHoraAnt := now;
- except
- on e : Exception do
- begin
- LogErro('Erro ao Conectar a base de dados - Thread Crons','',e.Message,'BotCron');
- Log('Erro: '+e.message);
- end;
- end;
- FThread := 0;
- Loop := true;
- // ServicoCron.ServiceExecute(ServicoCron); //usar somente em debug
- end;
- procedure TServicoCron.ServiceDestroy(Sender: TObject);
- begin
- Log('ServiceDestroy');
- Loop := False;
- self := nil;
- self.Free;
- end;
- procedure TServicoCron.ServiceExecute(Sender : TService);
- var
- Hora : TTime;
- Inicia ,Forcar : boolean;
- Hoje,ProximaExecucao : TDateTime;
- Dia,TempPID : integer;
- mDia,mAno,mMes : Word;
- procedure AdicionaItem(Item : ThreadCrons);
- begin
- ListaThread.Add(Item);
- Item.Start;
- end;
- procedure VerificaSituacao;
- var x : integer;
- begin
- try
- for x := ListaThread.Count - 1 downto 0 do
- begin
- if ThreadCrons(ListaThread.Items[x]).Situacao = 1 then
- begin
- ThreadCrons(ListaThread.Items[x]).Terminate;
- ThreadCrons(ListaThread.Items[x]).Free;
- ListaThread.Delete(x);
- end;
- end;
- except
- on e : Exception do
- LogErro('Erro ao Limpar Lista de Threads - Id Loop :' + IntToStr(X),'',e.Message,'BotCron');
- end;
- end;
- function VerificaStatus(Disparador : integer; Msg : string; Concorrencia : Boolean = false) : Boolean;
- var
- x: Integer;
- begin
- try
- Result := true;
- for x := 0 to ListaThread.Count - 1 do
- begin
- if (ThreadCrons(ListaThread.Items[x]).Disparador = Disparador) and (ThreadCrons(ListaThread.Items[x]).ProcessoVivo) then
- begin
- ThreadCrons(ListaThread.Items[x]).MsgKill := Msg;
- if not Concorrencia then
- ThreadCrons(ListaThread.Items[x]).ProcessTerminate
- else
- begin
- ThreadCrons(ListaThread.Items[x]).Concorrencia := True;
- ThreadCrons(ListaThread.Items[x]).CountConcorrencia := ThreadCrons(ListaThread.Items[x]).CountConcorrencia + 1;
- Result := false;
- end;
- Sleep(100);
- exit;
- end;
- end;
- Except
- on e : Exception do
- LogErro('Erro ao Matar Processo - Id Disparador :' + IntToStr(Disparador),'',e.Message,'BotCron');
- end;
- end;
- begin
- CoInitialize(nil);
- ListaThread := TList.Create;
- if Conexao.PingServer then
- while loop do
- begin
- if Now > DataHoraAnt then
- begin
- GravaLog;
- DataHoraAnt := GetHora;
- end;
- if Conexao.PingServer then
- begin
- try
- VerificaSituacao;
- CronQuery.Close;
- CronQuery.SQL.text := 'select cr.* , cast(cd.datainicio as date) datainicio , cp.* , cd.* , (extract(epoch from intervalo_interrupcao)*1000) interrupcao' +
- ' , cp.nome as nomeprocesso,clock_timestamp() '+
- ' from crons cr' +
- ' left join crons_disparadores cd on cr.cron = cd.cron' +
- ' left join crons_processos cp on cr.processo = cp.processo' +
- ' left join servidores se on se.servidor = cr.servidor ' +
- ' where cr.ativo = true and cd.ativo = true and se.nome = :pServidor and (proxima_execucao < clock_timestamp() '+
- ' or forcar_execucao = true or parar_execucao = true)';
- CronQuery.ParamByName('pServidor').AsString := 'ROBO 2';
- CronQuery.Open;
- CronQuery.First;
- while not CronQuery.Eof do
- begin
- Inicia := False;
- Forcar := False;
- Hoje := CronQuery.FieldByName('clock_timestamp').AsDateTime;
- if CronQuery.FieldByName('parar_execucao').AsBoolean then
- begin
- GravaMensagem(CronQuery.FieldByName('disparador').AsInteger,'Parado Pelo Usuário.');
- Query.SQL.Clear;
- Query.SQL.Add('update crons_disparadores set parar_execucao = false, pid = null where disparador = :pDisparador');
- Query.ParamByName('pDisparador').AsInteger := CronQuery.FieldByName('disparador').AsInteger;
- Query.ExecSQL;
- VerificaStatus(CronQuery.FieldByName('disparador').AsInteger,'Parada Forçada pelo Usuário');
- CronQuery.Next;
- Continue;
- end;
- if CronQuery.FieldByName('forcar_execucao').AsBoolean = true then
- begin
- Forcar := True;
- Inicia := True;
- Query.SQL.Clear;
- Query.SQL.Add('update crons_disparadores set forcar_execucao = false where disparador = :pDisparador');
- Query.ParamByName('pDisparador').AsInteger := CronQuery.FieldByName('disparador').AsInteger;
- Query.ExecSQL;
- end
- else
- begin
- if CronQuery.FieldByName('datainicio').AsDateTime < Hoje then
- begin
- if TimeToStr(CronQuery.FieldByName('horainicio').AsDateTime) < TimeToStr(Hoje) then
- begin
- if not (CronQuery.FieldByName('intervalo').AsBoolean) then
- Inicia := True
- else
- begin
- Dia := DayOfWeek(Hoje) - 1;
- if (CronQuery.FieldByName('dia' + IntToStr(Dia)).AsBoolean) then
- begin
- if (CronQuery.FieldByName('apartir_dia').AsInteger > 0) then
- begin
- DecodeDate(Now,mAno,mMes,mDia);
- if mDia >= CronQuery.FieldByName('apartir_dia').AsInteger then
- Inicia := True
- else
- begin
- ProximaExecucao := CalculaProximaExecucao(CronQuery.FieldByName('horainicio').AsString,
- CronQuery.FieldByName('intervalo_repeticao').AsString,Query,Conexao);
- DecodeDate(ProximaExecucao,mAno,mMes,mDia);
- if (mDia > CronQuery.FieldByName('apartir_dia').AsInteger) then
- ProximaExecucao := ProximaExecucao - (DaysBetween(mDia,CronQuery.FieldByName('apartir_dia').AsInteger));
- Query.SQL.Clear;
- Query.SQL.Add('update crons_disparadores set proxima_execucao = :pProxima where disparador = :pDisparador');
- Query.ParamByName('pDisparador').AsInteger := CronQuery.FieldByName('disparador').AsInteger;
- Query.ParamByName('pProxima').AsDateTime := ProximaExecucao;
- Query.ExecSQL;
- end;
- end
- else
- Inicia := True;
- end
- else
- begin
- Query.SQL.Clear;
- Query.SQL.Add('update crons_disparadores set proxima_execucao = proxima_execucao + interval :pIntervalo where disparador = :pDisparador');
- Query.ParamByName('pDisparador').AsInteger := CronQuery.FieldByName('disparador').AsInteger;
- Query.ParamByName('pIntervalo').AsString := '1 Day';
- Query.ExecSQL;
- end;
- end;
- end;
- end;
- end;
- if Inicia then
- begin
- ProximaExecucao := CalculaProximaExecucao(CronQuery.FieldByName('horainicio').AsString,
- CronQuery.FieldByName('intervalo_repeticao').AsString,Query,Conexao);
- Query.SQL.Clear;
- Query.SQL.Add('update crons_disparadores set ultima_execucao = clock_timestamp(), proxima_execucao = :pProxima where disparador = :pDisparador');
- Query.ParamByName('pDisparador').AsInteger := CronQuery.FieldByName('disparador').AsInteger;
- Query.ParamByName('pProxima').AsDateTime := ProximaExecucao;
- Query.ExecSQL;
- if FileExists(CronQuery.FieldByName('path').AsString) then
- begin
- try
- if VerificaStatus(CronQuery.FieldByName('disparador').AsInteger,'', True) then
- begin
- TempPID := ExecutaCron(CronQuery.FieldByName('path').AsString + ' ' + CronQuery.FieldByName('argumentos').AsString);
- if TempPID > 0 then
- begin
- Log('Processo criado - PID ' + IntToStr(TempPID));
- AdicionaItem(
- ThreadCrons.Create(Forcar, TempPID, CronQuery.FieldByName('cron').AsInteger,
- CronQuery.FieldByName('disparador').AsInteger,
- CronQuery.FieldByName('interrupcao').AsInteger));
- end
- else
- Log('Erro ao criar processo - PID 0');
- end;
- except
- on e : exception do
- Log('Erro: ' + e.message + TimeToStr(Now) );
- end;
- end;
- end;
- CronQuery.Next;
- end
- except
- on e : exception do
- Log('Erro: ' + e.message + ' Disparador ' + CronQuery.FieldByName('disparador').AsString);
- end;
- Sleep(500);
- ServiceThread.ProcessRequests(False);
- end
- else
- Sleep(30000);
- end;
- ListaThread.Free;
- CoUninitialize;
- end;
- procedure TServicoCron.ServiceShutdown(Sender: TService);
- begin
- Log('ServiceShutdown');
- FreeAndNil(Self);
- end;
- procedure TServicoCron.ServiceStart(Sender : TService; var Started : Boolean);
- begin
- Loop := true;
- Log('Start');
- end;
- procedure TServicoCron.ServiceStop(Sender : TService; var Stopped : Boolean);
- begin
- try
- ServiceThread.ProcessRequests(False);
- Loop := false;
- ServiceStopShutDown;
- Log('ServiceStop');
- except
- on e: exception do
- LogErro(Conexao, 'Erro ao Tentar Parar Serviço - Thread Crons','',e.Message,'BotCron');
- end;
- end;
- procedure TServicoCron.ServiceStopShutDown;
- var X: integer;
- begin
- for x := 0 to ListaThread.count - 1 do
- begin
- ThreadCrons(ListaThread.Items[x]).MsgKill := 'Serviço Interrompido';
- ThreadCrons(ListaThread.Items[x]).ProcessTerminate;
- end;
- ListaThread.Free;
- end;
- end.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement