繁体   English   中英

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

[英]How to access an inherited anonymous pipe HANDLE, other than stdout, stderr & stdin, in Windows?

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

在Windows中,你可以创建一个带有管CreatePipe()使可继承一端SetHandleInformation() 然后对于 stdout 和 stderr,您可以将STARTUPINFO设置为hStdOutputhStdError传递给CreateProcess()以将另一端传递给孩子。 在调用CreateProcess() ,父CreateProcess()最接近它的句柄到子进程的管道末端。 在 MSDN 上创建具有重定向输入和输出的子进程中详细解释了这一切。 但是,除了通过 stderr、stdout 或 stdin 之外,我还没有找到将HANDLE传递给孩子的方法。

我试过将HANDLE转换为这样的字符串:

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

然后将其作为命令行参数传递并将其转换回HANDLE ,这只是子进程中的void * 虽然子进程显然继承了管HANDLE的实际价值HANDLE ,因为它传递这样没有工作必须比父不同。

我知道我可以使用命名管道来做到这一点,但似乎应该可以使用匿名管道来做到这一点。

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

更新 1:此 MSDN 文章中的示例代码似乎表明,至少使用套接字句柄,您可以将它们作为字符串传递给子级。

更新2:原来我犯了一个错误。 看我下面的回答。

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

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

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

为什么不使用这里显示的方法?

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

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

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM