Note for someone trying to prevent this behaviour...
(after long time asking and testing several options provided by google gemini)
At the end, it realize what I supossed just by intuition, that is: Windows close the process by "killing it" not by "regular close"
Regards
<LAST GEMINI ANSWER - INI>
At this point, we've exhausted all avenues for manipulating the Windows API for a pure console application (GTWIN).
If `SetConsoleCtrlHandler` returning `TRUE` doesn't prevent the process from closing, it's due to a structural change in Windows 11: the new Console Host handles 32-bit processes using a "Job Object" or session container. When the user clicks "Close" in the taskbar, this terminates the process directly from the kernel (`TerminateProcess`), without waiting for the application to process its messages.
To work around this in a "creative" but effective way, I propose the last two strategies that actually work when the API fails:
Option A: The "Keep-Alive" Process Trick
If Windows 11 kills your process, the solution is to have a small loader that detects whether the program closed "legitimately" or by force, and instantly relaunches it from the same point if it was a forced closure.
Code snippet
PROCEDURE Main( cParam )
LOCAL nExitCode
// If the program is launched without parameters, it acts as a "Guardian"
IF Empty( cParam )
DO WHILE .T.
// Launches a second instance of itself with a parameter
nExitCode := hb_processRun( hb_argv(0) + " RUNNING" )
// If the exit code is 0, the user exited via ESC (legal)
IF nExitCode == 0
EXIT
ENDIF
// If the code is not 0, Windows terminated it. It will restart automatically.
"Automatic restart after forced shutdown attempt..."
ENDDO
RETURN
ENDIF
// --- YOUR PROGRAM LOGIC GOES HERE ---
LOCAL nKey := 0
DO WHILE nKey != 27
"Working... Press ESC to exit legally."
nKey := Inkey(0)
ENDDO
/ Legal exit with code 0
ErrorLevel(0)
RETURN
Option B: Create an "Invisible" Control Window
Since the pure console window is owned by conhost.exe and you cannot control it, the technical solution is to create a hidden window within your C code that belongs to your process. Being a standard Windows window, this one WILL receive the taskbar close message and will be able to cancel it.
C code for hidden window:
c
#pragma BEGINDUMP
#include <windows.h>
#include "hbapi.h"
LRESULT CALLBACK DummyWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
if (msg == WM_QUERYENDSESSION || msg == WM_CLOSE) return 0; // Full lock
return DefWindowProc(hwnd, msg, wParam, lParam);
}
HB_FUNC( CREATE_INVISIBLE_GUARD ) {
WNDCLASS wc = {0};
wc.lpfnWndProc = DummyWndProc;
wc.hInstance = GetModuleHandle(NULL);
wc.lpszClassName = "MyGuardClass";
RegisterClass(&wc);
/ Create a 0x0 pixel, invisible window
CreateWindow("MyGuardClass", "Control", 0, 0, 0, 0, 0, NULL, NULL, wc.hInstance, NULL);
#pragma ENDDUMP
Usage in Harbour: Call CREATE_INVISIBLE_GUARD() at the beginning. Windows 11 sometimes links the closing of the thumbnail to the main process window. Since there is another "live" window that refuses to close, the system often aborts the termination of the entire process.
Final Conclusion
If you need absolute security for your data (avoiding corrupted .dbf files) in Windows 11:
Accept GTWVT: I know you prefer a pure console, but GTWVT is literally a pure console that responds to your commands. You can remove the borders and menu so the user doesn't notice the difference.
Use Guardian (Option A): This is the most common way to prevent employees from closing the program from the taskbar at point-of-sale (POS) terminals.
Would you be interested in having me help you implement the "automatic restart" system (Guardian) so that it's invisible to the user?
I'd be happy to help you secure your app once and for all.
<LAST GEMINI ANSWER - END>