Hoe en waarom bevriest de QuickEdit-modus in de opdrachtprompt applicaties?

Ik kwam onlangs een probleem tegen met de opdrachtprompt in Windows, waarbij de QuickEdit-modus was ingeschakeld en als ik op het venster klikte, tekst werd geselecteerd en een actief programma bleef hangen. Dit is blijkbaar bekend gedrag – ik heb er een paar vragen over gevonden:

Hoe is de applicatie “onderbroken”/”opgeschort”? Is het proces vergelijkbaar met het SIGSTOP-signaal op *nix? (Ik ben ook geïnteresseerd in het begrijpen van waaromdeze functionaliteit überhaupt bestaat? Het lijkt niet intuïtief en gevaarlijk.)


Antwoord 1, autoriteit 100%

Dit is zo ontworpen. Er is geen redelijke manier waarop een gebruiker tekst kan selecteren wanneer uw programma door de inhoud van het consolevenster blijft scrollen. Dus het console-hostprogramma stopt gewoon met het lezen van uw stdout/stderr-uitvoer en uw programma blijft hangen totdat de gebruiker de bewerking voltooit. Dit kan worden gewijzigd, u moet Get+SetConsoleMode()en schakel de optie ENABLE_QUICK_EDIT_MODE uit.

Houd er rekening mee dat dit “vastlopen” niet fundamenteel verschilt van de uitvoeringspauzes die u krijgt wanneer uw programma stdout-uitvoer genereert met een snelheid die veel hoger is dan de consolehost deze kan gebruiken. Al zijn die vertragingen eindig.

En het is niet de enige manier waarop de gebruiker uw programma kan stoppen, ze kunnen ook gewoon op Ctrl+S drukken. Door op Ctrl+Q te drukken wordt het weer hervat. Als je oud genoeg bent, herken je deze controlecodes misschien als Xon/Xoff, handdruktekens voor een terminal. Dat is wat een console eigenlijk is, een eenvoudige emulatie van een terminal zoals ze in de jaren zeventig werden gebruikt. Dit kan ook worden gewijzigd, u hoeft niet langer te vertrouwen op de ingebouwde gebufferde console-invoer en over te schakelen naar ReadConsole(). Of door de consoleoptie ENABLE_LINE_INPUT uit te schakelen, weet u niet precies welke bijwerkingen dat heeft aangezien u geen taalruntime heeft genoemd, u moet het proberen.

En natuurlijk is het beëindigen van je programma heel eenvoudig. Je krijgt EOF op stdin wanneer de gebruiker Ctrl+Z typt, dat zou je programma moeten beëindigen. En er is Ctrl+C en Ctrl+Break voor een onmiddellijke beëindiging, ongeacht wat uw programma doet. U kunt hiervoor een melding krijgen met SetConsoleCtrlHandler()maar je kunt het niet blokkeren.

Als het standaardgedrag gevaarlijkis en de gezondheid van een mens in gevaar brengt, raad ik u ten zeerste aan een consultant in te huren. En weet niet wie dit antwoord heeft geschreven.


Antwoord 2, autoriteit 6%

Om de vraag te beantwoorden hoe ik onlangs hetzelfde probleem debugde in een pythonscript en een stacktracering vastlegde met windbg.

De aanroep van WriteConsole leidt uiteindelijk tot de NtDeviceIoControlFile syscall en de kernel keert niet terug totdat er een toets wordt ingedrukt of de QuickEdit-modus is gewijzigd. Dus als u nooit naar de console schrijft, is uw proces veilig voor het bevriezen van de QuickEdit-modus. En uw gebruiker hoeft nooit iets te kopiëren. Dus wacht waar is de QuickEdit-modus ook alweer voor?

Other episodes