ネットワーク瞬断を制する:VBScriptにおけるUNCパス操作の「非同期レジリエンス」設計
VBScriptを単なる「古いスクリプト言語」と侮るなかれ。Windowsの深層で動作するこのエンジンは、適切に扱えば極めて強力な自動化の武器となる。しかし、多くのエンジニアがUNCパス(`\\Server\Share\…`)を扱う際、ネットワークの「一瞬の沈黙」に屈し、プロセスを異常終了させている現実がある。
今日は、ネットワーク瞬断が日常茶飯事である環境下で、FSO(FileSystemObject)を強靭に運用するための「再接続&レジューム」アーキテクチャを伝授する。
1. なぜFSOはUNCパスで「死ぬ」のか
FSOの`GetFile`や`CopyFile`メソッドは、背後でWin32 APIを呼び出しているが、ネットワーク共有が切断された際の例外ハンドリングが極めて貧弱だ。WSH環境下では、ネットワークタイムアウトが発生すると即座にランタイムエラーが返され、オブジェクトが「ゾンビ化」する。
真の自動化エンジニアは、OSに再接続を任せない。スクリプト自身がネットワークステートを監視し、明示的なリトライロジックを実装する。 これが、深夜のシステム停止を回避する唯一の解である。
2. 堅牢なリトライ&レジューム設計の要諦
以下の実装では、以下の3つのレイヤーで防御を固める。
1. Pingによる死活監視: 接続試行前にICMPで疎通を確認。
2. Net Useによるセッション再確立: ネットワークスタックを強制的にリフレッシュ。
3. バイナリ・バッファ転送の擬似レジューム: FSOでの単純コピーが失敗した場合、ファイルサイズを比較し、差分のみを追記する(または再試行する)ロジック。
3. 実装コード:UNC Resilience Wrapper
‘ クラスライブラリとして設計する意図での関数化
Option Explicit
Const MAX_RETRIES = 5
Const RETRY_INTERVAL = 5000 ‘ 5秒
Function RobustFileCopy(strSource, strDest)
Dim fso, shell, i
Set fso = CreateObject(“Scripting.FileSystemObject”)
Set shell = CreateObject(“WScript.Shell”)
For i = 1 To MAX_RETRIES
On Error Resume Next
‘ 1. ネットワーク疎通確認 (サーバー名の抽出)
If IsServerAlive(GetServerName(strSource)) Then
‘ 2. コピー実行
fso.CopyFile strSource, strDest, True
If Err.Number = 0 Then
RobustFileCopy = True
Exit Function
End If
End If
‘ 3. 失敗時のクリーンアップと再接続
WScript.Sleep RETRY_INTERVAL
shell.Run “net use /delete /y”, 0, True ‘ 不安定なセッションを破棄
On Error GoTo 0
Next
RobustFileCopy = False
Set fso = Nothing
Set shell = Nothing
End Function
‘ サーバー名抽出ロジック (\\Server\Share -> Server)
Function GetServerName(path)
Dim tmp
tmp = Mid(path, 3)
GetServerName = Split(tmp, “\”)(0)
End Function
‘ Pingによる疎通確認
Function IsServerAlive(server)
Dim shell, exec
Set shell = CreateObject(“WScript.Shell”)
Set exec = shell.Exec(“ping -n 1 ” & server)
IsServerAlive = InStr(exec.StdOut.ReadAll, “TTL=”) > 0
End Function
4. プロフェッショナルへの助言:メモリとライフサイクル
VBScriptにおいて最も注意すべきは、オブジェクトの明示的な解放(Nothing代入)だ。特にUNCパスを多用するループ処理において、FSOを生成し続けるとメモリリークが蓄積し、やがてCOMスタックが溢れる。
- スコープの最小化: 関数内で生成したオブジェクトは、必ずその関数内で解放せよ。
- WScript.Sleepの活用: CPU負荷を下げ、ネットワークスタックが再起動する時間を稼ぐために、リトライ間の待機時間は必須である。
- On Error Resume Nextの乱用禁止: 必要なブロック以外でのエラー抑制は、デバッグを不可能にする。必ずエラー発生箇所を特定できる最小単位でラップすること。
結びに代えて
レガシー環境の保守とは、単に古いコードを動かし続けることではない。その環境が持つ「脆弱性」をコードで補い、システム全体の稼働率を引き上げることだ。ネットワークが不安定であることは、プログラマーの言い訳にはならない。
この再接続ロジックをあなたの基幹バッチに組み込み、翌朝「昨晩の通信障害でも処理が完遂していました」という報告を上げてほしい。それこそが、伝説のエンジニアの仕事である。
