I use FPC 3.0.4 on Windows 7 Home Premium, 32 bit. I open a console window, start test.exe and then shutdown Windows via START / Shutdown.Read the Windows 7+ remark in the Windows documentation https://docs.microsoft.com/en-us/windows/console/setconsolectrlhandler (https://docs.microsoft.com/en-us/windows/console/setconsolectrlhandler).
After reboot I check my logfile. Only the "Start" message is there. Here is my code: Do you see a mistake?
Read the Windows 7+ remark in the Windows documentation https://docs.microsoft.com/en-us/windows/console/setconsolectrlhandler (https://docs.microsoft.com/en-us/windows/console/setconsolectrlhandler).
A console application (on FPC) by default loads the user32.dll and gdi32.dll, as a result SetConsoleCtrlHandler is not called.
In the same place indicated the solution.
... then handle the WM_QUERYENDSESSION and WM_ENDSESSION window messages that the hidden window receives ...
LRESULT CALLBACK WindowProc(
HWND hwnd, // handle to window
UINT uMsg, // message identifier
WPARAM wParam, // not used
LPARAM lParam // logoff option
);
I'm a complete beginner to Messages and Callback functions. I read the documentation but didn't understand it. Can anybody please give an example? Thanks a lot.Then it is easier to do so:
Yes, now it is not a small console application. It is possible to choose another solution, but we need to understand what else your application should do.
Here is what my small console application does: it is started together with the OS via AutoStart and runs all the time in the background until OS shuts down. Every 30 seconds it looks for certain programs/processes if they are running and if yes, writes this into a SQLite database.It will then be easier. Use the main form instead of the data module. For ApplicationProperties, set the ShowMainForm=False property, and show the form only when you run the program with special keys to show statistics. Modify the form for easy display of statistics. Put on it the TTimer and configure it to regularly update the information in the database. I don't have Linux at hand, but I suspect it's a cross-platform solution.
My program can run twice at a time: once in the background (see above) and secondly in the foreground using some command line parameters to show statistics or to control or kill the background program. I have this program finished for Windows and Linux (Ubuntu). Now I want to write a message into the logfile, when the OS (Windows or Linux) shuts down.
Pipes and Process Termination
To provide a cross-platform solution for ... processes ... additional functions have been added:
TChildExitReason = (cerExit, cerSignal);
TChildExitEvent = procedure(AData: PtrInt; AReason: TChildExitReason; AInfo: dword) of object;
function AddProcessEventHandler(AHandle: THandle; AEventHandler: TChildExitEvent; AData: PtrInt): PProcessEventHandler;
When a process terminates the event handler specified will be called. AInfo will contain the exit code if AReason is cerExit, or (on unix only) the termination signal if AReason is cerSignal. For gtk/unix, use the PID to watch as AHandle. Internally, a signal handler is installed to catch the SIGCHLD signal. On win32, AddEventHandler is used to watch process termination.
[. . .]
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.
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
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
function AddProcessEventHandler(AHandle: THandle; AEventHandler: TChildExitEvent;
AData: PtrInt): PProcessEventHandler;
begin
Result:=WidgetSet.AddProcessEventHandler(AHandle, AEventHandler, AData);
end;