wake-up-neo.net

Wie und warum friert der QuickEdit-Modus in der Eingabeaufforderung Anwendungen ein?

Ich habe kürzlich ein Problem mit der Eingabeaufforderung unter Windows festgestellt, bei dem der QuickEdit-Modus aktiviert war und beim Klicken auf das Fenster Text ausgewählt und ein laufendes Programm aufgehängt wurde. Dies ist anscheinend bekanntes Verhalten - ich habe ein paar Fragen dazu gefunden:

Wie wird die Anwendung "pausiert"/"ausgesetzt"? Ist der Vorgang dem Signal SIGSTOP auf * nix ähnlich? (Ich interessiere mich auch dafür, warum diese Funktionalität existiert überhaupt erst?

43
Whymarrh

Dies ist sehr beabsichtigt. Es gibt keinen vernünftigen Weg, wie ein Benutzer Text auswählen kann, wenn Ihr Programm den Inhalt des Konsolenfensters durchläuft. Das Konsolen-Host-Programm hört also einfach auf, die Ausgabe von stdout/stderr zu lesen, und Ihr Programm bleibt stehen, bis der Benutzer die Operation abgeschlossen hat. Dies kann geändert werden. Sie müssen Get + SetConsoleMode () aufrufen und die Option ENABLE_QUICK_EDIT_MODE deaktivieren.

Beachten Sie, dass dieses "Hang" sich nicht grundlegend von den Ausführungspausen unterscheidet, die Sie erhalten, wenn Ihr Programm eine Standardausgabe mit einer Geschwindigkeit generiert, die weit höher ist als die vom Host bereitgestellte Konsole. Obwohl diese Verzögerungen endlich sind.

Es ist nicht die einzige Möglichkeit, mit der der Benutzer Ihr Programm anhalten kann. Er kann auch einfach Strg + S drücken. Durch Drücken von Strg + Q wird es wieder fortgesetzt. Wenn Sie alt genug sind, erkennen Sie diese Steuercodes möglicherweise als Xon/Xoff , Handshake-Zeichen für ein Terminal. Was eine Konsole wirklich ist, eine einfache Emulation eines Terminals, wie sie in den 70er Jahren verwendet wurde. Dies kann auch geändert werden. Sie müssen sich nicht mehr auf die eingebaute gepufferte Konsoleneingabe verlassen und zu ReadConsole () wechseln. Oder indem Sie die ENABLE_LINE_INPUT-Konsolenoption deaktivieren und nicht sicher sind, welche Nebenwirkungen dies hat, da Sie keine Sprachlaufzeit erwähnt haben, müssen Sie es versuchen.

Und natürlich ist das Beenden Ihres Programms sehr einfach. Sie erhalten EOF unter stdin, wenn der Benutzer Strg + Z eingibt, damit das Programm beendet wird. Und es gibt Strg + C und Strg + Pause für eine sofortige Beendigung, unabhängig davon, was Ihr Programm macht. Sie können mit SetConsoleCtrlHandler () eine Benachrichtigung für diese erhalten, aber Sie können sie nicht blockieren.

Wenn das Standardverhalten gefährlich ist und die Gesundheit eines Menschen gefährdet ist, würde ich dringend empfehlen, einen Berater zu beauftragen. Und weiß nicht, wer diese Antwort geschrieben hat.

46
Hans Passant

Um zu beantworten, wie ich vor kurzem das gleiche Problem in einem Python-Skript debuggen und eine Stapelverfolgung mit windbg aufgenommen habe.

 

Der Aufruf von WriteConsole führt schließlich zum NtDeviceIoControlFile-Systemaufruf, und der Kernel kehrt erst zurück, wenn ein Tastendruck erfolgt oder der QuickEdit-Modus geändert wird. Wenn Sie also nie auf die Konsole schreiben, ist Ihr Prozess vor dem Einfrieren des QuickEdit-Modus geschützt. Und Ihr Benutzer muss niemals etwas kopieren. Warten Sie also noch einmal auf den QuickEdit-Modus.

0
SargeATM