【暴走防止】VBScriptを「死なせない」ためのタイムアウト監視術
こんにちは。現場の最前線で自動化を支えているエンジニアです。
VBScriptで業務自動化を始めると、誰もが一度は遭遇する恐怖があります。それが「無限ループ」や「外部リソースの応答待ちによるフリーズ」です。
「プログラムを走らせたまま昼食に行き、戻ってきたら画面が真っ白で止まっていた……」
こんな悲劇を繰り返さないために、今回はVBScriptの実行環境であるWSH(Windows Script Host)の心臓部を制御し、「スクリプトに制限時間を設ける」という極めて重要な技術を伝授します。
—
1. なぜ「タイムアウト」の設定が必要なのか?
VBScriptは非常に軽量で強力ですが、その分、実行プロセスに対する監視が甘くなりがちです。特に以下のような状況では、スクリプトが「ゾンビ」のように居座り続けます。
- ネットワーク監視: サーバーからの応答が永遠に返ってこない。
- ファイルI/O: 巨大なファイルを読み込もうとしてメモリ不足に陥る。
- ロジックミス: `Do While` ループの終了条件が一生満たされない。
これを放置すると、タスクマネージャーから手動でプロセスを殺す羽目になります。これでは「自動化」とは呼べませんよね。スクリプト自身に「時間制限」という自律的な防衛本能を持たせることが、プロの自動化エンジニアの第一歩です。
—
2. WScript.Timeout で「強制終了」を実装する
WSHには、スクリプト全体の実行時間を管理する `Timeout` プロパティが用意されています。これは、スクリプト実行開始からの「秒数」を指定するだけで、その時間を超えた瞬間にプロセスを強制終了させる最強の安全装置です。
実装コード例
‘ — 安全なスクリプトのテンプレート —
‘ 実行制限時間を「10秒」に設定する
WScript.Timeout = 10
‘ メイン処理の開始をログ出力
WScript.Echo “処理を開始します。10秒以内に終わらなければ強制終了します。”
‘ シミュレーション: 無限ループの罠
Do
‘ 何らかの重い処理やネットワーク待ちを想定
WScript.Sleep 1000 ‘ 1秒待機
WScript.Echo “実行中…”
Loop
‘ ここには到達しないはず
WScript.Echo “処理が正常に完了しました。”
このコードのポイント
- `WScript.Timeout = 10`: これを書くだけで、10秒経過した瞬間にWSHエンジンがプロセスを容赦なく停止させます。
- リスクの回避: どんなに深いループの中にいても、このタイマーは独立して機能します。これがWSHの設計思想の優れた点です。
—
3. 注意点:タイムアウトは「急死」である
ここで一つ、重要な心構えをお伝えします。`WScript.Timeout` による終了は、「エラーハンドリングを挟む猶予を与えない強制停止」です。
つまり、データベースの接続を解除したり、ログファイルを閉じたりといった「後始末」をする間もなくプロセスが消滅します。このため、以下の運用をセットで行うのが鉄則です。
1. クリティカルな処理は別プロセスで: データベースへの書き込みなどは、別の小規模なスクリプトで実行し、メインスクリプトからは呼び出す形にする。
2. ログは先行書き出し: 処理の「開始」だけでなく「進捗」をこまめにファイルへ書き出す(終了直前に何が起きていたか追跡するため)。
—
4. プロの現場での応用:多重起動の防止とセットで使う
タイムアウトの設定は、「多重起動防止」と組み合わせることで真価を発揮します。もしスクリプトがタイムアウトで止まった場合、次回起動時に「前回の残骸」が残っていると厄介です。
そんな時は、`GetObject` を使って実行中のプロセスをチェックするなどの工夫を組み合わせます。
—
最後に:自動化は「失敗」を前提に組むもの
初学者のうちは「コードが正しく動くこと」だけを考えがちですが、現場の自動化では「失敗した時にどう安全に止まるか」の方が100倍重要です。
今回紹介した `WScript.Timeout` は、あなたの書いたスクリプトに「自浄作用」を持たせるための最小にして最強の機能です。まずは手元のスクリプトの冒頭に、この一行を添えることから始めてみてください。
「止まらないプログラム」から「正しく安全に止まるプログラム」へ。
ここをクリアすれば、あなたはもう立派な自動化エンジニアの入り口に立っていますよ。
何か分からないことがあれば、いつでも聞いてくださいね。応援しています!
