SHARE
TWEET

Delphi - ServiceApp

Macari Dec 13th, 2016 (edited) 98 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. unit unServicoThread;
  2.  
  3. interface
  4.  
  5. uses Windows, Messages, SysUtils, Classes, Graphics, Controls, SvcMgr, Dialogs, Registry, DB, ZAbstractRODataset, ZAbstractDataset, ZDataset,
  6.   ZAbstractConnection, ZConnection, DateUtils, unThreadCrons, ActnList, BotLibrary, ExtCtrls, uWin32_Process, uWmiDelphiClass, Variants, ActiveX;
  7.  
  8. type
  9.   TServicoCron = class(TService)
  10.     ActionList1: TActionList;
  11.     procedure ServiceCreate(Sender : TObject);
  12.     procedure ServiceExecute(Sender : TService);
  13.     procedure ServiceStop(Sender : TService; var Stopped : Boolean);
  14.     procedure ServiceStart(Sender : TService; var Started : Boolean);
  15.     procedure ServiceDestroy(Sender: TObject);
  16.     procedure ServiceShutdown(Sender: TService);
  17.     procedure ServiceAfterInstall(Sender: TService);
  18.     procedure ServiceContinue(Sender: TService; var Continued: Boolean);
  19.  
  20.   private
  21.     function ExecutaCron(Comando : string): Cardinal;
  22.   public
  23.     function GetServiceController : TServiceController; override;
  24.     function GetHora: TDateTime;
  25.  
  26.     procedure ServiceStopShutDown;
  27.     procedure GravaLog;
  28.  
  29.     procedure Log(x : String);
  30. //    procedure AdicionaItem(Item: ThreadCrons);
  31. //    procedure VerificaStatus;
  32.  
  33.     { Public declarations }
  34.   end;
  35.  
  36. var
  37.   ServicoCron : TServicoCron;
  38.   Servidor : String;
  39.   IDServidor : Integer;
  40.   CronQuery , Query: TZQuery;
  41.   Conexao : TZConnection;
  42.   Thread : ThreadCrons;
  43.   ListaThread : TList;
  44.   Log : TStringList;
  45.   Loop : Boolean;
  46.   FThread, PID : integer;
  47.   Lista : Tlist;
  48.   DataHoraAnt : TDateTime;
  49.  
  50. implementation
  51.  
  52. {$R *.DFM}
  53.  
  54.  
  55. procedure ServiceController(CtrlCode : DWord); stdcall;
  56. begin
  57.   ServicoCron.Controller(CtrlCode);
  58. end;
  59.  
  60. function TServicoCron.ExecutaCron(Comando: string): Cardinal;
  61. Var
  62.  Process : TWin32_Process;
  63.  PID,Resultado : Cardinal;
  64. begin
  65.   try
  66.     Result  := 0;
  67.  
  68.     Process   := TWin32_Process.Create(True);
  69.     Resultado := Process.Create(Comando, 'C:\Windows' ,Unassigned, PID);
  70.  
  71.     result := PID;
  72.   except
  73.     on e : exception do
  74.       Log('Erro: ' + e.message + ' Comando: '+Comando+' '+TimeToStr(Now) );
  75.   end;
  76. end;
  77.  
  78. function TServicoCron.GetHora: TDateTime;
  79. begin
  80.   Query.SQL.Text := 'select current_timestamp + interval '+QuotedStr('1 minutes');
  81.   Query.Open;
  82.  
  83.   Result := Query.Fields[0].AsDateTime;
  84.   Query.Close;
  85. end;
  86.  
  87. function TServicoCron.GetServiceController : TServiceController;
  88. begin
  89.   Result := ServiceController;
  90. end;
  91.  
  92. procedure TServicoCron.GravaLog;
  93. begin
  94.   Query.SQL.Clear;
  95.   Query.SQL.Add('update servidores set atualizacao_cron = clock_timestamp() where servidor = :pID');
  96.   Query.ParamByName('pID').AsInteger := IDServidor;
  97.   Query.ExecSQL;
  98. end;
  99.  
  100. procedure TServicoCron.Log(x : String);
  101. var
  102.   Lista : TStringList;
  103.   Arquivo : string;
  104. begin
  105.   Arquivo := 'C:\Errolog.txt';
  106.   Lista := TStringList.Create;
  107.   if not FileExists(Arquivo) then
  108.     Lista.SaveToFile(Arquivo);
  109.   Lista.LoadFromFile(Arquivo);
  110.   Lista.Add( DateTimeToStr(Now)+ ' - ' + x);
  111.   Lista.SaveToFile(Arquivo);
  112.   Lista.Free;
  113. end;
  114.  
  115. procedure TServicoCron.ServiceAfterInstall(Sender: TService);
  116. var
  117.   Reg: TRegistry;
  118. begin
  119.   Reg := TRegistry.Create(KEY_READ or KEY_WRITE);
  120.   try
  121.     Reg.RootKey := HKEY_LOCAL_MACHINE;
  122.     if Reg.OpenKey('\SYSTEM\CurrentControlSet\Services\ServicoCron', false) then
  123.     begin
  124.       Reg.WriteString('Description', 'Controle de Crons');
  125.       Reg.CloseKey;
  126.     end;
  127.   finally
  128.     Reg.Free;
  129.   end;
  130. end;
  131.  
  132. procedure TServicoCron.ServiceContinue(Sender: TService; var Continued: Boolean);
  133. begin
  134.   GetServiceController;
  135. end;
  136.  
  137. procedure TServicoCron.ServiceCreate(Sender : TObject);
  138. var Registro : TRegistry;
  139. begin
  140.   try
  141.     Registro := TRegistry.Create;
  142.     Registro.RootKey := HKEY_LOCAL_MACHINE;
  143.     Registro.OpenKey('SOFTWARE\WebGlobal', true);
  144.     Servidor   := Registro.ReadString('Servidor');
  145.     IDServidor := Registro.ReadInteger('ServidorID');
  146.     Log('Servidor definido: '+Servidor);
  147.  
  148.     Conexao := TZConnection.Create(nil);
  149.  
  150.     Conexao.DataBase := 'WebBot';
  151.     Conexao.HostName := 'webglobaldb1.com.br';
  152.     Conexao.LoginPrompt := false;
  153.     Conexao.Password := 'botcron123';
  154.     Conexao.Protocol := 'postgresql-9';
  155.     Conexao.User := 'BotCron';
  156.     Conexao.Connect;
  157.  
  158.     Log('Conectou Banco');
  159.  
  160.     CronQuery := TZQuery.Create(nil);
  161.     CronQuery.Connection := Conexao;
  162.  
  163.     Query := TZQuery.Create(nil);
  164.     Query.Connection := Conexao;
  165.  
  166.     DataHoraAnt := now;
  167.   except
  168.     on e : Exception do
  169.     begin
  170.       LogErro('Erro ao Conectar a base de dados - Thread Crons','',e.Message,'BotCron');
  171.       Log('Erro: '+e.message);
  172.     end;
  173.   end;
  174.  
  175.   FThread := 0;
  176.   Loop := true;
  177.  
  178. //  ServicoCron.ServiceExecute(ServicoCron); //usar somente em debug
  179. end;
  180.  
  181. procedure TServicoCron.ServiceDestroy(Sender: TObject);
  182. begin
  183.   Log('ServiceDestroy');
  184.   Loop := False;
  185.   self := nil;
  186.   self.Free;
  187. end;
  188.  
  189. procedure TServicoCron.ServiceExecute(Sender : TService);
  190. var
  191.   Hora : TTime;
  192.   Inicia ,Forcar : boolean;
  193.   Hoje,ProximaExecucao : TDateTime;
  194.   Dia,TempPID : integer;
  195.   mDia,mAno,mMes : Word;
  196.  
  197.   procedure AdicionaItem(Item : ThreadCrons);
  198.   begin
  199.     ListaThread.Add(Item);
  200.     Item.Start;
  201.   end;
  202.  
  203.   procedure VerificaSituacao;
  204.   var x : integer;
  205.   begin
  206.     try
  207.       for x := ListaThread.Count - 1 downto 0 do
  208.       begin
  209.         if ThreadCrons(ListaThread.Items[x]).Situacao = 1 then
  210.         begin
  211.           ThreadCrons(ListaThread.Items[x]).Terminate;
  212.           ThreadCrons(ListaThread.Items[x]).Free;
  213.           ListaThread.Delete(x);
  214.         end;
  215.       end;
  216.     except
  217.       on e : Exception do
  218.         LogErro('Erro ao Limpar Lista de Threads - Id Loop :' + IntToStr(X),'',e.Message,'BotCron');
  219.     end;
  220.   end;
  221.  
  222.   function VerificaStatus(Disparador : integer; Msg : string; Concorrencia : Boolean = false) : Boolean;
  223.   var
  224.     x: Integer;
  225.   begin
  226.     try
  227.       Result := true;
  228.       for x := 0 to ListaThread.Count - 1 do
  229.       begin
  230.         if (ThreadCrons(ListaThread.Items[x]).Disparador = Disparador) and (ThreadCrons(ListaThread.Items[x]).ProcessoVivo) then
  231.         begin
  232.           ThreadCrons(ListaThread.Items[x]).MsgKill := Msg;
  233.  
  234.           if not Concorrencia then
  235.             ThreadCrons(ListaThread.Items[x]).ProcessTerminate
  236.           else
  237.           begin
  238.             ThreadCrons(ListaThread.Items[x]).Concorrencia := True;
  239.             ThreadCrons(ListaThread.Items[x]).CountConcorrencia := ThreadCrons(ListaThread.Items[x]).CountConcorrencia + 1;
  240.             Result := false;
  241.           end;
  242.  
  243.           Sleep(100);
  244.           exit;
  245.         end;
  246.       end;
  247.     Except
  248.       on e : Exception do
  249.         LogErro('Erro ao Matar Processo - Id Disparador :' + IntToStr(Disparador),'',e.Message,'BotCron');
  250.     end;
  251.   end;
  252.  
  253. begin
  254.   CoInitialize(nil);
  255.   ListaThread := TList.Create;
  256.   if Conexao.PingServer then
  257.   while loop do
  258.   begin
  259.     if Now > DataHoraAnt then
  260.     begin
  261.       GravaLog;
  262.       DataHoraAnt := GetHora;
  263.     end;
  264.  
  265.     if Conexao.PingServer then
  266.     begin
  267.       try
  268.         VerificaSituacao;
  269.  
  270.         CronQuery.Close;
  271.         CronQuery.SQL.text := 'select cr.* , cast(cd.datainicio as date) datainicio , cp.* , cd.* , (extract(epoch from intervalo_interrupcao)*1000)  interrupcao' +
  272.                               ' , cp.nome as nomeprocesso,clock_timestamp() '+
  273.                               '  from crons cr' +
  274.                               '  left join crons_disparadores cd on cr.cron = cd.cron' +
  275.                               '  left join crons_processos cp on cr.processo = cp.processo' +
  276.                               '  left join servidores se on se.servidor = cr.servidor ' +
  277.                               ' where cr.ativo = true and cd.ativo = true and se.nome = :pServidor and (proxima_execucao < clock_timestamp()  '+
  278.                               '    or forcar_execucao = true or parar_execucao = true)';
  279.         CronQuery.ParamByName('pServidor').AsString := 'ROBO 2';
  280.         CronQuery.Open;
  281.  
  282.         CronQuery.First;
  283.         while not CronQuery.Eof do
  284.         begin
  285.           Inicia := False;
  286.           Forcar := False;
  287.  
  288.           Hoje := CronQuery.FieldByName('clock_timestamp').AsDateTime;
  289.  
  290.           if CronQuery.FieldByName('parar_execucao').AsBoolean then
  291.           begin
  292.             GravaMensagem(CronQuery.FieldByName('disparador').AsInteger,'Parado Pelo Usuário.');
  293.  
  294.             Query.SQL.Clear;
  295.             Query.SQL.Add('update crons_disparadores set parar_execucao = false, pid = null where disparador = :pDisparador');
  296.             Query.ParamByName('pDisparador').AsInteger :=  CronQuery.FieldByName('disparador').AsInteger;
  297.             Query.ExecSQL;
  298.  
  299.             VerificaStatus(CronQuery.FieldByName('disparador').AsInteger,'Parada Forçada pelo Usuário');
  300.  
  301.             CronQuery.Next;
  302.             Continue;
  303.           end;
  304.  
  305.           if CronQuery.FieldByName('forcar_execucao').AsBoolean = true then
  306.           begin
  307.             Forcar := True;
  308.             Inicia := True;
  309.  
  310.             Query.SQL.Clear;
  311.             Query.SQL.Add('update crons_disparadores set forcar_execucao = false where disparador = :pDisparador');
  312.             Query.ParamByName('pDisparador').AsInteger := CronQuery.FieldByName('disparador').AsInteger;
  313.             Query.ExecSQL;
  314.           end
  315.           else
  316.           begin
  317.             if CronQuery.FieldByName('datainicio').AsDateTime < Hoje then
  318.             begin
  319.               if TimeToStr(CronQuery.FieldByName('horainicio').AsDateTime) < TimeToStr(Hoje) then
  320.               begin
  321.                 if not (CronQuery.FieldByName('intervalo').AsBoolean) then
  322.                   Inicia := True
  323.                 else
  324.                 begin
  325.                   Dia := DayOfWeek(Hoje) - 1;
  326.                   if (CronQuery.FieldByName('dia' + IntToStr(Dia)).AsBoolean) then
  327.                   begin
  328.                     if (CronQuery.FieldByName('apartir_dia').AsInteger > 0) then
  329.                     begin
  330.                       DecodeDate(Now,mAno,mMes,mDia);
  331.  
  332.                       if mDia >= CronQuery.FieldByName('apartir_dia').AsInteger then
  333.                         Inicia := True
  334.                       else
  335.                       begin
  336.                         ProximaExecucao := CalculaProximaExecucao(CronQuery.FieldByName('horainicio').AsString,
  337.                                                                   CronQuery.FieldByName('intervalo_repeticao').AsString,Query,Conexao);
  338.  
  339.                         DecodeDate(ProximaExecucao,mAno,mMes,mDia);
  340.  
  341.                         if (mDia > CronQuery.FieldByName('apartir_dia').AsInteger) then
  342.                           ProximaExecucao := ProximaExecucao - (DaysBetween(mDia,CronQuery.FieldByName('apartir_dia').AsInteger));
  343.  
  344.                         Query.SQL.Clear;
  345.                         Query.SQL.Add('update crons_disparadores set proxima_execucao = :pProxima where disparador = :pDisparador');
  346.                         Query.ParamByName('pDisparador').AsInteger := CronQuery.FieldByName('disparador').AsInteger;
  347.                         Query.ParamByName('pProxima').AsDateTime   := ProximaExecucao;
  348.                         Query.ExecSQL;
  349.                       end;
  350.                     end
  351.                     else
  352.                       Inicia := True;
  353.                   end
  354.                   else
  355.                   begin
  356.                     Query.SQL.Clear;
  357.                     Query.SQL.Add('update crons_disparadores set proxima_execucao = proxima_execucao + interval :pIntervalo where disparador = :pDisparador');
  358.                     Query.ParamByName('pDisparador').AsInteger := CronQuery.FieldByName('disparador').AsInteger;
  359.                     Query.ParamByName('pIntervalo').AsString   := '1 Day';
  360.                     Query.ExecSQL;
  361.                   end;
  362.                 end;
  363.               end;
  364.             end;
  365.           end;
  366.  
  367.           if Inicia then
  368.           begin
  369.             ProximaExecucao := CalculaProximaExecucao(CronQuery.FieldByName('horainicio').AsString,
  370.                                                       CronQuery.FieldByName('intervalo_repeticao').AsString,Query,Conexao);
  371.  
  372.             Query.SQL.Clear;
  373.             Query.SQL.Add('update crons_disparadores set ultima_execucao = clock_timestamp(), proxima_execucao = :pProxima where disparador = :pDisparador');
  374.             Query.ParamByName('pDisparador').AsInteger := CronQuery.FieldByName('disparador').AsInteger;
  375.             Query.ParamByName('pProxima').AsDateTime   := ProximaExecucao;
  376.             Query.ExecSQL;
  377.  
  378.             if FileExists(CronQuery.FieldByName('path').AsString) then
  379.             begin
  380.               try
  381.                 if VerificaStatus(CronQuery.FieldByName('disparador').AsInteger,'', True) then
  382.                 begin
  383.                   TempPID := ExecutaCron(CronQuery.FieldByName('path').AsString + ' ' + CronQuery.FieldByName('argumentos').AsString);
  384.                   if TempPID > 0 then
  385.                   begin
  386.                     Log('Processo criado - PID ' + IntToStr(TempPID));
  387.  
  388.                     AdicionaItem(
  389.                     ThreadCrons.Create(Forcar, TempPID, CronQuery.FieldByName('cron').AsInteger,
  390.                                                CronQuery.FieldByName('disparador').AsInteger,
  391.                                                CronQuery.FieldByName('interrupcao').AsInteger));
  392.                   end
  393.                   else
  394.                     Log('Erro ao criar processo - PID 0');
  395.                 end;
  396.               except
  397.                 on e : exception do
  398.                   Log('Erro: ' + e.message + TimeToStr(Now) );
  399.               end;
  400.             end;
  401.           end;
  402.         CronQuery.Next;
  403.       end
  404.       except
  405.         on e : exception do
  406.           Log('Erro: ' + e.message + ' Disparador '  + CronQuery.FieldByName('disparador').AsString);
  407.       end;
  408.       Sleep(500);
  409.       ServiceThread.ProcessRequests(False);
  410.     end
  411.     else
  412.       Sleep(30000);
  413.   end;
  414.   ListaThread.Free;
  415.   CoUninitialize;
  416. end;
  417.  
  418. procedure TServicoCron.ServiceShutdown(Sender: TService);
  419. begin
  420.   Log('ServiceShutdown');
  421.   FreeAndNil(Self);
  422. end;
  423.  
  424. procedure TServicoCron.ServiceStart(Sender : TService; var Started : Boolean);
  425. begin
  426.   Loop := true;
  427.   Log('Start');
  428. end;
  429.  
  430. procedure TServicoCron.ServiceStop(Sender : TService; var Stopped : Boolean);
  431. begin
  432.   try
  433.     ServiceThread.ProcessRequests(False);
  434.     Loop := false;
  435.     ServiceStopShutDown;
  436.     Log('ServiceStop');
  437.   except
  438.     on e: exception do
  439.       LogErro(Conexao, 'Erro ao Tentar Parar Serviço - Thread Crons','',e.Message,'BotCron');
  440.   end;
  441. end;
  442.  
  443. procedure TServicoCron.ServiceStopShutDown;
  444. var X: integer;
  445. begin
  446.   for x := 0 to ListaThread.count - 1 do
  447.   begin
  448.     ThreadCrons(ListaThread.Items[x]).MsgKill := 'Serviço Interrompido';
  449.     ThreadCrons(ListaThread.Items[x]).ProcessTerminate;
  450.   end;
  451.  
  452.   ListaThread.Free;
  453. end;
  454.  
  455.  
  456. end.
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top