从其他控制台应用程序启动控制台应用程序时,控制台所有权如何工作?
我看到四种可能性:
我很可能错过了一些东西,这四个选项都没有充分描述Windows对其控制台的作用。
如果答案接近选项4.我的后续问题是两个过程中的哪一个负责管理窗口? (当需要刷新/重绘屏幕时处理图形更新等)
一个具体示例:运行CMD。然后,使用CMD运行[console application]。 [控制台应用程序]将写入与CMD正在使用的控制台窗口相同的位置。
答案 0 :(得分:6)
你的四种可能性实际上都不是这样,你后续问题的答案是“两个进程中哪一个负责管理窗口?”, 进程都不是负责。 TUI程序根本不需要了解任何关于Windows的内容,而且,在幕后,它们甚至不必连接到GUI。
控制台是对象,通过句柄访问,就像文件,目录,管道,进程和线程一样。单个进程不会通过其句柄“拥有”控制台,而是一个进程“拥有”任何具有打开句柄的文件。对于控制台的句柄由父进程的子进程继承,其方式与所有其他(可继承)句柄相同。由CMD生成的TUI应用程序只是继承CMD表示应该继承的标准句柄,当它调用CreateProcess()
时 - 它们通常是CMD的标准输入,输出和错误(除非命令行)告诉CMD使用一些其他句柄作为孩子的标准输入,输出和错误。)
游戏机不依赖于CMD。只要存在(a)控制台输入或输出缓冲区的任何打开句柄或(b)否则“附加”到控制台的任何进程,它们就存在。因此,在您的示例中,您可以杀死CMD,但只有当您终止子进程时,控制台才会被破坏。
在版本6.1之前的Windows NT中,负责显示存在控制台的GUI窗口的过程是CSRSS,即客户端 - 服务器运行时子系统。窗口处理代码在WINSRV.DLL中,其中包含“控制台服务器” - 在封面下 - 执行控制台I / O的Win32程序进行LPC调用。在Windows NT 6.1中,由于原因covered by Raymond Chen,此功能从CSRSS转移到CSRSS产生的权限较低的进程中。
答案 1 :(得分:1)
我的猜测介于3到4之间。控制台是一个独立的对象,具有标准的输入,输出和错误流。这些流附加到使用控制台的第一个进程。如果未重定向,后续进程也可以继承这些流(例如,运行带有重定向到文件的命令。)
通常没有争用,因为父进程通常等待其子进程完成,异步进程通常启动自己的控制台(例如在命令提示符下尝试“start cmd”)或重定向标准输出。
但是,没有什么可以阻止两个进程同时写入输出流 - 共享流。当使用某些运行时库时,这可能是一个问题,因为对标准输出/错误的写入可能不会立即刷新,从而导致混合的乱码输出。通常,除非您采取措施通过并发原语(如互斥,事件等)来协调其输出,否则不得不主动写入相同的输出流进行处理通常不是一个好主意。
答案 2 :(得分:1)
SDK谈论它的方式非常类似于1.它是CreateProcess的一个选项,描述如下:
CREATE_NEW_CONSOLE
新进程有一个新的控制台,而不是继承其父控制台(默认)。有关更多信息,请参阅创建控制台。
输出通过句柄发生,你得到一个GetStdHandle()。传递STD_OUTPUT_HANDLE会返回控制台句柄,假设未重定向输出。实际输出通过WriteFile()或WriteConsole / Output()完成。如果两个进程都继续将输出写入句柄,则它们的输出将随机混合。否则,这与两个程序写入同一文件句柄时会发生的情况无法区分。
逻辑上,有一个与控制台关联的屏幕缓冲区。您可以使用SetConsoleScreenBufferXxx()修补它。从这个角度来看,你可以称之为共享内存。实际的实现是不可发现的,处理抽象它们,就像任何Win32 API一样。使用新的conhost.exe进程肯定会在Vista中发生相当大的变化。
答案 3 :(得分:0)
CMD'拥有'控制台。当它为应用程序创建进程时,该应用程序会继承控制台的句柄。它可以读写这些。当流程消失后,CMD将继续拥有所有权。
注意:我不完全确定“所有权”在这里是正确的词。当CMD退出时,Windows将关闭控制台,但这可能是一个简单的设置。
答案 4 :(得分:0)
我认为它在documentation中的说法相当不错。
答案 5 :(得分:-1)
每个应用程序都将在其自己的AppDomain中运行。每个AppDomain都应该运行它自己的控制台。
啊,你是对的。我正在考虑在一个进程中运行可执行文件并忘记他们开始自己的进程 - 我没有深入了解。