管道句柄繼承
管道伺服器會控制其句柄是否可以以下列方式繼承:
- CreatePipe 函式會接收 SECURITY_ATTRIBUTES 結構。 如果管道伺服器將此結構的 bInheritHandle 成員設定為 true ,則可以繼承 createPipe 所建立 句柄。
- 管道伺服器可以使用 DuplicateHandle 函式來變更管道句柄的繼承。 管道伺服器可以建立可繼承管道控點的不可繼承複本,或是不可繼承管道句柄的可繼承複本。
- CreateProcess 函式可讓管道伺服器指定子進程是否繼承其可繼承的句柄。
當子進程繼承管道句柄時,系統可讓進程存取管道。 不過,父進程必須將句柄值傳達給子進程。 父進程通常會藉由將標準輸出句柄重新導向至子進程來執行此動作,如下列步驟所示:
- 呼叫 GetStdHandle 函式,以取得目前的標準輸出句柄;儲存此句柄,以便在建立子進程之後還原原始標準輸出句柄。
- 呼叫 SetStdHandle 函式,將標準輸出句柄設定為管線的寫入句柄。 現在父進程可以建立子進程。
- 呼叫 closeHandle函式關閉管道的寫入句柄。 子進程繼承寫入句柄之後,父進程就不再需要其複本。
- 呼叫 SetStdHandle 還原原始標準輸出句柄。
子進程會使用 GetStdHandle 函式來取得其標準輸出句柄,現在是管道寫入端的句柄。 子進程接著會使用 WriteFile 函式將其輸出傳送至管道。 當子系完成管道時,它應該藉由呼叫 CloseHandle 或終止來關閉管道句柄,以自動關閉句柄。
父進程會使用 ReadFile 函式來接收管道的輸入。 數據會以位元組數據流的形式寫入匿名管道。 這表示從管道讀取的父進程無法區分以個別寫入作業寫入的位元組,除非父進程和子進程都使用通訊協定來指出寫入作業結束的位置。 當管道的所有寫入句柄都關閉時,readFile 函式 會傳回零。 在呼叫 readFile 之前,父進程必須先將其句柄關閉至管道的寫入端。 如果未這麼做,ReadFile 作業便無法傳回零,因為父進程具有管道寫入端的開啟句柄。
重新導向標準輸入句柄的程序類似於重新導向標準輸出句柄的程式,不同之處在於管道的讀取句柄會當做子系的標準輸入句柄使用。 在此情況下,父進程必須確保子進程不會繼承管道的寫入句柄。 如果未這麼做,則子進程所執行 ReadFile 作業無法傳回零,因為子進程具有管道寫入端的開啟句柄。
如需使用匿名管道重新導向子進程標準句柄的範例程式,請參閱 使用重新導向的輸入和輸出建立子進程。