Recent

Author Topic: Console app - how to cleanup after improper user termination?  (Read 1375 times)

dculp

  • Full Member
  • ***
  • Posts: 129
Console app - how to cleanup after improper user termination?
« on: November 07, 2019, 12:32:02 pm »
For a console app (run under Windows 7+), if the user improperly terminates the app by clicking the "X" in the upper right of the title bar, can the program still cleanup (e.g., close opened files, etc.)? For the following code, I couldn't get the "finalize" block to operate if the app is improperly closed at either of the first two readlns.

(There might be some way to disable the "X" but I wouldn't want to do that. If the app should hang without raising an exception, the user would then have no easy way to close the app.)

Code: Pascal  [Select][+][-]
  1. {$mode objfpc}{$H+}
  2. {$APPTYPE CONSOLE}
  3.  
  4. program Try_Except_Finally;
  5.  
  6. uses
  7.    SysUtils,  // required for type Exception
  8.    crt;
  9.  
  10. var
  11.    Debug_file: text;
  12.  
  13. begin
  14.  
  15. try
  16.    try
  17.    clrscr;
  18.    write('Press any key ... '); readln;
  19.    writeln(Debug_file, 'OK');  // create exception - file not open
  20.    except
  21.       on E: Exception do
  22.          begin
  23.          writeln('Exception block (file not open)'); readln;
  24.          end;
  25.    end;
  26.  
  27. finally // always executed, even regardless of exceptions
  28. writeln('finally block - do cleanup here!');
  29. readln;
  30. end;
  31.  
  32. end.  
  33.  

Thanks,
Don C.
« Last Edit: November 13, 2019, 01:04:42 pm by dculp »

440bx

  • Hero Member
  • *****
  • Posts: 3946
Re: Console app - how to cleanup after improper user termination?
« Reply #1 on: November 07, 2019, 12:56:42 pm »
The answer is yes. A console can get a notification from Windows for various events, among them, the close event.

To get those events you need to install a control handler.  It's fairly easy to do and MS has an example of how this is done at https://docs.microsoft.com/en-us/windows/console/registering-a-control-handler-function  the example is in C but, it's very simple, porting it to Pascal should be straightforward.

Also the example shows that there are a variety of events, in addition to a simple close event, a console app should be "mindful" of, for instance, ctrl-c and ctrl-break.  The example shows how to "trap" them.

HTH.
(FPC v3.0.4 and Lazarus 1.8.2) or (FPC v3.2.2 and Lazarus v3.2) on Windows 7 SP1 64bit.

Thaddy

  • Hero Member
  • *****
  • Posts: 14210
  • Probably until I exterminate Putin.
Re: Console app - how to cleanup after improper user termination?
« Reply #2 on: November 07, 2019, 01:06:30 pm »
And the system unit has already hooks/entrypoints that support it cross-platform.
Specialize a type, not a var.

440bx

  • Hero Member
  • *****
  • Posts: 3946
Re: Console app - how to cleanup after improper user termination?
« Reply #3 on: November 07, 2019, 01:42:30 pm »
And the system unit has already hooks/entrypoints that support it cross-platform.
By any chance, do you have a simple example of how to use the system unit facility to handle those events ? It would probably be useful to the OP and, I would be interested in seeing how it's done that way.
« Last Edit: November 07, 2019, 01:58:12 pm by 440bx »
(FPC v3.0.4 and Lazarus 1.8.2) or (FPC v3.2.2 and Lazarus v3.2) on Windows 7 SP1 64bit.

Thaddy

  • Hero Member
  • *****
  • Posts: 14210
  • Probably until I exterminate Putin.
Re: Console app - how to cleanup after improper user termination?
« Reply #4 on: November 07, 2019, 04:40:33 pm »
Example later, but relevant docs here:
 https://www.freepascal.org/docs-html/rtl/system/syssetctrlbreakhandler.html 
here https://www.freepascal.org/docs-html/rtl/system/exitproc.html
https://www.freepascal.org/docs-html/rtl/system/initproc.html
https://www.freepascal.org/docs-html/rtl/system/errorproc.html

All of these can be used, with the first one specifically for the purpose..
Note sysutils sets most of these, so you should chain the calls where  applicable
Specialize a type, not a var.

Cyrax

  • Hero Member
  • *****
  • Posts: 836
Re: Console app - how to cleanup after improper user termination?
« Reply #5 on: November 07, 2019, 09:13:02 pm »
https://docs.microsoft.com/en-us/windows/console/setconsolectrlhandler#remarks

Quote
Windows 7, Windows 8, Windows 8.1 and Windows 10:

If a console application loads the gdi32.dll or user32.dll library, the HandlerRoutine function that you specify when you call SetConsoleCtrlHandler does not get called for the CTRL_LOGOFF_EVENT and CTRL_SHUTDOWN_EVENT events. The operating system recognizes processes that load gdi32.dll or user32.dll as Windows applications rather than console applications. This behavior also occurs for console applications that do not call functions in gdi32.dll or user32.dll directly, but do call functions such as Shell functions that do in turn call functions in gdi32.dll or user32.dll.

To receive events when a user signs out or the device shuts down in these circumstances, create a hidden window in your console application, and then handle the WM_QUERYENDSESSION and WM_ENDSESSION window messages that the hidden window receives. You can create a hidden window by calling the CreateWindowEx method with the dwExStyle parameter set to 0.

Well, that sounds bad. Especially if you are making a service component (which is special console application) with FPC, because System unit links statically to user32.dll.

dculp

  • Full Member
  • ***
  • Posts: 129
Re: Console app - how to cleanup after improper user termination?
« Reply #6 on: November 12, 2019, 09:59:50 pm »
Example later
Have you been able to consider this further?

Quote
All of these can be used, with the first one specifically for the purpose..
Note sysutils sets most of these, so you should chain the calls where  applicable
I used InitProc and ExitProc many years ago in TP5 but I'm not sure how these would apply to my current request. Could you provide a short test example?

Thanks.

 

TinyPortal © 2005-2018