VBScriptを極める:MakeCABとFSOが奏でる「非同期アーカイブ」の極意
VBScriptは「レガシー」などと揶揄されることもあるが、Windowsの深層部を叩くための最速のスクリプト言語であることに変わりはない。特に、膨大なログファイルの整理といった、インフラの保守運用における泥臭い自動化において、その軽量さは他の追随を許さない。
今日は、FSO(FileSystemObject)の網羅的な走査と、Windows標準のMakeCABツールを組み合わせた、堅牢でメモリ効率を極限まで高めたアーカイブ・アーキテクチャを伝授する。
1. なぜ「非同期」である必要があるのか
単に `WScript.Shell.Run` で `makecab` を叩くだけでは、アーカイブ対象が数千ファイルを超えた瞬間にシステムはフリーズする。特にログの圧縮はCPU負荷が高い。
シニアエンジニアが考えるべきは「非同期実行の制御」と「リソースの解放」だ。`WScript.Shell`の `Exec` メソッドを使い、プロセスの終了を検知して次へ進む同期制御と、ファイル消去の安全性を担保するトランザクション的思考が不可欠となる。
2. 実装コード:堅牢なアーカイブ・エンジン
このスクリプトは、指定したディレクトリ内の「指定日数経過したログ」を抽出し、圧縮後に元ファイルを削除する。エラーハンドリングとオブジェクト管理の細部に注目してほしい。
Option Explicit
‘ メモリリークを許さない:定数とオブジェクトの定義
Const TargetDir = “C:\Logs\App”
Const ArchiveDir = “C:\Logs\Archive”
Const RetentionDays = 30
Dim fso, folder, file, shell, execObj
Set fso = CreateObject(“Scripting.FileSystemObject”)
Set shell = CreateObject(“WScript.Shell”)
‘ 処理対象ディレクトリの検証
If Not fso.FolderExists(TargetDir) Then WScript.Quit
Set folder = fso.GetFolder(TargetDir)
‘ ファイル走査:FSOのコレクションはメモリを消費するため、ループを最小限に
For Each file In folder.Files
‘ 日付条件の判定
If DateDiff(“d”, file.DateLastModified, Now) > RetentionDays Then
‘ MakeCABの非同期実行
‘ /V1: 冗長出力を抑制, /D: 圧縮アルゴリズムの設定など
Dim cmd
cmd = “makecab “”” & file.Path & “”” “”” & ArchiveDir & “\” & file.Name & “.cab”””
‘ Execを使用することで標準出力をハンドリング可能にする
Set execObj = shell.Exec(cmd)
‘ 非同期完了待機:CPUを使いすぎないようSleepを挟む
Do While execObj.Status = 0
WScript.Sleep 100
Loop
‘ 圧縮成功時のみ元ファイルを削除する安全策
If fso.FileExists(ArchiveDir & “\” & file.Name & “.cab”) Then
file.Delete True
End If
End If
Next
‘ オブジェクトの明示的解放:VBScriptの鉄則
Set execObj = Nothing
Set shell = Nothing
Set folder = Nothing
Set fso = Nothing
3. チーフアーキテクトからの「極限の知見」
このコードを実戦投入する際、以下の3点についてさらに深掘りしてほしい。
① FSOのメモリ管理の罠
数万ファイルを超えるフォルダを `folder.Files` で列挙すると、VBScriptのプロセスはメモリを急速に食い潰す。数が多い場合は、`WScript.Shell` から `dir /b` コマンドを叩き、その標準出力をパイプで読み取る方式へ切り替えるべきだ。メモリ負荷を一定に保つのがプロのコードである。
② MakeCABの限界と代替案
MakeCABは古いツールだが、OS標準でインストール不要というメリットは大きい。もし、より高度なアーカイブ(パスワード付与やフォルダ階層維持)が必要なら、`7-Zip` のコマンドライン版 (`7z.exe`) を使用し、同様に `WScript.Shell.Exec` でラップする構成に移行せよ。
③ ログの「読み取り専用」属性と競合
ログファイルは、アプリケーションが書き込みを掴んでいる可能性がある。`fso.Delete` を実行する前に、必ず `On Error Resume Next` とエラーコード検証を組み込み、削除失敗時のリトライ処理(指数バックオフなど)を実装すること。
結びに
スクリプトを書くことは、単に処理を記述することではない。システムという生命体を、いかに効率よく、いかに静かに、そしていかに確実に運用させるかという「設計思想」をコードに落とし込むことである。
VBScriptは過去の遺物ではない。OSの深層部を操るための、最も鋭利なナイフであり続ける。君が現場で直面するであろう無数のログファイルという名の混沌を、この手法で静かに鎮めてほしい。
