在Windows上,控制台窗口所有权如何工作?

从另一个控制台应用程序启动控制台应用程序时,控制台所有权如何工作?

我看到了四种可能性:

  1. 第二个应用程序从第一个应用程序的一生中inheritance控制台,并在退出时将控制台返回给原始所有者。
  2. 每个应用程序都有自己的控制台 然后,Windows以某种方式将两者的内容合并到用户可见的“控制台”中
  3. 第二个应用程序获取属于第一个应用程序的控制台的句柄。
  4. 控制台放置在共享内存中,两个应用程序拥有相同的“所有权”

我很可能错过了一些东西,而这四个选项都没有充分描述Windows在其控制台上的作用。

如果答案接近选项4.我的后续问题是两个进程中的哪一个负责pipe理窗口? (当屏幕需要刷新/重绘等处理graphics更新)

一个具体的例子:运行CMD。 然后,使用CMD,运行[控制台应用程序]。 [控制台应用程序]将写入似乎与CMD使用的控制台窗口相同的窗口。

Solutions Collecting From Web of "在Windows上,控制台窗口所有权如何工作?"

实际上,你的四种可能性都不是这样,对于后续问题“两个过程中哪一个负责管理窗口?”的答案是,这两个过程都不负责任。 TUI程序根本不需要了解任何有关窗口的知识 ,而且在这些封面下,甚至不一定需要查看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中, 由于Raymond Chen所涵盖的原因,这个功能已经从CSRSS中移出到CSRSS产生的权限较低的进程中。

我的猜测是介于3到4之间。控制台是一个独立的对象,具有标准的输入,输出和错误流。 这些流被附加到使用控制台的第一个进程。 如果没有重定向,后续进程也可以继承这些流(例如,运行带有重定向到文件的命令)。

通常没有争用,因为父进程通常等待子进程完成,异步进程通常启动自己的控制台(例如,在命令提示符下尝试“启动cmd”)或重定向标准输出。

但是,没有什么能够阻止两个进程同时写入输出流 – 这些流是共享的。 使用某些运行时库可能会造成问题,因为写入标准输出/错误可能不会立即刷新,导致混合乱码输出。 一般来说,除非您采取措施,通过互斥,事件等并发原语来协调输出,否则不得不主动写入相同的输出流。

SDK谈到的方式非常类似于1.它是CreateProcess的一个选项,描述如下:

CREATE_NEW_CONSOLE
新进程有一个新的控制台,而不是继承其父控制台(默认)。 有关更多信息,请参阅创建控制台。

然而,输出通过句柄发生,你会得到一个与GetStdHandle()。 假设输出未被重定向,传递STD_OUTPUT_HANDLE将返回控制台句柄。 实际输出是通过WriteFile()或WriteConsole / Output()完成的。 如果两个进程都将输出写入句柄,那么它们的输出将被随机混合。 这与两个程序写入同一个文件句柄时会发生什么不同。

逻辑上,有一个与控制台相关的屏幕缓冲区。 你可以用SetConsoleScreenBufferXxx()来修改它。 从这个角度来看,你可以称之为共享内存。 实际的实现是不可发现的,像任何Win32 API一样把它们抽象出来。 新的conhost.exe进程肯定会在Vista中有相当大的改变。

CMD'拥有'控制台。 当它为应用程序创建一个进程时,该应用程序会继承控制台的句柄。 它可以读写这些。 当过程消失时,CMD继续拥有权。

注意:我不完全确定“所有权”在这里是正确的。 CMD退出时,Windows将关闭控制台,但这可能是一个简单的设置。

我认为它在文档中的拼写很好。

每个应用程序将运行在它自己的AppDomain中。 每个AppDomain都应该运行它自己的控制台。

啊,你是对的。 我正在考虑在一个进程中运行可执行文件,并忘记了他们开始自己的进程 – 我没有深入钻取。