[英]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
設置為hStdOutput
或hStdError
傳遞給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.