【現場の鉄則】VBScriptで「なぜ止まった?」を可視化する。障害調査用・自動スクリーンショット捕獲モジュール
こんにちは。システム自動化の現場で長年、VBScriptと格闘してきたエンジニアです。
VBScriptを運用していると、必ずぶち当たる壁があります。それは「無人環境でエラーが起きたとき、画面で何が起きていたか分からない」という問題です。`On Error Resume Next` でエラーを握りつぶしてログを吐くだけでは、GUI上の異常(ポップアップの重なりや、想定外の警告)は特定できません。
今回は、エラー発生時に「その瞬間のデスクトップ」を強制的に画像として保存し、事後検証を劇的に楽にする「デバッグ用スナップショット・モジュール」を伝授します。
—
1. なぜVBScript単体では不可能なのか?
まず、VBScriptの限界を知りましょう。VBScriptはOS標準の「糊(のり)」のような言語であり、高度な画像処理ライブラリを内蔵していません。
そこで、「WScript.Shell」という強力な武器を使い、OSに組み込まれている「PowerShell」を裏で呼び出すというアプローチをとります。VBScriptから見れば、重たい画像処理はPowerShellに丸投げし、自分は制御に集中する。これが、伝説級の自動化エンジニアが使う「責任分界」の考え方です。
—
2. 障害調査用スナップショット・モジュールの実装
以下のコードを、あなたのスクリプトの「お守り」として組み込んでください。
‘ — 障害調査用:スナップショット保存プロシージャ —
Sub TakeScreenshot(fileName)
Dim shell, psCommand
Set shell = CreateObject(“WScript.Shell”)
‘ PowerShellを呼び出してデスクトップ全体をキャプチャするコマンド
‘ .NET FrameworkのSystem.Drawingを使用して高速に画像化します
psCommand = “powershell -Command “”Add-Type -AssemblyName System.Drawing; ” & _
“$bmp = New-Object System.Drawing.Bitmap([System.Windows.Forms.Screen]::PrimaryScreen.Bounds.Width, ” & _
“[System.Windows.Forms.Screen]::PrimaryScreen.Bounds.Height); ” & _
“$graphics = [System.Drawing.Graphics]::FromImage($bmp); ” & _
“$graphics.CopyFromScreen(0, 0, 0, 0, $bmp.Size); ” & _
“$bmp.Save(‘” & fileName & “‘, [System.Drawing.Imaging.ImageFormat]::Png); ” & _
“$bmp.Dispose(); $graphics.Dispose();”””
‘ ウィンドウを隠して実行(0)し、完了を待つ(True)
shell.Run psCommand, 0, True
Set shell = Nothing
End Sub
‘ — 実践的なエラーハンドリング例 —
On Error Resume Next
‘ ここにメインの処理が入ります
Err.Raise 51, “TestApp”, “仮想的な致命的エラー発生” ‘ わざとエラーを起こしてみる
If Err.Number <> 0 Then
Dim logPath
logPath = “C:\Temp\Error_” & Replace(Replace(Now, “/”, “”), “:”, “”) & “.png”
‘ エラーが起きたら即座に証拠を確保!
TakeScreenshot(logPath)
WScript.Echo “エラー発生!デスクトップ画面を保存しました: ” & logPath
WScript.Quit 1
End If
—
3. このコードが「プロ仕様」である理由
このコードには、初心者が陥りやすい罠を避けるための工夫が詰まっています。
- `shell.Run psCommand, 0, True` の重み:
第2引数の「0」はウィンドウを非表示にする設定です。黒い画面をユーザーに見せて驚かせないための配慮です。また、第3引数を「True」にすることで、「画像が保存し終わるまで次の処理に進まない」ように制御しています。これをしないと、スクリプトが速攻で終了してしまい、画像が保存される前にプロセスが消えることがあります。
- `.Dispose()` の重要性:
PowerShell側で `Dispose()` を呼んでいるのは、メモリリークを防ぐためです。業務自動化では「24時間365日動く」ことが求められます。小さなリソース解放の積み重ねが、サーバーの安定性を支えるのです。
—
4. 陥りやすいエラーと回避策
1. パスの権限問題: 保存先パス(`C:\Temp`など)に書き込み権限がないとスクリプトは沈黙します。必ず実行ユーザーに書き込み権限がある場所を指定しましょう。
2. マルチディスプレイ環境: 上記のコードは「メインディスプレイ」のみをキャプチャします。もしサブディスプレイにエラーが出ている場合は、PowerShell側の `[System.Windows.Forms.Screen]::AllScreens` を使う必要があり、少し難易度が上がります。まずはメイン画面から確実に押さえるのが、トラブル対応の鉄則です。
—
最後に:自動化は「失敗の記録」で強くなる
VBScriptは古い言語と言われますが、Windowsの深層心理を知り尽くせば、これほど強力な自動化ツールはありません。
今回紹介した「エラー発生時の証拠保存」は、あなたの作ったスクリプトを「ブラックボックス」から「自己報告できる賢いプログラム」へと進化させます。エラーが起きるのは悪いことではありません。「エラーが起きたときに何が起きたか知っている」ことこそが、エンジニアとしての格の違いを生みます。
さあ、恐れずに現場へ投入してみてください。きっと、あなたの自動化ライフを強力にサポートしてくれるはずですよ。
