VBScriptを掌握せよ:DriveTypeで極める「デバイス監視」の鉄則
業務自動化の世界において、VBScriptは「古き良き道具」ではない。Windows環境に深く根を張り、標準機能だけでOSの深部にアクセスできる「研ぎ澄まされたメス」だ。
特にFileSystemObject(FSO)を用いたデバイス監視は、USBメモリの挿入検知やネットワークドライブの自動同期など、現場の泥臭い課題を解決する最短ルートとなる。しかし、多くのエンジニアが書くコードは、例外処理が甘く、リソースを食いつぶす「素人のスクリプト」に留まっている。
今回は、`DriveType`プロパティを軸に、「現場で絶対に止まらない」堅牢な自動処理ロジックを伝授する。
—
1. なぜ「DriveType」が重要なのか
FSOの`Drives`コレクションを回せば、システムに認識されている全てのドライブを取得できる。だが、無差別に全ドライブへアクセスするのは三流だ。
- Fixed (2): 内蔵HDD/SSD。不用意に触ればシステムを壊す。
- Network (3): 共有フォルダ。応答速度が不安定で、タイムアウトのリスクを孕む。
- Removable (1): これこそがUSBメモリや外付けHDDだ。
プロフェッショナルの設計では、まずDriveTypeでフィルタリングし、必要なデバイスに対してのみ「IsReady」をチェックする。この順序を間違えると、中身のないカードリーダーにアクセスした瞬間にスクリプトがハングアップ、あるいは「ディスクを挿入してください」という無様なダイアログをユーザーに突きつけることになる。
—
2. 実践:プロフェッショナル・デバイス監視スクリプト
以下のコードは、特定のUSBメモリ(Removable)が接続されたことを検知し、即座にバックアップを開始する実務直結型のテンプレートだ。
Option Explicit
‘ ————————————————————————-
‘ 定数定義(マジックナンバーを排除し、保守性を高める)
‘ ————————————————————————-
Const DriveTypeRemovable = 1
Const DriveTypeFixed = 2
Const DriveTypeNetwork = 3
Const DriveTypeCDROM = 4
‘ 監視設定
Const TARGET_DRIVE_LABEL = “BKUP_USB” ‘ 監視対象のボリュームラベル
Const SLEEP_INTERVAL = 5000 ‘ 監視間隔(ミリ秒)
‘ ————————————————————————-
‘ メインループ
‘ ————————————————————————-
Dim fso, drive, isDetected
Set fso = CreateObject(“Scripting.FileSystemObject”)
Do
isDetected = False
‘ Drivesコレクションを走査
For Each drive In fso.Drives
‘ 1. まずはDriveTypeを判定(不要なデバイスへのアクセスを遮断)
If drive.DriveType = DriveTypeRemovable Then
‘ 2. デバイスが準備できているか(IsReady)を必ず確認
‘ これを怠ると、空のカードリーダー等で実行時エラーが発生する
If drive.IsReady Then
‘ 3. ボリュームラベルで特定の個体を識別(誤動作防止)
If drive.VolumeName = TARGET_DRIVE_LABEL Then
Call ExecuteBackupTask(drive.Path)
isDetected = True
End If
End If
End If
Next
‘ 負荷軽減のためのスリープ。CPUリソースを独占させないのがプロの流儀。
WScript.Sleep SLEEP_INTERVAL
‘ 開発時は無限ループに注意。実運用ではタスクスケジューラ等で制御する。
Loop
‘ ————————————————————————-
‘ バックアップ実行サブプロシージャ
‘ ————————————————————————-
Sub ExecuteBackupTask(drivePath)
On Error Resume Next ‘ 予期せぬファイルロック等に備える
Dim timestamp
timestamp = Replace(Replace(Now, “/”, “”), “:”, “”)
‘ ログ出力や実際のコピー処理をここに記述
‘ 例: fso.CopyFile “C:\Data\.db”, drivePath & “\Backup_” & timestamp & “\”
WScript.Echo “Device Detected: [” & drivePath & “] – Backup Started at ” & Now
If Err.Number <> 0 Then
‘ エラーハンドリング:データベース連携失敗や容量不足を想定
WScript.Echo “Error: ” & Err.Description
Err.Clear
End If
End Sub
‘ ————————————————————————-
‘ オブジェクトの解放(VBScriptのライフサイクルを意識する)
‘ ————————————————————————-
‘ ※無限ループのため到達しないが、関数の出口では常に意識すべき作法。
Set fso = Nothing
—
3. 現場で差がつく設計の要諦
① `IsReady`プロパティの絶対遵守
`DriveType`が `1 (Removable)` や `4 (CD-ROM)` の場合、ハードウェアが存在していても「メディアが挿入されていない」状態があり得る。この状態で `VolumeName` や `FreeSpace` プロパティを参照すると、VBScriptはエラーを吐く。「種類を確認してから、準備ができているか問う」。この二段構えが、堅牢なスクリプトの鉄則だ。
② ネットワークドライブ(DriveType = 3)の罠
ネットワークドライブを対象にする場合、ネットワークの瞬断によってスクリプトが数秒間フリーズすることがある。もし大規模なファイル操作を行うのであれば、FSOだけでなく、`WshNetwork`オブジェクトを併用して現在のマウント状況を正確に把握する設計が求められる。
③ パフォーマンスとリソース管理
上記のコードでは `WScript.Sleep` を入れている。これを忘れると、スクリプトはCPUの1コアを100%使い切り、他の業務アプリケーションを圧迫する「ウイルス紛いの挙動」を呈する。5秒〜10秒程度のインターバルは、実務上のリアルタイム性を損なわず、システムの静寂を保つ絶妙なラインだ。
—
4. チーフアーキテクトからの助言
「動けばいい」だけのコードは、負債でしかない。
特にファイルシステムを扱う自動化ツールは、アクセス権限、ディスク容量不足、デバイスの予期せぬ抜去など、常に「最悪のシナリオ」に晒されている。
今回紹介した `DriveType` によるフィルタリングは、そうした外乱を排除し、処理の対象を純体化するための第一歩だ。オブジェクトを生成したら必ず解放する(`Set Nothing`)、マジックナンバーを定数化する、エラーハンドリングを局所化する。これらの基本を積み重ねた先に、伝説と呼ばれるエンジニアの「美しい自動化」が存在する。
このコードをベースに、君の現場に合わせた最強の監視ツールを構築してほしい。
