Lösung: Die Prozedur ConsoleEventProc, die mit SetConsoleCtrlHandler registriert wird, läuft asynchron zum Programm in einem anderen Thread. Wenn diese Prozedur beendet wird, wird das Programm "von außen" beendet, sobald offenbar ein weiterer Thread wieder rechenzeit bekommt. Jedenfalls werden nach Beendigung der Prozedur ConsoleEventProc noch ein paar wenige Befehle ausgeführt, bevor das Programm unkontrolliert abbricht. Abhilfe: ConsoleEventProc nie beenden. Damit hat man zumindest bis zum Timeout Zeit, das Programm ordentlich zu beenden.
Delphi-Quellcode:
function ConsoleEventProc(CtrlType: DWord): Bool; stdcall; far;
begin
// Diese Prozedur läuft asynchron zum Programm in einem eigenen Thread
case CtrlType of
CTRL_C_EVENT,
CTRL_BREAK_EVENT,
CTRL_LOGOFF_EVENT,
CTRL_SHUTDOWN_EVENT,
CTRL_CLOSE_EVENT:
begin
// Globale Variable setzen, die regelmäßig abgefragt werden muss
Terminated := True;
WriteLn('Shutdown Request received');
// unendlich warten, um das Programm ordentlich beenden zu können
// Die Unendlichkeit ist durch einen Windows-Timeout begrenzt
Sleep(INFINITE);
// Schließt die Konsole und bricht damit das Programm "von außen" ab
Result := True;
end;
else
Result := False; // Standard-Handler aufrufen
end;
end;
Application ändert an der ganzen Geschichte übrigens nichts, also hab ich die
Unit Forms wieder rausgeschmissen und nutze meine eigene Message-Schleife weiter.
"Seit er seinen neuen Computer hat, löst er alle seine Probleme, die er vorher nicht hatte."