VBScriptを掌握する極限の知見:FileSystemObjectの`DriveExists`メソッドによる堅牢なドライブ死活監視
レガシーシステムの深部、あるいは現代のWindows自動化の隠れた基盤において、VBScript(Visual Basic Scripting Edition)はいまだに現役のインフラストラクチャとして稼働し続けている。GUIを持たない常駐タスク、深夜のバッチ処理、そして物理的な外部ストレージを介したデータ連携。これらの中枢において最も排除すべきは、「予期せぬランタイムエラーによるプロセスの沈黙」である。
今回は、File System Object(以下、FSO)の基本メソッドである `DriveExists` に焦点を当て、単なるAPIの使い方ではなく、「ハードウェアの物理的・論理的疎通をいかに安全にハンドリングするか」という、シニアエンジニアが知るべき極限の知見を紐解く。
—
1. なぜ `DriveExists` なのか?——「楽観的実行」という名の悪徳
USBメモリ、外付けHDD、あるいはVPN経由のネットワークドライブ(UNC/マウントドライブ)。これらは本質的に「いつ消えるか分からない」不安定なリソースだ。
未接続のドライブに対して、スクリプトが直接ファイルの読み書き(例: `OpenTextFile` や `CopyFile`)を試みた瞬間、VBScriptの実行エンジンは致命的なランタイムエラー(エラー番号:71 “Disk not ready” など)を吐き出し、容赦なくスクリプトを強制終了させる。
ここで初心者が陥りがちなアンチパターンが、`On Error Resume Next` によるエラーの全握りつぶしである。
‘ 【悪手】エラーフックに頼った実装
On Error Resume Next
Set fso = CreateObject(“Scripting.FileSystemObject”)
fso.CopyFile “D:\data\export.csv”, “C:\archive\”
‘ エラーハンドリングの文脈が曖昧になり、パーミッションエラーなのかドライブ不在なのか判別不能になる
On Error GoTo 0
このアプローチは、コードの意図を曖昧にし、デバッグを困難にする。「障害の予見」ではなく「障害の事後処理」に依存するシステムは、実務において確実に破綻する。
物理的・論理的依存関係を持つ外部ストレージを扱う場合、処理を実行する前に 「ドライブがOSレベルで認識されているか」 を明示的に同期的に確認する。これがエンタープライズ品質の基本原則である。
—
2. `DriveExists` の深層とメモリ最適化の作法
FSOのインスタンス生成と `DriveExists` の評価には、VBScriptランタイム特有のライフサイクル管理が存在する。これを軽視すると、特に長時間の常駐プロセスや大量ループ処理において、メモリリークの温床となる。
以下の実用コードを見てほしい。これは、単にメソッドを呼ぶだけでなく、COMコンポーネントの明示的解放、ドライブ文字の正規化、そしてネットワークドライブ特有の遅延を考慮した堅牢な設計を実装したものである。
Option Explicit
‘ ==============================================================================
‘ Module: SafeDriveChecker.vbs
‘ Description: 外付けドライブの接続状態を安全に判定し、安全なデータ連携を行う
‘ ==============================================================================
Dim targetDrive, isConnected
targetDrive = “D:” ‘ 判定対象のドライブレター
isConnected = CheckDriveConnection(targetDrive)
If isConnected Then
WScript.Echo “【INFO】ドライブ ” & targetDrive & ” は正常に接続されています。処理を継続します。”
‘ ここに実際のファイル操作ロジックを記述
Else
WScript.Echo “【CRITICAL】ドライブ ” & targetDrive & ” が検出されません。処理を中断します。”
‘ ログ出力、アラート発報などのフェイルセーフ処理へ
WScript.Quit(1)
End If
‘ ——————————————————————————
‘ Function: CheckDriveConnection
‘ Args: strDriveLetter (String) – 例: “D:” または “D”
‘ Returns: Boolean
‘ ——————————————————————————
Function CheckDriveConnection(ByVal strDriveLetter)
Dim fso, normalizedDrive, result
result = False
‘ 1. 引数の正規化(末尾のコロンの有無を吸収)
strDriveLetter = Trim(strDriveLetter)
If UCase(Right(strDriveLetter, 1)) <> “:” Then
strDriveLetter = strDriveLetter & “:”
End If
‘ 2. FSOインスタンスの生成(COMコンポーネントの遅延バインディング)
Set fso = CreateObject(“Scripting.FileSystemObject”)
‘ 3. 厳密な例外考慮を伴うDriveExistsの実行
‘ ※ DriveExistsは、”D:” のようなフォーマットを要求する
On Error Resume Next
result = fso.DriveExists(strDriveLetter)
‘ 万が一のCOM例外(オブジェクト不整合など)をトラップ
If Err.Number <> 0 Then
result = False
Err.Clear
End If
On Error GoTo 0
‘ 4. 【極限の知見】メモリの明示的解放
‘ VBScriptのガベージコレクションに依存せず、スコープアウト前に確実に破棄する
Set fso = Nothing
CheckDriveConnection = result
End Function
—
3. シニアエンジニアが踏むべき「現場の罠」と高度な拡張
上記のコードで基本は網羅できるが、実務の現場ではさらなる変数が襲いかかる。特に以下の2点については、アーキテクトとして考慮せざるを得ない。
A. ネットワークドライブ(UNC / マッピングドライブ)のタイムアウト問題
`DriveExists` は高速に動作するが、対象が切断されたネットワークドライブ(Zドライブなど)である場合、OSのネットワークドライバが応答するまでに数秒から数十秒のブロッキング(フリーズ)が発生することがある。
これを回避するため、VBScript単体ではなく、WMI(Windows Management Instrumentation)の `Win32_LogicalDisk` クラスを併用し、デバイスの可用性をステータスコードベースで監視する設計も視野に入れるべきだ。
B. COMオブジェクトの解放(`Set ◯◯ = Nothing`)の哲学
「VBScriptはスクリプト終了時に自動でメモリが解放されるから `Nothing` は不要だ」という俗説がある。これは短命なスクリプトであれば真である。
しかし、タスクスケジューラから呼び出され、何千回もループする常駐型VBScriptや、他のCOMオブジェクト(Excel.ApplicationやWScript.Networkなど)と複合的に連携するシステムにおいて、インスタンスの放置は確実なメモリ肥大化(Bloat)を引き起こす。「生成したリソースは、そのスコープ内で責任を持って破壊する」。これがプロフェッショナルのコード規約である。
—
総括
たった一行の `fso.DriveExists(“D:”)`。
しかし、その背後にあるエラーハンドリングの哲学、COMオブジェクトのライフサイクル管理、そしてインフラストラクチャの物理的変動に対する耐性を理解しているか否かで、書くコードの「格」は決定的に変わる。
レガシー技術であっても、極限まで突き詰めれば、そこには揺るぎないエンジニアリングの美学が存在する。脆弱なスクリプトを淘汰し、止まらない自動化基盤を構築せよ。
