【テクニカル・上級編】【ZIP自動圧縮・解凍】Shell.Application を活用した外部ツール不要のファイルアーカイブ自動化 – VBScript (Visual Basic Scripting Edition)解析バイブル

スポンサーリンク

VBScriptを掌握する極限の知見:Shell.Applicationで挑むZIP自動アーカイブの深淵

古のOSから現代のWindows 11に至るまで、我々エンジニアの足元を支え続けてきたVBScript。現代では「レガシー」と揶揄されることもあるが、OSの深部に触れるためのその軽量さと、環境構築不要の即時性は、今なお自動化の現場で絶対的な信頼を置ける武器だ。

今回は、外部のライブラリやサードパーティ製ツールに依存することなく、`Shell.Application` オブジェクトを駆使してWindows標準のZIP機能を掌握する手法を解説する。これは単なるコードの紹介ではない。OSの非同期処理とメモリ管理の限界に挑む、アーキテクチャの作法だ。

1. 舞台裏の真実:Shell.Applicationという「非同期の獣」

多くのエンジニアが `Shell.Application` で躓く最大の要因は、これが「GUIの背後で動作するWindowsシェルそのもの」であるという点を見落としていることだ。

`Namespace` メソッドでZIPを操作する際、OSはバックグラウンドでフォルダとしてZIPをマウントし、コピー処理を行う。この処理は非同期で走る。つまり、スクリプトが次の行へ進んだ瞬間、まだコピーが終わっていないという悲劇が起こる。

「なぜかZIPが空のまま生成される」という現象に遭遇したなら、それは待機処理(Sleep)を怠ったか、オブジェクトのライフサイクル管理が破綻している証拠である。

2. 堅牢な圧縮・解凍を実装する:実用コード

以下に、実務でそのまま利用可能なクラスライブラリ的なアプローチを示す。重要なのは、処理の完了を待機するためのループ戦略だ。

‘ — Shell.ApplicationによるZIPアーカイブ制御 —
Option Explicit

‘ 圧縮処理の核心部
Sub ZipFile(strSourcePath, strZipFile)
Dim objShell, objFSO, objZipFile, objSource
Set objShell = CreateObject(“Shell.Application”)
Set objFSO = CreateObject(“Scripting.FileSystemObject”)

‘ 空のZIPファイルを作成(ヘッダー情報が必要)
If Not objFSO.FileExists(strZipFile) Then
Dim ts: Set ts = objFSO.CreateTextFile(strZipFile, True)
ts.Write “PK” & Chr(5) & Chr(6) & String(18, vbNullChar)
ts.Close
End If

Set objZipFile = objShell.NameSpace(strZipFile)
Set objSource = objShell.NameSpace(strSourcePath)

‘ コピー実行(非同期)
objZipFile.CopyHere objSource.Items

‘ 【重要】処理完了まで待機する極限のループ
‘ 圧縮が完了するまでオブジェクトを解放してはならない
Do Until objZipFile.Items.Count > 0
WScript.Sleep 500
Loop

‘ 後始末:メモリリークを防ぐための明示的解放
Set objSource = Nothing
Set objZipFile = Nothing
Set objShell = Nothing
Set objFSO = Nothing
End Sub

3. シニアエンジニアが守るべき「3つの鉄則」

① メモリ管理の潔癖性

VBScriptのガベージコレクションを信用してはならない。特に `Shell.Application` のようなCOMオブジェクトは、明示的に `Nothing` を代入し、参照カウントをゼロにしなければ、スクリプト終了後もプロセスがゾンビとして残る可能性がある。

② パス解決の厳密性

`Shell.Namespace` は絶対パスを要求する。`WScript.ScriptFullName` から親ディレクトリを取得し、`FSO.GetAbsolutePathName` を通して正規化する習慣を徹底せよ。相対パスに逃げるのは、バグの温床を育てる行為に他ならない。

③ 非同期待ちのタイムアウト実装

上記のコードでは単純なループを使用しているが、実環境では無限ループを避けるためにカウンタを導入すべきだ。「X秒経過しても完了しない場合は例外をスローする」という防衛的プログラミングが、自動化システムの安定性を担保する。

4. 最後に:なぜ今、VBScriptなのか

PowerShellやPythonといったモダンなツールがある中で、なぜVBScriptを使うのか?
答えはシンプルだ。「何もインストールされていない環境」こそが、我々エンジニアにとっての真の戦場だからだ。

レガシーシステムを保守する際、勝手にツールをインストールすることは許されない。そんな制約の中で、WindowsというOSが提供するAPIを直接叩き、目的を遂行する。これこそが、技術の真髄を理解したエンジニアの矜持である。

この知見を、あなたの現場の自動化パイプラインに組み込んでほしい。コードは語る。あなたの技術レベルがどこにあるのかを。

タイトルとURLをコピーしました