パスワードを忘れた? アカウント作成
10008006 journal
Windows

IR.0-4の日記: WSH/Execメソッド/TextStreamオブジェクトが詰まる

日記 by IR.0-4

例でよくある以下のコードは、実は期待通りに動かずforループから抜け出せない。

var WshShell = WScript.CreateObject("WScript.Shell");
WScript.Echo("START");
        var wExec = WshShell.Exec('cmd /c "dir %windir%"');
        for( ; wExec.Status == 0 ; ){WScript.Sleep(1);}
WScript.Echo("END");

var exit_code = wExec.ExitCode;
var stdout = wExec.StdOut.ReadAll();
var stderr = wExec.StdErr.ReadAll();
WScript.Echo(stdout);

どうやらTextStream:StdOut又StdErrの内部バッファがいっぱいになると、
次を読み込まなくなるかららしい。
(だから%windir%じゃなくてもdirじゃなくてもそれなりのストリーム量で、
標準出力/標準エラー出力を使うプログラムでこれが発生する)

だから以下の解決策

var stdout="";
var stderr="";
var read_size = 1024;
WScript.Echo("START");
        var wExec = WshShell.Exec('cmd /c "dir %windir%"');
        for( ; wExec.Status == 0 ; ){
        stdout += wExec.StdOut.Read(read_size);
        stderr += wExec.StdErr.Read(read_size);
        WScript.Sleep(1);}
WScript.Echo("END");
for( ; ! wExec.StdOut.AtEndOfStream ; ){
        stdout += wExec.StdOut.Read(read_size);
}
for( ; ! wExec.StdErr.AtEndOfStream ; ){
        stderr += wExec.StdErr.Read(read_size);
}
WScript.Echo( stdout );
WScript.Quit(0);

終了待ちループ中に読み出せばいい。
read_sizeは任意。

(ただ実際に内部バッファが原因かは調べていない)
(バッファサイズを得る方法がないのか、分からない)

この議論は賞味期限が切れたので、アーカイブ化されています。 新たにコメントを付けることはできません。
typodupeerror

一つのことを行い、またそれをうまくやるプログラムを書け -- Malcolm Douglas McIlroy

読み込み中...