簡體   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