如何在 Windows 中访问继承的匿名管道句柄(除了 stdout、stderr 和 stdin)?

jco*_*and 5 c++ windows ipc pipe child-process

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

在 Windows 中,您可以使用 来创建管道CreatePipe()并使用 使其一端不可继承SetHandleInformation()。然后,对于 stdout 和 stderr,您可以通过STARTUPINFO、 withhStdOutput或hStdErrorset 来传递 to ,CreateProcess()将另一端传递给子级。在调用CreateProcess()最接近的父级之后,它是管道子级末端的句柄。MSDN 上的使用重定向输入和输出创建子进程对此进行了详细解释。HANDLE但是,除了通过 stderr、stdout 或 stdin 之外,我还没有找到将 a 传递给子级的方法。

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

std::ostringstream str;
str << hex << "0x" << handle;
std::string handleArg = str.str();
Run Code Online (Sandbox Code Playgroud)

然后将其作为命令行参数传递并将其转换回 a HANDLE,这只是void *子进程中的 a 。尽管子进程显然继承了管道,HANDLE但实际值HANDLE必须与父进程中的不同,因为以这种方式传递它是行不通的。

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

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

Update1:​​这篇 MSDN 文章中的示例代码似乎表明,至少使用套接字句柄,您可以将它们作为字符串传递给子进程。

Update2:事实证明我犯了一个错误。请参阅下面我的回答。

jco*_*and 5

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

为了完成这项工作,您需要确保严格遵循创建具有重定向输入和输出的子进程。调用后关闭子进程的管道末端很重要CreateProcess()并确保所有继承设置正确非常重要。

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