CreateProcessでファイルをリダイレクト入力

[戻る]
ken92 2007/10/29(月) 19:36:08
cal.exe< model.txt >out.txt
に相当する処理をプログラム内からCreateProcessで実行しようとしています。
 model.txt及びout.txtはテキストファイルで、cal.exeに本来標準入力する内容、及び
cal.exeが標準出力する内容になります。
CreateProcessはそのままではリダイレクトを受け付けないので以下のようにしました。

FILE *fout,*fin;
PROCESS_INFORMATION pi;
STARTUPINFO si;

fout=freopen("out.txt", "w", stdout);
fin=freopen("model.txt", "r", stdin);
ZeroMemory(&si,sizeof(si));
si.cb=sizeof(si);
si.dwFlags = STARTF_USESHOWWINDOW;
si.wShowWindow=SW_SHOWNORMAL;
si.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
si.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);

CreateProcess(NULL,(LPTSTR)"cal.exe",NULL,NULL,TRUE,NORMAL_PRIORITY_CLASS,NULL,NULL,&si,&pi);

と言った感じにしていますが、実際にCreateProcessを呼び出すと、入力待ちとなってし
まい、入力ファイルのリダイレクトがうまくいっていないようです。一方、out.txtは作
成されて空っぽです。これは入力待ちの状態で停止しているためだと思いますが。

 どこがまずいのか、ご教示いただければと思います。

wclrp ( 'o') 2007/10/30(火) 00:11:15
自分のプロセスのstdout,stdinを変える必要ないし
自分のプロセスのSTD_INPUT_HANDLE、STD_OUTPUT_HANDLEを
渡す必要もないんじゃない。

CreateFileとかでファイルを指定すればいいんじゃない。

それと
freopen("out.txt", "w", stdout);
この時点でファイルが作られたんじゃない。

シャノン 2007/10/30(火) 13:11:24
STARTF_USESTDHANDLES が欠けてるんじゃない?

シャノン 2007/10/30(火) 13:18:03
あぁ、まだ突っ込みどころがあった。
si.hStdInput / hStdOutput は HANDLE なので FILE * じゃダメです。
FILE * から HANDLE を得る方法も無くは無いですが、CreateFile で開いたほうが簡単で
しょう。

あと、fin と fout が子プロセスに渡されてないし。

FUKU 2007/10/30(火) 14:34:12
単純に、これではダメですか?

 ::ShellExecute(NULL, NULL, "cmd",
  "/c c:\\cal.exe < c:\\model.txt > c:\\out.txt", NULL, SW_HIDE);

ken92 2007/10/30(火) 14:44:38
 皆様どうもありがとうございます。だいたい以下の感じでうまくいきました。
だいたいというのは、引っかかることが一つあるからです。

今回は

si.dwFlags = STARTF_USESTDHANDLES;

とする必要があるのですが、これだとWindowの状態(SW_HIDEとか)を制御できないよう
ですね。制御するには

si.dwFlags = STARTF_USESHOWWINDOW;

とする必要があるのですが、これでは今回は駄目なわけです。

今回の子プロセスはコマンドラインプログラムで、真っ暗なウインドウが開いてしまい
ます。これまで
si.wShowWindow = SW_HIDE;
で消していたのですが、両立する方法はありますか。また下記に現行のリストを書きま
すので、突っ込みどころをお待ちしております。

----------------------------------------
PROCESS_INFORMATION pi;
STARTUPINFO si;
HANDLE hStdInput, hStdOutput;
pi.hProcess = NULL;

HANDLE hFile_in=CreateFile
("in.dat",GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL
,NULL);
HANDLE hFile_out=CreateFile
("out.dat",GENERIC_WRITE,FILE_SHARE_WRITE,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NOR
MAL,NULL);
DuplicateHandle(GetCurrentProcess(), hFile_in, GetCurrentProcess(),&hStdInput, 
0, 1, DUPLICATE_SAME_ACCESS);
DuplicateHandle(GetCurrentProcess(), hFile_out, GetCurrentProcess
(),&hStdOutput, 0, 1, DUPLICATE_SAME_ACCESS);
ZeroMemory(&si,sizeof(si));
si.cb = sizeof(si);
si.dwFlags = STARTF_USESTDHANDLES;
si.hStdInput = hStdInput;
si.hStdOutput = hStdOutput;
CreateProcess(NULL,
(LPTSTR)"hoge.exe",NULL,NULL,TRUE,NORMAL_PRIORITY_CLASS,NULL,NULL,&si,&pi);
CloseHandle(pi.hThread);
while(WaitForSingleObject(pi.hProcess,50)!=WAIT_OBJECT_0){
    Application->ProcessMessages();
}
CloseHandle(pi.hProcess);
CloseHandle(hFile_in);
CloseHandle(hFile_out);
CloseHandle(hStdOutput);
CloseHandle(hStdInput);
-----------------------------------------------------

+ 2007/10/30(火) 16:14:06
第6引数にCREATE_NO_WINDOW

シャノン 2007/10/30(火) 17:19:39
si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;

ken92 2007/10/31(水) 08:05:09
[[解決]]
 どうも有難うございました。解決致しました。

FUKU 2007/10/31(水) 12:50:50
蛇足ですが以下でもリダイレクトできました

CreateProcess(NULL,"cmd /c c:\\cal.exe < c:\\model.txt > c:\\out.txt",〜);

古いスレッドには追加発言できません。