Behandeln Sie STRG+C auf Win32
Habe ich einige Probleme mit der Handhabung von STRG+C - Ereignisse, die in einem Win32 C++ Konsole.
Grundsätzlich mein Programm sieht wie folgt aus: (basierend auf dieser anderen Frage: Windows Strg-C - Reinigung der lokale stack-Objekte in der Befehlszeile app)
bool running;
int main() {
running = true;
SetConsoleCtrlHandler((PHANDLER_ROUTINE) consoleHandler, TRUE);
while (running) {
//do work
...
}
//do cleanup
...
return 0;
}
bool consoleHandler(int signal) {
if (signal == CTRL_C_EVENT) {
running = false;
}
return true;
}
Ist das problem der cleanup-code nicht ausgeführt überhaupt.
Nach der Ausführung der handler-Funktion in der Prozess beendet wird, aber ohne den code auszuführen, nachdem der main-loop. Was ist falsch?
EDIT: wie gewünscht, das ist ein minimaler Testfall ähnlich wie mein Programm: http://pastebin.com/6rLK6BU2
Habe ich nicht den "test-cleanup-Anweisung" Text in meiner Ausgabe.
Ich weiß nicht, ob das wichtig ist, ich kompiliere mit MinGW.
EDIT 2: Das problem mit den test-case-Programm ist die Verwendung der Sleep()
Funktion. Ohne ihn funktioniert das Programm wie erwartet.
In Win32 die Funktion handler läuft in einem anderen thread, so dass, wenn der Hundeführer/thread beendet seine Ausführung, der Haupt-thread schlafen. Vermutlich ist dies die Ursache von Prozess-Unterbrechung?
SetConsoleCtrlHandler
zurück?Sind Sie sicher, dass die
ConsoleHandler
Funktion läuft? Wenn du das Programm im debugger und setzen Sie einen Haltepunkt, wird es halt am Haltepunkt?Auch, sollten Sie BOOL für die retval, und DWORD für das argument der consoleHandler. Auch, FALSCH/WAHR, in...
Und Sie deklarieren Sie eine Funktion Prototyp des
consoleHandler
- Funktion vor dem Aufruf SetConsoleCtrlHandler
?Wie können Sie dann überprüfen, dass der code nach der Schleife nicht ausgeführt werden? Wenn Sie einen Haltepunkt in den code ein und führen Sie in einem debugger, wird es aufhören?
InformationsquelleAutor eang | 2013-08-17
Du musst angemeldet sein, um einen Kommentar abzugeben.
Folgende code funktioniert bei mir:
InformationsquelleAutor lpapp
Laut die Dokumentation, wenn der handler (die ist falsch erklärt, BTW) erhält eine
CTRL_CLOSE_EVENT
,CTRL_LOGOFF_EVENT
oderCTRL_SHUTDOWN_EVENT
signal, der Prozess ist beendet, nachdem der handler beendet. Zu tun, was Sie versuchen sollen Sie zu bewegen, Ihre cleanup-code in den handler selbst.CTRL_C_EVENT
. Getestet nur jetzt mit einemswitch
im my-handler-Funktion, und drücken Sie STRG+C in der Konsole.InformationsquelleAutor Remy Lebeau
Je nach Ihren spezifischen Anforderungen Sie haben eine Reihe von Optionen. Wenn Sie wollen einfach zu ignorieren Strg+C können Sie anrufen
SetConsoleCtrlHandler
vorbeiNULL
alsHandlerRoutine
parameter:Diese entfernt alle signal-Handler. Zum beenden dieser Anwendung, die Sie haben zu implementieren benutzerdefinierte Logik, um zu bestimmen, Wann abgeschaltet.
Wenn Sie möchten, behandeln Sie Strg+C haben Sie zwei Möglichkeiten: Legen Sie einen handler für das signal, oder übergeben Sie die Tastatur-Eingaben auf normale Tastatur-handling.
Einrichtung eine Prozedur ist ähnlich wie der code oben, aber statt der übergabe
NULL
als der Hundeführer Sie bieten Ihre eigene Implementierung.Die Ausgabe dieses Programms ist:
Beachten Sie, dass die cleanup-code ausgeführt wird, unabhängig von der code innerhalb der main
while
-Schleife. Signal-Handler bilden eine verkettete Liste, wo die handler-Funktionen aufgerufen werden, die auf einen last-registriert, erste genannte basis, bis einer der Handler zurückgibtTRUE
. Wenn keiner der Handler TRUE zurück, wird der default-handler aufgerufen wird. Der default-handler für eine Konsole AufrufeExitProcess
bei der Verarbeitung von Strg+C.Wenn Sie verhindern möchten, dass eine Vorverarbeitung und behandeln Sie Strg+C als normale Tastatur Eingabe statt, wechselt man die Konsole durch den Aufruf
SetConsoleMode
.Einmal die
ENABLE_PROCESSED_INPUT
flag entfernt Strg+C wird nicht mehr vom system verarbeitet und an die Konsole wie normale Tastatur-Eingaben. Es kann gelesen werden mitReadConsoleInput
oderReadFile
.Disclaimer: Die oben wurde getestet auf Windows 8 64bit, zusammengestellt für 32-und 64-bit -, Release-und Debug-Konfigurationen.
InformationsquelleAutor IInspectable