mcrblog

vcpp-ml

2003年06月

30

[vcpp 00060958] Re:popen()でのエラー取得

こんにちは、炎羅です。

On Mon, 30 Jun 2003 15:06:30 +0900
At [vcpp 00060956] RE: popen()でのエラー取得
"t...@tokyo-horei.co.jp" <t...@tokyo-horei.co.jp> Wrote:

> ファイルに落とさず、出力結果を変数(char * , CStringなど)に
> 代入させてやることは出来ないのでしょうか?

CreateFileMapping APIが使えそうな気がします。

■ Written by 炎羅 (e...@mail.interq.or.jp) ■
30

[vcpp 00060957] Re: popen()でのエラー取得

Tietew です。

On Mon, 30 Jun 2003 15:06:30 +0900
In article <2...@ta-taki.tokyo-horei.co.jp>
[[vcpp 00060956] RE: popen()でのエラー取得]
"t...@tokyo-horei.co.jp" <t...@tokyo-horei.co.jp> wrote:

> si.hStdOutput = hFile;  // 標準出力
> si.hStdError = hFile;   // 標準エラー出力

> にファイルハンドルを指定していますが、
> これだとファイルに落ちてしまいます。
> ファイルに落とさず、出力結果を変数(char * , CStringなど)に
> 代入させてやることは出来ないのでしょうか?

CreatePipe で無名パイプを作って,書き込み側パイプを「継承可」フ
ラグをセットして複製 (DuplicateHandle) し,si.hStdOutput 等に代
入しておき,ReadFile で読み込むと普通のファイルっぽく読めます。

_read() を使いたいなら読み込み側パイプを _open_osfhandle() して
ファイル記述子を取得し,fread() 等を使いたいなら更に fdopen() す
ればよろし。

-----

// エラー処理してないので適切にすること。

HANDLE rh, wh0, wh;
CreatePipe(&rh, &wh0, NULL, 1024);
DuplicateHandle(GetCurrentProcess(), wh,
  GetCurrentProcess(), &wh0, 0, true, DUPLICATE_SAME_ACCESS);
CloseHandle(wh0);

STARTUPINFO si = { sizeof STARTUPINFO };
si.dwFlags = STARTF_USESTDHANDLES;
si.hStdOutput = wh;
si.hStdError = wh;
PROCESS_INFORMATION pi;

CreateProcess(NULL, /*CommandLine*/, NULL, NULL, true,
  0, NULL, NULL, &si, &pi);
CloseHandle(wh);

while(ReadFile(rh, ...)) {
  // 読んだバッファで処理処理
}
if(GetLastError() != ERROR_BROKEN_PIPE) {
  // やばいエラー
}
// 子プロセスが終了した。

CloseHandle(rh);
CloseHandle(si.hThread);
CloseHandle(si.hProcess);


―[ Tietew ]――――――――――――――――――――――――――――
Mail: t...@tietew.net / t...@raug.net
Web : http://www.tietew.net/     Tietew Windows Lab.
PGP fingerprint: 26CB 71BB B595 09C4 0153  81C4 773C 963A D51B 8CAA
30

[vcpp 00060956] RE: popen()でのエラー取得

Takizawaです。

渋木さんありがとうございました。

http://numata.aquasky.jp/programming/vcpp/sys_001.html
のページに方法が載っていました。

そこで、もう一つ疑問なのですが、

si.hStdOutput = hFile;  // 標準出力
si.hStdError = hFile;   // 標準エラー出力

にファイルハンドルを指定していますが、
これだとファイルに落ちてしまいます。
ファイルに落とさず、出力結果を変数(char * , CStringなど)に
代入させてやることは出来ないのでしょうか?

無理なら、いったんファイルに落ちたものを読み込むことに
しようと思いますが、どうなんでしょうか?

変な質問になってしまいましたが、よろしくお願いします。

---------------------
環境:
WindowsXP(SP1) + VS6(SP5)

mailto:t...@tokyo-horei.co.jp
---------------------
30

[vcpp 00060955] RE: popen()でのエラー取得

 渋木です。

> のですが、通常のメッセージは取得出来るのですが、エラーメッセージが取得
> 出来ません。どうすればよいのでしょうか?

 ここで言う「エラーメッセージ」は、おそらく標準エラー出力に対して出力さ
れているのでしょう。

 popen() は標準エラー出力を捕捉しないので、popen() を使って目的を達成す
ることは出来ません。

 CreateProcess() など、プロセス起動時に標準エラー出力を指定することがで
きる API も存在するので、コードで挙動を制御したければそれらを使うことに
なると思います。

 あるいは、コマンドシェルが NT 系の cmd.exe であると仮定してよければ、起
動コマンドを

dir b: 2>&1

 のようにすれば、標準エラー出力先を標準出力に切り替えることが出来ます。

 この場合はおそらく、popen() で目的が達成できるでしょう。

--
// 渋木宏明 (Hiroaki SHIBUKI)
// mailto:h...@mbi.nifty.com
// http://www.hidori.jp/
// Microsoft MVP 2002-2003 of Windows
30

[vcpp 00060954] popen()でのエラー取得

Takizawaと申します。

WindowsNT/2000で_popen()を利用してコマンドを実行しているのですが、その際のメッセージを取得したい
のですが、通常のメッセージは取得出来るのですが、エラーメッセージが取得出来ません。どうすればよいの
でしょうか? 

現在のソースは下記のようです。 

int main(int argc, char* argv[]) 

char str[512],*ptr; 
FILE *fp; 

if((fp = _popen("dir b:","rt")) == NULL) 

fprintf( stderr , "error!!!\n"); 
return -1; 

while(1) 

fgets(str,512,fp); 
if(feof(fp)) 

break; 

ptr = strchr(str,'\n'); 
if(ptr != NULL) 

*ptr='\0'; 

printf("%s\n",str); 

_pclose(fp); 
return 0; 


---------------------
環境:
Windows2000(SP3) + VS6(SP5)

mailto:t...@tokyo-horei.co.jp
---------------------
記事検索
Amazon.co.jp
  • ライブドアブログ