首页 文章

如何在Windows中访问除stdout,stderr和stdin之外的继承的匿名管道HANDLE?

提问于
浏览
3

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

在Windows中,您可以使用 CreatePipe() 创建管道,并使一端不能与 SetHandleInformation() 一起继承 . 然后对于stdout和stderr,您可以将 STARTUPINFO (设置为 hStdOutputhStdError )传递给 CreateProcess() ,以将另一端传递给子项 . 在调用 CreateProcess() 之后,父级最接近它's handle to the child'的管道结束 . 这些都在MSDN上的Creating a Child Process with Redirected Input and Output中详细解释 . 但是,除了通过stderr,stdout或stdin之外,我还没有找到一种方法将 HANDLE 传递给孩子 .

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

std::ostringstream str;
str << hex << "0x" << handle;
std::string handleArg = str.str();

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

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

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

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

Update2: 结果我犯了一个错误 . 请参阅下面的答案 .

1 回答

  • 3

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

    要完成这项工作,您需要确保密切关注Creating a Child Process with Redirected Input and Output . 它在调用 CreateProcess() 之后's important that you close the child process'管道的结尾并获得所有继承设置 .

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

相关问题