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