如何访问继承的匿名管道HANDLE,而不是stdout,stderr& stdin,在Windows中?

时间:2015-09-17 23:15:44

标签: c++ windows pipe ipc child-process

我正在尝试通过Windows中的匿名管道从子进程接收数据。我知道如何使用标准I / O流执行此操作,但这些用于其他目的。我也知道如何使用fork()pipe()execv()在Linux或OSX中执行此操作。

在Windows中,您可以使用CreatePipe()创建一个管道,并使用SetHandleInformation()使一端可继承。然后对于stdout和stderr,您可以将设置为STARTUPINFOhStdOutput的{​​{1}}传递给hStdError,以将另一端传递给孩子。在致电CreateProcess()父母最近之后,它会处理孩子管道的一端。这些都在MSDN上的Creating a Child Process with Redirected Input and Output中详细解释。但是,除了通过stderr,stdout或stdin之外,我还没有办法将CreateProcess()传递给孩子。

我尝试将HANDLE转换为字符串,如下所示:

HANDLE

然后将其作为命令行参数传递并将其转换回std::ostringstream str; str << hex << "0x" << handle; std::string handleArg = str.str(); ,这只是子进程中的HANDLE。尽管子进程显然继承了管道void *,但HANDLE的实际值必须与父进程不同,因为以这种方式传递它不会起作用。

我知道我可以使用命名管道来执行此操作,但似乎应该可以使用匿名管道执行此操作。

那么如何将管道HANDLE传递给Windows中的子进程?

Update1:​​ this MSDN article中的示例代码似乎表明,至少对于套接字句柄,您可以将它们作为字符串传递给子代。

Update2:原来我犯了一个错误。请参阅下面的答案。

2 个答案:

答案 0 :(得分:3)

事实证明,可以HANDLE作为命令行参数传递给子进程,方法是将其转换为字符串,然后在子进程中返回HANDLE }(只是void *)。使用HANDLE到套接字的示例代码可以是found here

要完成这项工作,您需要确保密切关注Creating a Child Process with Redirected Input and Output。在调用CreateProcess()并关闭所有继承设置后,关闭子进程的管道末端非常重要。

注意,我尝试在命令行上将HANDLE作为字符串传递,但我做错了。我的错误在于将HANDLE作为int传递给boost::iostreams::file_descriptor(),这使得它将其视为文件描述符而不是Windows HANDLE

答案 1 :(得分:0)

为什么不使用 here 所示的方法?

<块引用>

调用GetStdHandle函数获取当前标准输出 处理;保存此句柄,以便您可以恢复原始标准 创建子进程后的输出句柄。

调用 SetStdHandle 函数将标准输出句柄设置为 管道的写句柄。现在父进程可以创建 子进程。

调用 CloseHandle 函数关闭管道的写句柄。 子进程继承写句柄后,父进程 不再需要它的副本。

调用 SetStdHandle 恢复原始标准输出句柄。