8

Windows API を使用して C++ で子プロセスを作成する場合、親から子へのハンドルの継承を許可できます。Microsoft の例「Creating a Child Process with Redirected Input and Output」では、子プロセスの std in/out を親によって作成されたパイプにリダイレクトします。リダイレクト パイプを使用できるようにするには、継承を許可する必要があります。

私は、外部実行可能ファイルを起動し、出力を読み取り、それを呼び出し元 (返された出力をファイルに記録する) に返す小さなデモ クラスに取り組んでいます。タイムアウト機能を構築しようとしています。この機能ではTerminateProcess()、子供を呼び出して生活を続ける前に、一定時間だけブロックします。

ただし、ハンドルの継承を許可することで、子プロセスにも出力ファイルへのハンドル ( Process Explorerで表示) があることがわかりました。子プロセスにこのハンドルを取得させたくありませんが、この場合の親 (このデモ クラス) もハンドルを認識していないため、現在SetHandleInformation()、特に出力ファイルのフラグを解除して継承から除外するために使用することはできません。

意図しないハンドルや望ましくないハンドルを渡す「ブランケット」継承を許可せずに、必要な特定のハンドルのみを継承するより良い方法があるに違いないと確信しています。残念ながら、解決策を見つけることができませんでした。関連する MSDN の記事をできるだけ多く閲覧し、Google で落胆の状態に陥りました。

少なくとも、子からハンドルを削除するために何かをする必要がありますが、必ずしもデモ クラス内にそれらのハンドルを含める必要はありません (それらのハンドルは呼び出し元のクラスによって使用され、このデモ クラスにはそれらの存在が明示的に認識されていません)。

より選択的な継承のための解決策はありますか? 特に、どのハンドルを継承するかを具体的に宣言できるソリューションに興味があります。そのようなソリューションが存在する場合、未指定のハンドルはすべて継承されません。

よろしくお願いします。

4

3 に答える 3

4

出力ファイル ハンドルが子プロセスによって継承される場合、それは、ファイルを開いた親プロセスのコードが、ファイル ハンドルを継承可能にする必要があることを明示的に示しているためです。lpSecurityAttributesのパラメータの値を渡しましたCreateFile。デフォルトの状態では、ハンドルは継承できません。

プロセスを作成するクラスは、すでにファイルを開いている呼び出し元を推測しようとすべきではないように思えます。

ただし、どのハンドルが新しいプロセスのニーズに対応するかについて特別な知識がある場合は、Windows Vista の時点で、どのハンドルを継承するかを指定するメカニズムがあります。を呼び出す準備をするときは、通常の の代わりに構造体をCreateProcess使用します。メンバーがいます。割り当てて初期化し、 with を使用して継承するハンドルのリストを設定します。すべてのハンドルは継承可能である必要があり、いつ呼び出すかを指定する必要があります。また、パラメーターに含める必要があります。Raymond Chen は、2011 年の記事でこの手法を実演しました。STARTUPINFOEXSTARTUPINFOlpAttributeListUpdateProcThreadAttributePROC_THREAD_ATTRIBUTE_HANDLE_LISTbInheritHandles = TRUECreateProcessEXTENDED_STARTUPINFO_PRESENTdwCreationFlags

その追加機能が利用できない場合は、プログラムの開いているすべてのハンドルを列挙し、すべての継承プロパティを で設定することは確かにできますが、それSetHandleInformationは子プロセスを作成する機能の範囲を超えているようです。ハンドルを作成するコードは、ハンドルが継承可能かどうかを気にします。

于 2010-02-26T21:59:22.030 に答える
1

SetHandleInformationを使用して、出力ハンドルのビットをクリアできますHANDLE_FLAG_INHERIT。これにより、子プロセスがそれを継承できなくなります。

このフラグが設定されている場合、CreateProcessのbInheritHandlesパラメーターをTRUEに設定して作成された子プロセスは、オブジェクトハンドルを継承します。

于 2010-02-26T21:22:39.797 に答える