【テクニカル・上級編】【暴走防止】WScript.Timeout プロパティ設定による無限ループの安全停止とタイムアウト監視 – VBScript (Visual Basic Scripting Edition)解析バイブル

スポンサーリンク

亡霊のようなスクリプトを飼い慣らす:WScript.Timeoutによる「完全停止」のアーキテクチャ

VBScriptは、現代のコンテナやマイクロサービスから見れば「化石」のような言語かもしれない。しかし、製造現場の制御PCや、レガシーなWindows Serverのタスクスケジューラという名の「深淵」において、今なおこの言語は支配的だ。

諸君が直面する最も恐ろしい敵は、何か? 構文エラーではない。「無言の沈黙」だ。ネットワークの瞬断、あるいは外部COMコンポーネントのデッドロックによって、スクリプトがプロセスの片隅で死んだまま、ゾンビのようにメモリを食い潰し続ける事態。これこそが、システム管理者にとっての悪夢である。

今日は、VBScriptが「暴走」という業を背負わないための、最後の防壁について語ろう。

1. なぜ「WScript.Timeout」なのか

VBScriptには、マルチスレッドという概念が存在しない。WSH環境において、スクリプトは単一の実行スレッドで完結する。一度無限ループや重いI/O待ちに突入すれば、OS側から強制終了(Taskkill)を食らわせる以外に術はない。

ここで重要なのは、「スクリプト自身に寿命(TTL)を握らせる」という設計思想だ。

`WScript.Timeout` は、実行開始から指定した秒数が経過した瞬間に、WSHエンジンがスクリプトを強制終了させるプロパティである。これは、泥沼化した処理を切り捨てるための、冷徹かつ究極の安全装置だ。

2. 極限の制御:WScript.Timeoutの実装パターン

ただ値を設定するだけでは素人だ。システム連携における真のエンジニアは、動的にタイムアウトを制御する。

‘ ==================================================================
‘ 暴走防止:実行時間監視ユニット
‘ ==================================================================
Option Explicit

‘ 実行時間を60秒に制限する(単位は秒)
‘ ネットワークI/Oを含む場合は、あらかじめ予測される最大時間を設定せよ
WScript.Timeout = 60

On Error Resume Next

‘ メイン処理実行
Call ExecuteCriticalProcess()

If Err.Number <> 0 Then
‘ エラーハンドリング:タイムアウト時はWSHが終了させるため、
‘ ここでは「ログの永続化」のみを意識する
Call LogError(“Critical failure occurred: ” & Err.Description)
End If

On Error GoTo 0

Sub ExecuteCriticalProcess()
‘ ここに重いネットワーク通信や外部連携を記述
‘ 万が一ここで無限ループに陥っても、60秒後にプロセスは消滅する
End Sub

Sub LogError(msg)
‘ ファイルIOは極力シンプルに。COMオブジェクトの多用は避けよ
Dim fso, logFile
Set fso = CreateObject(“Scripting.FileSystemObject”)
Set logFile = fso.OpenTextFile(“C:\Logs\Error.log”, 8, True)
logFile.WriteLine Now & ” : ” & msg
logFile.Close

‘ オブジェクトの明示的解放:VBScriptのGCを信用するな
Set logFile = Nothing
Set fso = Nothing
End Sub

3. シニアエンジニアが守るべき「メモリと生存戦略」

`WScript.Timeout` でプロセスを殺す際、メモリリークを気にする者がいるかもしれない。だが、恐れることはない。プロセスごとOSが回収する以上、メモリの断片化を気にする必要はないのだ。

ただし、以下の鉄則だけは守れ。

  • 外部リソースのコミットは最後に: DBへの書き込みやファイル保存は、処理の最深部で行うな。トランザクションの整合性が取れなくなる。
  • Objectの破棄: `Set obj = Nothing` を忘れるな。スクリプトがタイムアウトするまでの間、無駄な参照を保持することは、他のプロセスに対するメモリプレッシャーになる。
  • WMI経由の監視(上位互換策): もし、より詳細な監視が必要なら、WSH単体ではなく、外部から `Win32_Process` を監視する別プロセス(VBS/PowerShell)を起動し、親プロセスとして「子プロセスの死」を監視するアーキテクチャを組め。

4. 結びに:レガシーとの付き合い方

VBScriptを駆使する現場は、往々にして監視環境が不十分だ。だからこそ、スクリプトそのものに「自己消滅する権利」を与えておく必要がある。

「プログラムは、異常を検知した瞬間に潔く死ぬべきである」

これが、長年数多のシステムを生き抜いてきた私の結論だ。`WScript.Timeout` は、単なるプロパティではない。システムの安定稼働を担保するための、エンジニアの矜持そのものである。

諸君、コードを書くときは常に「この処理が二度と戻ってこないとしたら?」という自問自答を忘れるな。それこそが、伝説のエンジニアへの第一歩だ。

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