如何在Windows中访问继承的匿名管道HANDLE,而不是stdout,stderr和stdin?
How to access an inherited anonymous pipe HANDLE, other than stdout, stderr & stdin, in Windows?
我试图通过Windows中的匿名管道从子进程接收数据。我知道如何使用标准I/O流来做到这一点,但是这些流被用于其他目的。我也知道如何使用fork()
, pipe()
和execv()
在Linux或OSX中做到这一点。
在Windows中,您可以使用CreatePipe()
创建一个管道,并使一端非可由SetHandleInformation()
继承。然后,对于stdout和stderr,可以将设置了hStdOutput
或hStdError
的STARTUPINFO
传递给CreateProcess()
,以将另一端传递给子进程。在调用CreateProcess()
之后,父进程的句柄最接近子进程的管道末端。在MSDN上创建具有重定向输入和输出的子进程中详细解释了这一点。然而,我还没有找到一种方法来传递HANDLE
,除了通过标准错误,标准输出或标准输入,给孩子。
我试过把HANDLE
转换成一个字符串,像这样:
std::ostringstream str;
str << hex << "0x" << handle;
std::string handleArg = str.str();
然后将其作为命令行参数传递并将其转换回HANDLE
,这只是子进程中的void *
。虽然子进程显然继承了管道HANDLE
,但HANDLE
的实际值必须与父进程中的值不同,因为以这种方式传递它无法工作。
我知道我可以使用命名管道来完成此操作,但似乎应该可以使用匿名管道来完成此操作。
那么我如何将管道HANDLE
传递给Windows中的子进程?
Update1: MSDN文章中的示例代码似乎表明,至少对于套接字句柄,您可以将它们作为字符串传递给子进程。
Update2:原来我犯了一个错误。
原来您可以将HANDLE
作为命令行参数传递给子进程,方法是将其转换为字符串,然后在子进程中返回到HANDLE
(这只是void *
)。使用HANDLE
到套接字的示例代码可以在这里找到。
要使此工作,您需要确保您严格遵循创建具有重定向输入和输出的子进程。在调用CreateProcess()
之后关闭子进程的管道末端并正确设置所有继承设置是很重要的。
注意,我之前尝试在命令行上传递HANDLE
作为字符串,但我做错了。我的错误是将HANDLE
作为int
传递给boost::iostreams::file_descriptor()
,这使得它将其视为文件描述符而不是Windows HANDLE
。
为什么不使用这里所示的方法呢?
调用GetStdHandle函数来获取当前的标准输出处理;保存此句柄,以便您可以恢复原始标准子进程创建后的输出句柄。
调用SetStdHandle函数将标准输出句柄设置为管道的写句柄。现在,父进程可以创建子进程。
调用CloseHandle函数关闭管道的写句柄。子进程继承写句柄后,父进程继承写句柄不再需要它的副本。
调用SetStdHandle恢复原来的标准输出句柄。
- 如何将stdout重定向到stderr
- 尝试在 Windows 上重定向 stdout 和 stderr——_fileno(stdout) 返回 -2
- 使用参数 + stdout + stderr 从命令行调用 MFC 应用程序
- visual Redirect stdout/stderr to null vs2017 c++
- 如何将"cout"、"cerr"、"stdout"和"stderr"从C++程序定向到单个文件
- stdin,stdout,stderr是如何关闭的
- 在Qt中:我可以输出到“stdout”吗,就像使用qDebug()输出到“stderr”一样简单
- 为什么在Shell输出中运行的可执行操作到stdout,而不是崩溃时的stderr
- C++-将stdout/stderr复制到文件,同时保留控制台输出
- 重定向PostgreSQL Qt驱动程序stdout/stderr输出
- 在sigpipe之后恢复stdout和stderr
- 使用stdout/stderr以外的管道与子流程进行通信
- 如何正确启动进程并转发 stdin/stdout/stderr
- 有没有办法在Visual Studio中捕获stderr和stdout
- 实现QProcess的最佳方法是什么,在"real time"中读取stdout和stderr?
- 再次将 stdout/stderr 重定向到 UNIX 下的文件
- fprintf() / std::cout 不会将部分字符串打印到 stdout/stderr
- 当c风格的stdout / stderr写入时通知
- StdIn / StdOut / StdErr重定向到WinSock连接
- 在 Windows 上重定向 stdout/stderr