バックグラウンド:
stdout
プログラムの、stderr
および戻り値をキャプチャできるようにする必要があるプログラムに取り組んでいます。理想的には、プロセスの詳細を保持するオブジェクト内に保存する文字列にこれらをキャプチャしたいと考えています。私は現在、(私の意見では) 古風な C ファイル ハンドル マジックを使用して、出力をファイルに保存することで機能するコードをいくつか持っています。結果を出力したいときはいつでも、そのファイルを開いて内容を印刷します。
ときどき (作成したプロセスが実行されたままになっている場合)、書き込み用にファイルを開くことができないため、実行可能ファイルの次の実行が失敗することがあります。
問題文:
stdout
Windows で作成されたプロセスの出力を 1 つの文字列に保存stderr
し、より安全で最新の方法で別の文字列に保存する方法を探しています。そうすれば、作成した各プロセスの結果を出力したいときにいつでもそれらのコンテンツを印刷できます。
私の醜いコード:
メインチャンク
int stdoutold = _dup(_fileno(stdout)); //make a copy of stdout
int stderrold = _dup(_fileno(stdout)); //make a copy of stderr
FILE *f;
if(!fopen_s(&f, "name_of_my_file", "w")){ //make sure I can write to the file
_dup2(_fileno(f), _fileno(stdout)); //make stdout point to f
_dup2(_fileno(f), _fileno(stderr)); //make stderr point to f
fork("command_I_want_to_run", &pi); //run my fake fork (see below)
}
else{
...//error handling
}
_close(_fileno(stdout)); //close tainted stdout
_close(_fileno(stderr)); //close tainted stderr
_close(_fileno(f)); //close f
_dup2(stdoutold, _fileno(stdout)); //fix stdout
_dup2(stderrold, _fileno(stderr)); //fix stderr
fork- (これは単なる CreateProcess と考えることができますが、ここで何が起こるかを誰かが確認する必要がある場合に備えて)
int fork(std::string s, PROCESS_INFORMATION* pi){
char infoBuf[INFO_BUFFER_SIZE];
int bufCharCount =
ExpandEnvironmentStrings(s.c_str(), infoBuf, INFO_BUFFER_SIZE );
...
STARTUPINFO si;
ZeroMemory( &si, sizeof(si) );
si.cb = sizeof(si);
ZeroMemory( pi, sizeof(*pi) );
LPSTR str = const_cast<char *>(infoBuf);
if(!CreateProcess(NULL,
str,
NULL,
NULL,
TRUE,
0,
NULL,
NULL,
&si,
pi)
){
int err = GetLastError();
printf("CreateProcess failed (%d).\n", err);
CloseHandle((*pi).hProcess);
CloseHandle((*pi).hThread);
return err;
}
return 0;
}
ノート:
- 私はVS 2010を使用しています
- スレッドではなく複数のプロセスを使用し続けたいのは、実行するものが独自のプロセスの自由を持つ必要があるためです
編集:
追加の注意: また、指定されたコードを実行する関数を呼び出した直後にプロセスが終了するのを待つようにしているため、その時点でstdout
との結果を利用できます。stderr