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

发布于 2024-08-31 16:11:13 字数 463 浏览 0 评论 0原文

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

我看到四种可能性:

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

我很可能错过了一些东西,而这四个选项都没有充分描述 Windows 对其控制台所做的事情。

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

具体示例:运行CMD。然后,使用 CMD 运行 [控制台应用程序]。 [控制台应用程序] 将写入与 CMD 使用的控制台窗口相同的内容。

When a console application is started from another console application, how does console ownership work?

I see four possibilities:

  1. The second application inherits the console from the first application for its lifetime, with the console returning to the original owner on exit.
  2. Each application has its own console. Windows then somehow merges the content of the two into what the "console" visible to the user
  3. The second application get a handle to the console that belongs to the first application.
  4. The console is placed into shared memory and both applications have equal "ownership"

It's quite possible that I missed something and none of these four options adequately describe what Windows does with its consoles.

If the answer is close to option 4. My follow-up question is which of the two processes is responsible for managing the window? (Handling graphical updates when the screen needs to be refreshed / redrawn, etc)

A concrete example: Run CMD. Then, using CMD, run [console application]. The [console application] will write to what appears to be the same console window that CMD was using.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

梦年海沫深 2024-09-07 16:11:13

您的四种可能性实际上都不是这种情况,并且您的后续问题“两个进程中的哪一个负责管理窗口?”的答案是两个进程都不负责。 TUI 程序根本不需要了解有关 Windows 的任何信息,并且在幕后,甚至不一定会深入到 GUI。

控制台是对象,可以通过句柄访问,就像文件、目录、管道、进程和线程一样。单个进程不会通过其句柄“拥有”控制台,就像进程不会“拥有”它具有打开句柄的任何文件一样。子进程从其父进程继承控制台的句柄,就像所有其他(可继承的)句柄一样。您的 TUI 应用程序由 CMD 生成,只需继承 CMD 在调用 CreateProcess() 时应继承的标准句柄,这些句柄通常是 CMD 的标准输入、输出和错误(除非命令行告诉 CMD 使用其他一些句柄作为子进程的标准输入、输出和错误)。

控制台不依赖于 CMD。只要存在 (a) 控制台输入或输出缓冲区的任何打开句柄或 (b) 以其他方式“附加”到控制台的任何进程,它们就存在。因此,在您的示例中,您可以杀死 CMD,但只有当您也终止子进程时,控制台才会真正被销毁。

在 Windows NT 6.1 之前的版本中,负责显示包含控制台的 GUI 窗口的进程是 CSRSS(客户端-服务器运行时子系统)。窗口处理代码位于 WINSRV.DLL 中,其中包含“控制台服务器”,在幕后,执行控制台 I/O 的 Win32 程序会对其进行 LPC 调用。在 Windows NT 6.1 中,此功能的原因由 Raymond Chen 介绍< /a>,从 CSRSS 移出到 CSRSS 生成的特权较低的进程中。

None of your four possibilities is actually the case, and the answer to your follow-on question, "Which of the two processes is responsible for managing the window?", is that neither process is responsible. TUI programs don't have to know anything about windows at all, and, under the covers, aren't necessarily even plumbed in to the GUI.

Consoles are objects, accessed via handles just like files, directories, pipes, processes, and threads. A single process doesn't "own" a console via its handle to it any more than a process "owns" any file that it has an open handle to. Handles to consoles are inherited by child processes from their parents in the same way that all other (inheritable) handles are. Your TUI application, spawned by CMD, simply inherits the standard handles that CMD said that it should inherit, when it called CreateProcess() — which are usually going to be CMD's standard input, output, and error (unless the command-line told CMD to use some other handles as the child's standard input, output, and error).

Consoles aren't dependent upon CMD. They exist as long as there are (a) any open handles to the console's input or output buffers or (b) any processes otherwise "attached" to the console. So in your example you could kill CMD, but only when you terminated the child process too would the console actually be destroyed.

The process that is in charge of displaying the GUI windows in which consoles are presented is, in Windows NT prior to version 6.1, CSRSS, the Client-Server Runtime SubSystem. The window handling code is in WINSRV.DLL, which contains the "console server" that — under the covers — Win32 programs performing console I/O make LPC calls to. In Windows NT 6.1, this functionality, for reasons covered by Raymond Chen, moved out of CSRSS into a less-privileged process that CSRSS spawns.

对你再特殊 2024-09-07 16:11:13

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

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

但是,没有什么可以阻止两个进程同时写入输出流 - 流是共享的。使用某些运行时库时这可能会出现问题,因为对标准输出/错误的写入可能不会立即刷新,从而导致混合乱码输出。一般来说,必须处理主动写入同一输出流通常不是一个好主意,除非您采取措施通过并发原语(如互斥体、事件等)来协调它们的输出。

My guess is somewhere between 3 and 4. The console is a self-standing object, which has standard input, output and error streams. These streams are attached to the first process that uses the console. Subsequent processes can also inherit these streams if not redirected (e.g. running a command with redirect to a file.)

Normally there is no contention, since parent processes usually wait for their child process to complete, and asynchronous processes typically start their own console (e.g. try "start cmd" in a command prompt) or redirect standard output.

However, there is nothing to stop both processes writing to the output stream at the same time - the streams are shared. This can be a problem when using some runtime libraries since writes to standard output/error may not be immediately flushed, leading to mixed garbled output. In general, having to processes actively writing to the same output stream is usually not a good idea, unless you take measures to co-ordinate their output through concurrency primitives like Mutexes, Events and the like.

爱给你人给你 2024-09-07 16:11:13

SDK谈论它的方式与1非常相似。它是CreateProcess的一个选项,描述如下:

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

但是,输出是通过句柄进行的,您可以使用 GetStdHandle() 获得一个输出。假设输出未重定向,传递 STD_OUTPUT_HANDLE 返回控制台句柄。实际输出是通过 WriteFile() 或 WriteConsole/Output() 完成的。如果两个进程都不断将输出写入句柄,那么它们的输出将随机混合。否则,这与两个程序写入同一文件句柄时发生的情况无法区分。

从逻辑上讲,有一个与控制台关联的屏幕缓冲区。您可以使用 SetConsoleScreenBufferXxx() 对其进行修改。从这个角度来看,你可以将其称为共享内存。实际的实现是不可发现的,句柄将它们抽象出来,就像任何 Win32 API 一样。在 Vista 中,新的 conhost.exe 进程肯定会发生很大的变化。

The way the SDK talks about it strongly resembles 1. It is an option with CreateProcess, described as follows:

CREATE_NEW_CONSOLE
The new process has a new console, instead of inheriting its parent's console (the default). For more information, see Creation of a Console.

Output however happens through handles, you'd get one with GetStdHandle(). Passing STD_OUTPUT_HANDLE returns the console handle, assuming output isn't redirected. Actual output is done through WriteFile() or WriteConsole/Output(). If both processes keep writing output to the handle then their output will be randomly intermingled. This is otherwise indistinguishable from what would happen when two programs write to the same file handle.

Logically, there's a screen buffer associated with a console. You can tinker with it with SetConsoleScreenBufferXxx(). From that point of view you could call it shared memory. The actual implementation is undiscoverable, handles abstract them away, like any Win32 API. It is sure to have changed considerably in Vista with the new conhost.exe process.

别闹i 2024-09-07 16:11:13

CMD“拥有”控制台。当它为应用程序创建进程时,该应用程序将继承控制台的句柄。它可以读取和写入这些内容。当该进程消失时,CMD 继续拥有所有权。

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

CMD 'owns' the console. When it creates a process for an app, that app inherits handles to the console. It can read and write those. When the process goes away, CMD continues ownership.

Note: I'm not entirely sure that 'ownership' is the right word here. Windows will close the Console when CMD exits, but that may be a simple setting.

花辞树 2024-09-07 16:11:13

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

啊,你说得对。我正在考虑在一个进程中运行可执行文件,却忘记了它们启动了自己的进程 - 我没有深入研究。

Each application will run in it's own AppDomain. Each AppDomain should be running it's own console.

Ah, you're right. I was thinking about running executables within a process and forgot they start their own process - I didn't drill down far enough.

倒数 2024-09-07 16:11:13

我认为文档中对此进行了很好的说明。

I think it's spelled out fairly well in the documentation.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文