• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:VBScriptでCABファイルを展開する)

VBScriptでCABファイルを展開する

このQ&Aのポイント
  • VBScriptを使用して、あるディレクトリにあるCABファイルを展開するプログラムを作成しているのですが、CABファイル展開が終了しても、sleepのDo whileを抜けてくれない。
  • VBScriptで作成したCABファイル展開プログラムにおいて、CABファイルの展開が終了しても、Do while文から抜けられない問題が発生しています。
  • VBScriptを使用して、CABファイルを展開するプログラムを作成中ですが、CABファイルの展開が終了しても、Do while文を抜けることができません。

質問者が選んだベストアンサー

  • ベストアンサー
noname#246547
noname#246547
回答No.2

>原因を探っているうちに、下記の場所が悪さしているみたいなのではずしました。 外さないでください >後、自分でも2行いらないと思ったので、実行コマンド格納のSet objExecCmd = objWshShell.Exec(CmdLine)だけで実行すると、CABファイルの展開が不十分で終わるのです。。 検証してみた結果、expandの標準出力バッファが一杯になって、expandの処理が一時停止していました。 よって、whileの部分で標準出力バッファの中身を読み捨てればいいです。 補足:expand自体に、標準出力を抑制するスイッチがあれば、スイッチを付けるだけで解決したのですけどね。 ○参考ソース Option Explicit On Error Resume Next Dim objWshShell ' WshShell オブジェクト Dim objFSO ' FileSystemObject Dim strFolder ' フォルダ名 Dim strCab ' CABファイルパス Dim CmdLine ' 実行コマンド Dim objExecCmd ' 実行コマンド情報 dim readBuff strFolder = "\temp\test" strCab = "\temp\data2.cab" ' CABファイルの展開コマンド作成 CmdLine = "expand """ & strCab & """ -f:* """ & strFolder & """" Set objWshShell = CreateObject("WScript.Shell") Set objFSO = CreateObject("Scripting.FileSystemObject") 'CABファイルの存在確認 If objFSO.FileExists(strCab) = True Then ' 実行コマンド格納 Set objExecCmd = objWshShell.Exec(CmdLine) WScript.Echo "成功:コマンドを格納" & CmdLine & Err.Description ' 実行コマンドが終了するまで待つ Do While objExecCmd.Status = 0' and objExecCmd.ExitCode = 0 readBuff= objExecCmd.StdOut.Read(5000) 'expandの標準出力を捨てる ' readBuff= objExecCmd.StdOut.ReadAll 'expandの標準出力を捨てる このメソッドでは、expandが終了しないと戻ってこない WScript.Sleep(3000) WScript.Echo "展開中です" & Err.Description Loop WScript.Echo "成功:コマンド終了" & CmdLine & Err.Description '展開したCABファイルを削除する ' 'objFSO.DeleteFile strCab, True Else WScript.Echo "エラー:" & strCab & "が存在しません" & Err.Description End If

shou0995
質問者

お礼

marimari01さん、誠にありがとうございます。 これこそ意図していた動きです!! いろいろ原因探っててobjExecCmd.Statusが永遠に0のままだと思っていたら、バッファがいっぱいになっていたのですね。 参考までにお伺いしたいのですが、なぜバッファがいっぱいになってるって分かったのでしょうか…? (VBScript素人なもので、全く分かりませんでした。。) ホントにありがとうございました。

その他の回答 (2)

noname#246547
noname#246547
回答No.3

stdin,stdout,stderrのバッファは有限です。 サイズは256byteか1024byte位だったと思います そもそも、コンピュータ中で無限はありません。 無限に見えるバッファも、内部で保持しているバッファ以上のデータがきた場合は、バッファのサイズをリサイズしているだけです 。 例:Stringクラス、Listクラス stdin,stdout,stderrはリサイズしません。 理由:通常大きなデータを扱わない。かつ、データの保持期間が短い。 今回のExecからexpand呼び出しでは、 通常CRTに出力したら勝手にクリアされるstdoutが、 どこにも出力されるところが無かった(stdoutがCRTに繋がっていない)ため、 stdout内が満杯になってしまったのが原因です。 なので今回は、stdoutをreadBuffにつなげてあげる事によって stdout内が満杯にならないようにしてあげたわけです expand以外にも、stdoutに大量出力するコマンドは注意する必要があります。 コマンドにsilentモードがあればいいですが。

shou0995
質問者

お礼

なるほど、とても勉強になりました。 バッファと言う存在を、今まで全く気にしたことが無かったのがお恥ずかしい話です。。 ホントにありがとうございました。 これからも、もっとがんばろうと思います。

noname#246547
noname#246547
回答No.1

objWshShellの実体はどこでnewされているの? >' CABファイル展開 >objWshShell.Exec(CmdLine) > >' 実行コマンド格納 >Set objExecCmd = objWshShell.Exec(CmdLine) CABファイルの~ の2行いらないでしょ? 2重実行してないかい?

shou0995
質問者

お礼

ご回答ありがとうございます。 >objWshShellの実体はどこでnewされているの? レジストリからフォルダパスを取得する処理のすぐ上で、Set objWshShell = CreateObject("WScript.Shell")を宣言しております(記載漏れ申し訳ないです。。) 後、自分でも2行いらないと思ったので、実行コマンド格納のSet objExecCmd = objWshShell.Exec(CmdLine)だけで実行すると、CABファイルの展開が不十分で終わるのです。。 (650ファイルのCABですが、33個展開して永久ループに陥ります) ※2行にすると全て展開してくれるのですが。。 説明分かりにくいかもしれませんが、上記の現象で何か思い当たる点などありますでしょうか?

shou0995
質問者

補足

marimari01さんの、おっしゃる通り二重実行されていましたので、 ---------------------------------- ' CABファイル展開 objWshShell.Exec(CmdLine) ----------------------------------- の処理を消しました。 すると、CABファイルの展開が途中で止まります。 原因を探っているうちに、下記の場所が悪さしているみたいなのではずしました。 ------------------------------------ ' 実行コマンドが終了するまで待つ Do While objExecCmd.Status = 0 WScript.Sleep(3000) WScript.Echo "展開中です" & Err.Description Loop -------------------------------------- すると、スクリプトだけはどんどん進み終了しました。 (CABファイルの展開は追いつかず、スクリプトが終わった後も展開し続けています) スクリプトの終了=CABファイルの展開終了 という形には言語の特性上等無理なのでしょうか・・・?