プログラミング工房 > HSP > サンプルスクリプト > 

2つのコンソール・アプリケーションをパイプでつないで実行

(2008/01/21 追記)

 このページの情報は下記のページの注とあわせて利用してください。


 下のスクリプトは、コマンドプロンプト(cmd.exe)で2つのコンソール・アプリをパイプ記号("|")でつないだコマンドラインを実行したときの動作を再現するものです。(ウィンドウは表示されません)

 あるコンソール・アプリの出力をそのまま別のコンソール・アプリの入力に流し込んで処理を行わせる場合、名無しパイプという仕組みを利用します。

 その手順はまずCreatePipe APIで名無しパイプを作成します。名無しパイプはプロセス間で一方向にのみデータを受け渡すのに使えるバッファです。このとき、使用するSECURITY_ATTRIBUTES構造体の第3メンバに1を指定し、作成したパイプのハンドルが子プロセス(コンソール・プログラム)にも使えるようする必要があります。APIが成功すると得られる、バッファの読み書きに必要な2つのハンドルのうち、書き込み側ハンドルを1つ目のアプリに渡し、読み出し側ハンドルを2つ目のアプリに渡すことでデータが通る「パイプ」を通じさせます。

 それぞれのハンドルをアプリに渡すには、アプリの起動時に指定する必要があるSTARTUPINFO構造体の「標準出力ハンドル」メンバ(書き込み側ハンドルの場合)、もしくは「標準入力ハンドル」メンバ(読み出し側ハンドルの場合)にセットし、これらのハンドルを有効にするために「フラグ」メンバ(12番目のメンバ)にSTARTF_USESTDHANDLES(0x00000100)をセットすればOKです。

 ちなみに、STARTUPINFO構造体の「フラグ」メンバにSTARTF_USESHOWWINDOW(0x00000001)を加え、「ウィンドウ初期表示状態」メンバ(13番目)に適切な値をセットすることで、起動時のウィンドウ状態を設定することができます。

 このパイプを使った処理を行うときの注意点は、アプリを起動するためのCreateProcess(A) APIを実行した後はそのAPIに使用したパイプのハンドルを即座にクローズすることです。例えば、下のスクリプトの中でmes.exe起動時に使用した書き込み側ハンドル(hWritePipe)を即座にクローズせず、sort.exeが終了してからクローズしようとすると、sort.exe(データ受け取り側)はデータのやり取りが終わったという合図を受け取ることができず、永久にデータを待ち続けてしまいます(強制終了しなければならなくなります)。sort.exeが終了しなければスクリプトも永久に終了しません(sort.exeを強制終了させれば終了します)。

 >> スクリプトを見る

 >> ダウンロード  (実行に必要なファイルはすべてアーカイブに含まれています)