パイプ サーバーは、次の方法でハンドルを継承できるかどうかを制御します。
- CreatePipe 関数は、SECURITY_ATTRIBUTES 構造体を受け取ります。 パイプ サーバーで、この構造体の bInheritHandle メンバーを TRUE 設定すると、CreatePipe によって作成されたハンドル 継承できます。
- パイプ サーバーは、DuplicateHandle 関数を使用して、パイプ ハンドルの継承を変更できます。 パイプ サーバーは、継承可能なパイプ ハンドルの継承不可能な複製、または非継承可能なパイプ ハンドルの継承可能な複製を作成できます。
- CreateProcess 関数を使用すると、パイプ サーバーは、子プロセスが継承可能なハンドルをすべて継承するか、まったく継承しないかを指定できます。
子プロセスがパイプ ハンドルを継承すると、システムはプロセスがパイプにアクセスできるようにします。 ただし、親プロセスは、子プロセスにハンドル値を伝える必要があります。 親プロセスでは、通常、次の手順に示すように、標準の出力ハンドルを子プロセスにリダイレクトすることでこれを行います。
- GetStdHandle 関数を呼び出して、現在の標準出力ハンドルを取得します。子プロセスの作成後に元の標準出力ハンドルを復元できるように、このハンドルを保存します。
- SetStdHandle 関数を呼び出して、標準出力ハンドルをパイプへの書き込みハンドルに設定します。 これで、親プロセスで子プロセスを作成できるようになりました。
- CloseHandle 関数を呼び出して、パイプへの書き込みハンドルを閉じます。 子プロセスが書き込みハンドルを継承した後、親プロセスはそのコピーを必要としません。
- SetStdHandle呼び出して、元の標準出力ハンドルを復元します。
子プロセスでは、GetStdHandle 関数を使用して標準出力ハンドルを取得します。これは、パイプの書き込み末尾へのハンドルになりました。 その後、子プロセスは WriteFile 関数を使用して、その出力をパイプに送信します。 子がパイプを終了したら、CloseHandle呼び出すか、終了してハンドルを自動的に閉じて、パイプ ハンドルを閉じる必要があります。
親プロセスでは、ReadFile 関数を使用してパイプからの入力を受け取ります。 データは、バイト ストリームとして匿名パイプに書き込まれます。 つまり、親プロセスと子プロセスの両方がプロトコルを使用して書き込み操作が終了する場所を示さない限り、パイプからの親プロセスの読み取りでは、個別の書き込み操作で書き込まれたバイトを区別できません。 パイプに対するすべての書き込みハンドルが閉じられると、ReadFile 関数は 0 を返します。 親プロセスでは、ReadFile を呼び出す前に、パイプの書き込み側のハンドル閉じる必要があります。 これを行わない場合、親プロセスにはパイプの書き込み終了に対するオープン ハンドルがあるため、ReadFile 操作は 0 を返すことができません。
標準入力ハンドルをリダイレクトする手順は、パイプの読み取りハンドルが子の標準入力ハンドルとして使用されることを除き、標準出力ハンドルをリダイレクトする手順と似ています。 この場合、親プロセスは、子プロセスがパイプの書き込みハンドルを継承しないようにする必要があります。 これを行わない場合、子プロセスがパイプの書き込み終了に対して開いているハンドルを持っているため、子プロセスによって実行される ReadFile 操作は 0 を返すことができません。
匿名パイプを使用して子プロセスの標準ハンドルをリダイレクトするサンプル プログラムについては、「リダイレクトされた入力と出力のを使用した子プロセスの作成」を参照してください。