快速编辑模式在命令提示符中如何以及为什么会导致应用程序冻结?

82

我最近在Windows上使用命令提示符时遇到了一个问题,即启用了QuickEdit模式并且单击窗口会选择文本并挂起正在运行的程序。显然,这是已知的行为 - 我找到了一些相关的问题:

该应用程序是如何“暂停” / “挂起”的?这个过程是否类似于 *nix 上的 SIGSTOP 信号? (我也想了解为什么这个功能首先存在? 它似乎不直观和危险。)


1
抱歉,无法告诉你如何做。至于为什么,我可以想象,在文本滚动时选择某些文本是相当困难的。 - Stephan
2
这里已经有一个相当不错的回答了:http://superuser.com/questions/459609/what-does-it-do-exactly-if-i-click-in-the-window-of-cmd - Scott C
@ScottC 发现得不错,谢谢!但是,我真的想要了解底层的工作原理(而且我很想知道为什么)。此外,还需要与*nix进行一些比较。 - Whymarrh
这是一个Python解决方案:https://dev59.com/SVsX5IYBdhLWcg3wY-rX#76855923 - Maicon Mauricio
2个回答

89
这是有意为之的。当程序不断滚动控制台窗口内容时,用户无法合理地选择文本。因此,控制台主机程序停止读取您的标准输出/标准错误输出,您的程序将挂起,直到用户完成操作。这可以通过更改(启用)Get+SetConsoleMode() 函数中的ENABLE_QUICK_EDIT_MODE选项来解决。
请注意,这种“挂起”并没有根本上的区别,与程序以远高于控制台主机处理速度的速率生成标准输出时出现的执行暂停。尽管这些延迟是有限的。
而且用户可以通过按下Ctrl+S来停止您的程序,这并不是唯一的方法。按下Ctrl+Q会恢复它。如果您够老,那么您可能会认出这些控制代码Xon/Xoff,它们是终端的握手字符。这就是控制台的真正含义,它是对上世纪70年代使用的终端的简单仿真。这也可以改变,您需要停止依赖内置缓冲控制台输入,并切换到ReadConsole()。或者通过关闭ENABLE_LINE_INPUT控制台选项,但由于您没有提到任何语言运行时,所以不确定这会产生什么副作用,您需要自己尝试。
当然,终止程序非常容易。当用户键入Ctrl + Z时,您会在stdin上获得EOF,这应该结束您的程序。而且,无论您的程序正在做什么,都可以使用Ctrl + C和Ctrl + Break进行立即终止。您可以通过SetConsoleCtrlHandler()获取这些的通知,但无法阻止它。
如果默认行为是危险的并且会危及人类健康,那么我强烈建议您聘请顾问。我不知道谁写了这个答案。

2
谢谢!我当然是指“危险”是指它很可能会引起问题。您将暂停与程序在生成输出过快时表现的行为进行比较,这是否意味着执行会在Console.WriteLine上暂停,直到选择被做出? - Whymarrh
是的。具体是哪一个你无法知道。 - Hans Passant
4
这似乎与 Windows 的设计和兼容性问题有关,但在任何 Linux 上,你都可以从终端选择文本而程序不会停止。 - Rafał Kłys
这是否适用于Linux? - Peheje
1
带有 [windows] 标签的问题不适用于 Linux。 - Hans Passant
可能有用的信息:重定向输出和/或错误流将防止快速编辑模式暂停您的程序。在某些情况下,这也可能是有帮助的,如果您不想更改控制台的任何设置,并且愿意在其他地方捕获输出... - stackprotector

8

为了回答这个问题,最近我在调试一个Python脚本时使用了Windbg来捕获堆栈跟踪。

调用WriteConsole最终会导致NtDeviceIoControlFile系统调用,内核不会返回直到发生按键或更改QuickEdit模式。因此,如果您从未写入控制台,则您的进程不会被QuickEdit模式冻结。您的用户也永远不需要复制任何内容。那么,QuickEdit模式是什么?


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接