
お世話になっております。
VBScriptを使用して、あるディレクトリにあるCABファイルを展開するプログラムを作成しているのですが問題がありまして、分かる方いらっしゃいましたらぜひご教授頂きたいです。
■問題
CABファイルを展開している間はスクリプトをストップさせ、展開が終了したら次のCABファイルを展開しにいくと言うプログラムですが、CABファイル展開が終了しても、sleepのDo whileを抜けてくれない。
■以下ソースです↓↓↓
Option Explicit
On Error Resume Next
Dim objWshShell ' WshShell オブジェクト
Dim strHomePath ' ホームパス
Dim objFSO ' FileSystemObject
Dim strFolder ' フォルダ名
Dim strCab ' CABファイルパス
Dim CmdLine ' 実行コマンド
Dim objExecCmd ' 実行コマンド情報
strFolder = ""
strHomePath = ""
strCab = ""
レジストリからフォルダパスを取得する処理
If strHomePath <> "" Then
Set objFSO = CreateObject("Scripting.FileSystemObject")
If Err.Number = 0 Then
strFolder = strHomePath
' CABファイルのパス
strCab = strFolder & "\CabG.CAB"
' CABファイルの展開コマンド作成
CmdLine = "expand """ & strCab & """ -f:* """ & strFolder & """"
'CABファイルの存在確認
If objFSO.FileExists(strCab) = True Then
' CABファイル展開
objWshShell.Exec(CmdLine)
' 実行コマンド格納
Set objExecCmd = objWshShell.Exec(CmdLine)
WScript.Echo "成功:コマンドを格納" & CmdLine & Err.Description
' 実行コマンドが終了するまで待つ
Do While objExecCmd.Status = 0
WScript.Sleep(3000)
WScript.Echo "展開中です" & Err.Description
Loop
WScript.Echo "成功:コマンド終了" & CmdLine & Err.Description
'展開したCABファイルを削除する
'objFSO.DeleteFile strCab, True
'展開で作成されるOSDファイルを削除する
Else
WScript.Echo "エラー:" & strCab & "が存在しません" & Err.Description
End If
順次同じようなロジックで次のCABファイルを展開する
■↑↑↑↑
DOS画面から起動すると、do while文が永遠に抜けれなくなります。。。
いろいろと調べて試行錯誤しているのですが、なかなか解決に至りません。
ぜひ、よろしくお願い致します。
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
marimari01さん、誠にありがとうございます。
これこそ意図していた動きです!!
いろいろ原因探っててobjExecCmd.Statusが永遠に0のままだと思っていたら、バッファがいっぱいになっていたのですね。
参考までにお伺いしたいのですが、なぜバッファがいっぱいになってるって分かったのでしょうか…?
(VBScript素人なもので、全く分かりませんでした。。)
ホントにありがとうございました。
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モードがあればいいですが。
なるほど、とても勉強になりました。
バッファと言う存在を、今まで全く気にしたことが無かったのがお恥ずかしい話です。。
ホントにありがとうございました。
これからも、もっとがんばろうと思います。
No.1
- 回答日時:
objWshShellの実体はどこでnewされているの?
>' CABファイル展開
>objWshShell.Exec(CmdLine)
>
>' 実行コマンド格納
>Set objExecCmd = objWshShell.Exec(CmdLine)
CABファイルの~
の2行いらないでしょ?
2重実行してないかい?
この回答への補足
marimari01さんの、おっしゃる通り二重実行されていましたので、
----------------------------------
' CABファイル展開
objWshShell.Exec(CmdLine)
-----------------------------------
の処理を消しました。
すると、CABファイルの展開が途中で止まります。
原因を探っているうちに、下記の場所が悪さしているみたいなのではずしました。
------------------------------------
' 実行コマンドが終了するまで待つ
Do While objExecCmd.Status = 0
WScript.Sleep(3000)
WScript.Echo "展開中です" & Err.Description
Loop
--------------------------------------
すると、スクリプトだけはどんどん進み終了しました。
(CABファイルの展開は追いつかず、スクリプトが終わった後も展開し続けています)
スクリプトの終了=CABファイルの展開終了 という形には言語の特性上等無理なのでしょうか・・・?
ご回答ありがとうございます。
>objWshShellの実体はどこでnewされているの?
レジストリからフォルダパスを取得する処理のすぐ上で、Set objWshShell = CreateObject("WScript.Shell")を宣言しております(記載漏れ申し訳ないです。。)
後、自分でも2行いらないと思ったので、実行コマンド格納のSet objExecCmd = objWshShell.Exec(CmdLine)だけで実行すると、CABファイルの展開が不十分で終わるのです。。
(650ファイルのCABですが、33個展開して永久ループに陥ります)
※2行にすると全て展開してくれるのですが。。
説明分かりにくいかもしれませんが、上記の現象で何か思い当たる点などありますでしょうか?
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Excel(エクセル) フォルダ内のワードファイルをPDFに一括変換するVBA 3 2023/06/09 16:51
- Visual Basic(VBA) VBAが止まります。 2 2022/09/02 14:02
- Visual Basic(VBA) エクセルのマクロについて教えてください。 2 2023/07/06 17:46
- Visual Basic(VBA) VBAでの共有パスにつきまして 1 2023/03/04 17:24
- Visual Basic(VBA) 貼り付けた値が消えていく 以下はソースファイルの2番目のシートのB6から最終行を取得 ターゲットファ 2 2023/07/27 12:23
- Visual Basic(VBA) VBAのユーザーフォームのテキストボックスに入力制限をしたい 6 2022/11/15 08:28
- Visual Basic(VBA) VBA★PDFをPDFアプリで印刷しようと思っていますが上手くゆきません 1 2022/06/06 22:04
- Visual Basic(VBA) 集めたシートのシート名を変更したい。 下記のコードでサブフォルダにあるファイルのSheet3を集めて 6 2022/08/23 10:38
- Visual Basic(VBA) サブフォルダ(データ)にある複数の.xlsxファイルのSheet3のA2セルの値で01から左側をB2 2 2022/08/14 15:46
- Visual Basic(VBA) VBA This Workbookモジュールを別ファイルにコピーする方法 1 2022/09/14 01:51
このQ&Aを見た人はこんなQ&Aも見ています
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
Vba Array関数について教えてく...
-
【マクロ】シートの変数へ入れ...
-
【マクロ】並び替えの範囲が、...
-
エクセルのVBAコードと数式につ...
-
エクセルのマクロについて教え...
-
エクセルの改行について
-
【VBA】 結合セルに複数画像と...
-
vbsでのwebフォームへの入力制限?
-
算術演算子「¥」の意味について
-
【マクロ】売上一覧YYYYMMDDHHS...
-
【マクロ】開いているブックの...
-
Vba セルの4辺について罫線が有...
-
vb.net(vs2022)のtextboxのデザ...
-
ダブルクリックで貼り付けた画...
-
VBAの「To」という語句について
-
VBAでユーザーフォームを指定回...
-
VBAでCOPYを繰り返すと、処理が...
-
【マクロ】変数を使った、文字...
-
エクセルのVBAコードについて教...
-
ワードの図形にマクロを登録で...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
Vba セルの4辺について罫線が有...
-
vbsでのwebフォームへの入力制限?
-
【ExcelVBA】5万行以上のデー...
-
【マクロ】売上一覧YYYYMMDDHHS...
-
【マクロ】開いているブックの...
-
【マクロ】並び替えの範囲が、...
-
エクセルの改行について
-
エクセルのマクロについて教え...
-
vb.net(vs2022)のtextboxのデザ...
-
VBAでCOPYを繰り返すと、処理が...
-
VBA ユーザーフォーム ボタンク...
-
エクセルのVBAコードと数式につ...
-
エクセルのVBAコードについて教...
-
[VB.net] ボタン(Flat)のEnable...
-
【マクロ】変数を使った、文字...
-
改行文字「vbCrLf」とは
-
質問58753 このコードでうまく...
-
【マクロ】シートの変数へ入れ...
-
ワードの図形にマクロを登録で...
-
算術演算子「¥」の意味について
おすすめ情報