【実務・中級編】【障害調査用画面キャプチャ機能】エラー発生時に全画面スナップショットを自動保存する例外発生時デバッグモジュール – VBScript (Visual Basic Scripting Edition)解析バイブル

スポンサーリンク

VBScriptを掌握せよ:障害発生時に「現場の証拠」を自動保存する堅牢なデバッグ戦略

現場で動いているVBScriptが「なぜか止まった」。管理者が駆けつけた時には既にエラーダイアログは閉じられ、画面は切り替わっている。この「再現性のない悲劇」を繰り返すのは、エンジニアとして最も避けるべき事態だ。

VBScriptは枯れた言語だが、だからこそ「異常系をどうハンドリングするか」が、そのシステムの寿命を決める。 今回は、エラー発生時に「その瞬間のデスクトップ画面」を自動保存し、事後検証を完全なものにするための高度な例外処理モジュールを伝授する。

1. なぜ `On Error Resume Next` は諸刃の剣なのか

多くの初学者は `On Error Resume Next` を「エラーを無視する魔法」だと勘違いしている。実務におけるVBScriptでは、これは「エラーが発生した事実を自らハンドリングし、その時のコンテキストを保護するための防壁」でなければならない。

単に無視して先へ進むコードは、単なる技術的負債だ。エラーが発生した瞬間、スクリプトのメモリ空間を凍結し、何が起きたかを記録する。この設計思想こそが、プロフェッショナルとアマチュアの分水嶺である。

2. 実装:PowerShellを「目」として使う

VBScript単体では画面キャプチャというリッチな機能は持たない。だが、我々には `WScript.Shell` がある。これを利用して、Windows標準装備のPowerShellをバックエンドで駆動させる。

以下は、プロダクション環境でそのまま使える、エラーハンドリング付きのキャプチャモジュールだ。

‘ — 障害調査用デバッグモジュール —
Option Explicit

‘ メイン処理のサンプル
Sub Main()
On Error Resume Next

‘ ここで意図的にエラーを発生させる(例:存在しないファイルへのアクセス)
Dim fso : Set fso = CreateObject(“Scripting.FileSystemObject”)
Dim file : Set file = fso.OpenTextFile(“C:\NonExistent.txt”, 1)

‘ エラーが発生していればキャプチャを起動
If Err.Number <> 0 Then
CaptureDesktop “ErrorLog_” & Replace(Now, “/”, “-“) & “.png”
WScript.Echo “致命的なエラーが発生しました。デスクトップに証拠を保存しました。”
Err.Clear
End If
End Sub

‘ 画面キャプチャ関数
Sub CaptureDesktop(fileName)
Dim shell : Set shell = CreateObject(“WScript.Shell”)
Dim desktopPath : desktopPath = shell.SpecialFolders(“Desktop”)
Dim savePath : savePath = desktopPath & “\” & fileName

‘ PowerShellを呼び出して画面をキャプチャするワンライナー
‘ .NETのSystem.Drawingを使用し、メモリ効率を最大限に高める
Dim psCmd : psCmd = “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); ” & _
“$graph = [System.Drawing.Graphics]::FromImage($bmp); ” & _
“$graph.CopyFromScreen(0, 0, 0, 0, $bmp.Size); ” & _
“$bmp.Save(‘” & savePath & “‘, [System.Drawing.Imaging.ImageFormat]::Png); ” & _
“$bmp.Dispose(); $graph.Dispose();”

‘ 0 = ウィンドウ非表示で実行
shell.Run psCmd, 0, True
End Sub

Call Main

3. 堅牢な設計のための3つの鉄則

このコードをただコピペするだけでなく、以下のポイントを理解してほしい。

① 実行権限の分離

PowerShellを呼び出す際、スクリプトの実行権限とキャプチャ側の権限が一致している必要がある。タスクスケジューラ等で自動実行する場合、「最上位の特権で実行する」にチェックが入っていないと、バックグラウンドでの画面キャプチャが黒塗りで出力されることがある。

② リソースの解放(Dispose)

`.NET` の `Drawing` クラスは強力だが、メモリを消費する。スクリプトの中で多用する場合、`$bmp.Dispose()` を忘れるとメモリリークの原因となる。`shell.Run` でプロセスを分離しているのは、VBScript側のメモリ負荷を最小限に抑え、確実にリソースを解放させるためだ。

③ ファイルパスの正規化

`SpecialFolders(“Desktop”)` はOSの言語環境によって異なるが、VBScriptはそこを透過的に扱える。ただし、保存先フォルダの書き込み権限だけは事前に確認しておくこと。書き込み失敗による「エラー処理の中でのエラー」が起きると、デバッグは迷宮入りする。

結論:ログより語る「一枚の絵」

運用保守において、ログファイルに「オブジェクトが必要です」と書かれていても、その時の画面がどうなっていたかは分からない。「何が起きたか(ログ)」と「その時どう見えていたか(画像)」のセットこそが、障害対応を秒単位で解決に導く。

VBScriptを「古い言語」と切り捨てるのは簡単だ。しかし、この仕組みを実装することで、あなたの書いたスクリプトは、誰よりも雄弁に自らの死因を語るようになる。それが、真の自動化エンジニアの仕事だ。

さあ、コードを書き換えろ。あなたのシステムを、もっと賢くするために。

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