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

shr*_*ght 5 windows console winapi console-application

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

我看到四种可能性:

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

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

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

一个具体的例子:运行CMD.然后,使用CMD运行[console application].[控制台应用程序]将写入与CMD正在使用的控制台窗口相同的内容.

Jde*_*eBP 6

你的四种可能性实际上都不是这样,你后续问题的答案是"两个过程中哪一个负责管理窗口?",这两个过程都不是负责任的.TUI程序根本不需要了解任何关于Windows的内容,而且,在幕后,它们甚至不必连接到GUI.

控制台是对象,通过句柄访问,就像文件,目录,管道,进程和线程一样.单个进程不会通过其句柄"拥有"控制台,而是一个进程"拥有"任何具有打开句柄的文件.对于控制台的句柄由父进程的子进程继承,其方式与所有其他(可继承)句柄相同.你的TUI应用程序,由CMD生成,只是继承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产生的权限较低的流程中.