Recent

Author Topic: [CLOSED] How to call a routine when my program terminates by OS shutdown?  (Read 4235 times)

lucamar

  • Hero Member
  • *****
  • Posts: 1610
Re: How to call a routine when my program terminates by OS shutdown?
« Reply #15 on: January 11, 2019, 10:44:39 pm »
[. . .]
Could this be (another) solution to my problem? I found no documentation for AddProcessEventHandler(), so I can't estimate whether with this function I can write something into a logfile when the OS shuts down. Is there anybody who can tell this? If yes, where do I get the 'AHandle' from which I must pass to AddProcessEventHandler()? Thanks in advance.

I may wrong but I think AddProcessEventHandler() is meant to be used for child processes, not for the main process. But you can try it and see whether it works..

As for AHandle, it should be the handle/PID returned when you create a child process; there is a way to get the application handle (or PID in Unix) but I don't remember what it is ATM, sorry.
Turbo Pascal 3 CP/M - Amstrad PCW 8256 (512 KB !!!) :P
Lazarus 1.8.4 & 2.0.2 w/FPC 3.0.4 on:
(K|L)Ubuntu 12..16, Windows XP SP3, various DOSes.

Hartmut

  • Full Member
  • ***
  • Posts: 242
Re: How to call a routine when my program terminates by OS shutdown?
« Reply #16 on: January 12, 2019, 02:03:13 pm »
Hello again, lucamar. Thanks for your reply. To get the PID of a program you can use function system.GetProcessID().

I created a little demo for the idea in http://wiki.freepascal.org/Main_Loop_Hooks#Pipes_and_Process_Termination:
Code: Pascal  [Select]
  1. program test2;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. uses InterfaceBase,LCLIntf; // need Package "LCLBase"
  6.  
  7. type
  8.    TMyClass = Class(TObject)
  9.    procedure ChildExitEvent(AData: PtrInt; AReason: TChildExitReason; AInfo: dword); // of object;
  10.    end;
  11.  
  12. procedure TMyClass.ChildExitEvent(AData: PtrInt; AReason: TChildExitReason; AInfo: dword);
  13.    {my Exit-Procedure: must be a method of a Class, because it's usage in
  14.     AddProcessEventHandler() is declared as "procedure ... of object"}
  15.    begin
  16.    writeln('ChildExitEvent: ', AData, ' ', AReason, ' ', AInfo);
  17.    end;
  18.  
  19. var MyClass: TMyClass;
  20.  
  21. procedure install_ExitProc;
  22.    const AData = 0;
  23.    var pPEH: PProcessEventHandler; {=pointer}
  24.        h: THandle;
  25.    begin
  26.    h:=system.GetProcessID;
  27.    writeln('handle=', h);
  28.    pPEH:=AddProcessEventHandler(h, @MyClass.ChildExitEvent, AData);
  29.    end;
  30.  
  31. begin
  32. writeln('hello');
  33. MyClass:=TMyClass.Create;
  34. MyClass.ChildExitEvent(33,cerSignal,55); // only test if this method works
  35. install_ExitProc;
  36. readln;
  37. MyClass.Free;
  38. end.

It compiles with Lazarus 1.8.4 (FPC 3.0.4) but when I start it on Windows 7 (32 bit) I get:
Code: [Select]
An unhandled exception occurred at $00413F33:
EAccessViolation: Access violation
  $00413F33  ADDPROCESSEVENTHANDLER,  line 44 of ./include/lclintf.inc
  $0040180D  INSTALL_EXITPROC,  line 5779 of test2.pas
  $00401881  main,  line 35 of test2.pas 

On Linux (Ubuntu 18.04 64 bit) I get:
Code: [Select]
An unhandled exception occurred at $000000000043387D:
EAccessViolation: Access violation
  $000000000043387D line 44 of include/lclintf.inc
  $0000000000400DF0 line 28 of test2.pas
  $0000000000400E82 line 35 of test2.pas

Line 44 of include/lclintf.inc is:
Code: [Select]
function AddProcessEventHandler(AHandle: THandle; AEventHandler: TChildExitEvent;
  AData: PtrInt): PProcessEventHandler;
begin
  Result:=WidgetSet.AddProcessEventHandler(AHandle, AEventHandler, AData);
end;

I ran the program with the debugger, but that did not help me more. I tried older versions of Lazarus and FPC but got the same result, beside that FPC 2.6.4 says also "Runtime Error 210", which means "Object not initialized: When compiled with range checking on, a program will report this error if you call a virtual method without having called its object's constructor". But as far as I can see, the only object is MyClass and that is initialized...

I attached my little demo project. Can anybody help to avoid the Access violation?

Hartmut

  • Full Member
  • ***
  • Posts: 242
Re: How to call a routine when my program terminates by OS shutdown?
« Reply #17 on: January 17, 2019, 12:06:16 pm »
I closed this topic and opened a new one for questions about function AddProcessEventHandler() which has a better matching headline in https://forum.lazarus.freepascal.org/index.php/topic,43941.0.html