gpt4 book ai didi

c++ - 使用新的控制台窗口创建进程,但覆盖一些标准的 i/o 句柄

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:28:12 25 4
gpt4 key购买 nike

如果您使用带有标志 CREATE_NEW_CONSOLE 的 CreateProcess,新进程会将其标准输入、输出和错误句柄定向到新的控制台窗口。如果您想覆盖 I/O 流,您可以通过在 STARTUPINFO 字段 hStdOutput、hStdInput 和 hStdError 中设置句柄并设置标志 STARTF_USESTDHANDLES 来实现。

但是如果您只想覆盖其中一个句柄怎么办?例如,我可能想将 stderr 重定向到一个文件,同时让 stdout 和 stdin 连接到新的控制台窗口。

STARTF_USESTDHANDLES 标志告诉 CreateProcess 替换所有句柄,而不是将它们连接到新控制台窗口的句柄。所以看来我们必须提供所有三个句柄。显然我可以将 hStdError 设置为日志文件的句柄,但是 hStdInput 和 hStdOutput 应该使用什么值?

我尝试使用 NULL,它似乎适用于 Windows 8.1,但不适用于 Windows 7。

我还考虑过先创建一个控制台窗口,然后使用新控制台窗口缓冲区的句柄调用 CreateProcess(并省略 CREATE_NEW_CONSOLE 标志)。不幸的是,父进程也是一个控制台应用程序,控制台应用程序似乎无法创建第二个控制台窗口。

最佳答案

根据这篇 MSDN 支持文章:

How to spawn console processes with redirected standard handles

If the parent process only wishes to redirect one or two standard handles, specifying GetStdHandle() for the specific handles causes the child to create the standard handle as it normally would without redirection. For example, if the parent process only needs to redirect the standard output and error of the child process, then the hStdInput member of the STARTUPINFO structure is filled as follows:

hStdInput = GetStdHandle(STD_INPUT_HANDLE);

根据GetStdHandle() documentation :

STD_INPUT_HANDLE
(DWORD)-10
The standard input device. Initially, this is the console input buffer, CONIN$.

STD_OUTPUT_HANDLE
(DWORD)-11
The standard output device. Initially, this is the active console screen buffer, CONOUT$.

STD_ERROR_HANDLE
(DWORD)-12
The standard error device. Initially, this is the active console screen buffer, CONOUT$.

...

The standard handles of a process may be redirected by a call to SetStdHandle, in which case GetStdHandle returns the redirected handle. If the standard handles have been redirected, you can specify the CONIN$ value in a call to the CreateFile function to get a handle to a console's input buffer. Similarly, you can specify the CONOUT$ value to get a handle to a console's active screen buffer.

Attach/detach behavior

When attaching to a new console, standard handles are always replaced with console handles unless STARTF_USESTDHANDLES was specified during process creation.

If the existing value of the standard handle is NULL, or the existing value of the standard handle looks like a console pseudohandle, the handle is replaced with a console handle.

When a parent uses both CREATE_NEW_CONSOLE and STARTF_USESTDHANDLES to create a console process, standard handles will not be replaced unless the existing value of the standard handle is NULL or a console pseudohandle.

因此,如果父进程的 STDIN 未被重定向,GetStdHandle(STD_INPUT_HANDLE) 将返回 NULL 或引用 CONIN$ 的伪句柄。当该值通过 STARTUPINFO 传递给子进程时,子进程将收到一个控制台句柄,用于它恰好在其中运行的任何控制台的 STDIN。另一方面,如果父进程的 STDIN已被重定向,GetStdHandle(STD_INPUT_HANDLE) 将返回一个真实文件/管道/等的实际句柄, child 将继承和访问它。

这同样适用于 STDOUT 和 STDERR。

所以,如果你想重定向 child 的 STDIN/OUT/ERR 句柄,你必须将 hStdInput/Output/Error 设置为你自己的句柄。如果您希望子项接收默认句柄,请使用 GetStdHandle() 并让 CreateProcess() 根据父项本身是否被重定向来决定子项接收何种句柄还是不是。

关于c++ - 使用新的控制台窗口创建进程,但覆盖一些标准的 i/o 句柄,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30494945/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com