質問

アプリを起動し、stdoutおよび場合によってはstderrを介して出力をキャプチャするにはどうすればよいですか

自動ビルドシステムを作成しており、分析するために出力をキャプチャする必要があります。 svnリポジトリを更新し、リビジョン番号を取得して、autobuild / revNumber /内のファイルを移動できるようにします。また、makeを使用してビルドし、コンパイルテキストをサーバーにアップロードして、ビルドが失敗した場合の警告とエラーを確認できるようにします。

system()関数は見つかりませんが、MSDNで CreateProcess()関数を見つけました。必要なものを起動することはできますが、stderrとstdoutをキャプチャする方法がわかりません。ブレークポイントを設定してアプリを終了しない限り、プロセスは個別に起動し、アプリのコンソールウィンドウにすべてのテキストが保持されます。また、すべてのプロセスが完了するまで待ってから、生成されたデータをスキャンして、必要な追加の操作を行います。どうすればいいですか?

役に立ちましたか?

解決

実際のシェル(つまり、海のシェルではありません-Cシェルまたはその派生物ではありません):

program arg1 arg2 >/tmp/log.file 2>&1

これは、指定された引数でプログラムを実行し、stdoutを/tmp/log.fileにリダイレクトします。最後の表記( hieroglyph ) ' 2>& 1 'は、stderr(ファイル記述子2)をstdout(ファイル記述子1)が行く同じ場所に送ります。操作の順序が重要であることに注意してください。それらを逆にすると、標準エラーは標準出力が行っていた場所に移動し、標準出力(標準エラーではない)がファイルにリダイレクトされます。

表示されるファイル名の選択は、さまざまな理由でひどいです-ユーザーがディレクトリを選択できるようにし、ファイル名にプロセスIDまたはタイムスタンプを含める必要があります。

LOG=${TMPDIR:-/tmp}/log.$.$(date +%Y%m%d-%H%M%S)
program arg1 arg2 >$LOG 2>&1

C ++では、 system()関数(Cから継承)を使用してプロセスを実行できます。 C ++プログラムのファイル名(わかりやすい)を知る必要がある場合は、プログラムで名前を生成し( strftime()は友達です)、そのファイル名でコマンド文字列を作成します。 (厳密には、$ TMPDIRを取得するには getenv()が必要であり、プロセスIDを取得するにはPOSIX関数 getpid()が必要です。2行をシミュレートできますシェルスクリプト(使用されるPIDは起動されたシェルではなく、C ++プログラムのものです)。

代わりにPOSIX popen()関数を使用できます。コマンドの標準エラーを標準出力と同じ場所に送信するには、作成するコマンド文字列に「 2>& 1 」表記を含める必要がありますが、一時ファイルが必要です:

FILE *pp = popen("program arg1 arg2 2>&1", "r");

その後、ファイルストリームを読み取ることができます。 CファイルストリームをC ++ istreamにマップするクリーンな方法があるかどうかはわかりません。おそらくあります。

他のヒント

hStdInput、hStdOutput、およびhStdErrorを持つSTARTUP_INFO構造を埋める必要があります。 CreateProcessの際には、必ずハンドルを継承してください。

/* Assume you open a file handle or pipe called myoutput */
STARTUP_INFO si_startinfo;
ZeroMemory(&si_startinfo, sizeof(STARTUP_INFO));
si_startinfo.cb = sizeof(STARTUP_INFO);
si_startinfo.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
si_startinfo.hStdOutput = myoutput;
si_startinfo.hStdError = myoutput;
si_startifno.dwFlags != STARTF_USEHANDLES;

PROCESS_INFORMATION pi_procinfo;
ZeroMemory(&pi_procinfo, sizeof(PROCESS_INFORMATION);

CreateProcess(NULL, cmdline, NULL, NULL, true, 0, NULL, pathname, &si_startinfo, &pi_procinfo);

エラー処理の側面は示していませんが、これを行う必要があります。 5番目の引数は、ハンドルを継承するためにtrueに設定されます。他の人がパイプを作成する方法を説明したので、ここでは繰り返しません。

MicrosoftのCRTとMSDNライブラリには、システム関数と_popen関数が含まれています。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top