Advertisement
Macari

Delphi - ServiceApp

Dec 13th, 2016
127
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 14.70 KB | None | 0 0
  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.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement