VBA×WMIによるWindowsプロセス監視:業務停止を防ぐ異常検知の自動化

Tech

  • 専門用語を適切に用い、実務に即した具体的で無駄のない解説。

  • コード解説は構造的かつ論理的に行い、保守性を重視。

  • Win32 API使用時は必ずPtrSafe宣言を含め、64bit/32bit両対応を保証。

  • ユーザーの「今すぐ使いたい」に応えつつ、技術的背景も補完。

本記事はGeminiの出力をプロンプト工学で整理した業務ドラフト(未検証)です。

VBA×WMIによるWindowsプロセス監視:業務停止を防ぐ異常検知の自動化

【背景と目的】

業務アプリのハングアップや特定プロセスの異常なメモリ消費を、VBAでリアルタイムに監視。システム遅延による業務停滞や予期せぬエラーを早期に検知・記録します。

【処理フロー図】

graph TD
A["開始"] --> B["WMIサービスへ接続"]
B --> C["Win32_Processから情報を取得"]
C --> D{"閾値チェック"}
D -->|異常あり| E["Excelシートへログ出力"]
D -->|正常| F["次回の実行を待機"]
E --> F
F --> G["終了判断"]
G -->|継続| B
G -->|停止| H["終了"]

【実装:VBAコード】

Option Explicit

' 64bit/32bit両対応のSleep宣言
#If VBA7 Then

    Private Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As LongPtr)
#Else

    Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
#End If

''' <summary>
''' WMIを利用したプロセス監視および異常検知メインルーチン
''' </summary>
Public Sub MonitorProcesses()
    Dim objWMIService As Object
    Dim colProcesses As Object
    Dim objProcess As Object
    Dim ws As Worksheet
    Dim lastRow As Long
    Dim thresholdMemory As Double

    ' --- 設定値 ---
    thresholdMemory = 500 * 1024 * 1024 ' 閾値:500MB (バイト単位)
    Set ws = ThisWorkbook.Sheets(1)

    ' 高速化設定
    On Error GoTo ErrorHandler
    Application.ScreenUpdating = False
    Application.Calculation = xlCalculationManual

    ' WMIサービスへの接続(レイトバインドで参照設定不要)
    Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2")

    ' 見出しの設定
    ws.Cells.Clear
    ws.Range("A1:E1").Value = Array("取得日時", "プロセス名", "PID", "メモリ使用量(MB)", "判定")

    Do
        ' プロセス一覧の取得
        Set colProcesses = objWMIService.ExecQuery("Select * from Win32_Process")

        For Each objProcess In colProcesses
            ' メモリ使用量(WorkingSetSize)のチェック
            Dim memSizeMB As Double
            memSizeMB = Round(CDbl(objProcess.WorkingSetSize) / 1024 / 1024, 2)

            ' 異常(閾値超過)または特定の重要プロセスを監視する場合の条件分岐
            If memSizeMB > (thresholdMemory / 1024 / 1024) Then
                lastRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row + 1

                ' 配列を介さず直接書き込むが、頻度を抑える設計
                ws.Cells(lastRow, 1).Value = Now
                ws.Cells(lastRow, 2).Value = objProcess.Name
                ws.Cells(lastRow, 3).Value = objProcess.ProcessId
                ws.Cells(lastRow, 4).Value = memSizeMB
                ws.Cells(lastRow, 5).Value = "MEMORY ALERT"
                ws.Cells(lastRow, 5).Font.Color = vbRed
            End If
        Next

        ' イベント待機(CPU負荷軽減のため5秒スリープ)
        DoEvents
        Sleep 5000 

        ' 連続稼働させる場合はループ、デモ用に1回で抜ける場合は以下をコメントアウト
        ' Exit Do 
    Loop

CleanUp:
    Application.ScreenUpdating = True
    Application.Calculation = xlCalculationAutomatic
    Exit Sub

ErrorHandler:
    MsgBox "エラーが発生しました: " & Err.Description, vbCritical
    Resume CleanUp
End Sub

【技術解説】

  1. WMI (Windows Management Instrumentation): Windowsの管理情報を取得するための標準インターフェースです。Win32_Process クラスを使用することで、タスクマネージャーに表示されるプロセスの詳細情報をSQLライクなクエリで取得できます。

  2. PtrSafeと条件付きコンパイル: Declare PtrSafe を用いることで、Excel 64bit版でもエラーなく動作します。LongPtr 型の採用により、メモリアドレスの扱いも安全に行えます。

  3. パフォーマンス対策: 監視ループ内では DoEvents を呼び出し、ExcelのUIがフリーズするのを防いでいます。また、Sleep APIを利用してポーリング間隔を調整し、監視プログラム自体のCPU負荷を最小限に抑えています。

【注意点と運用】

  • 管理者権限: 一部のシステムプロセス情報は、管理者権限でExcelを実行していないと取得できない場合があります。

  • 無限ループの制御: 上記コードは Do...Loop を使用しています。停止ボタン(Ctrl+Break)や、特定のセル値を見て終了するフラグ処理の実装を推奨します。

  • ログの肥大化: 異常検知の頻度が高い場合、Excelの行数上限に達する恐れがあります。定期的なシートクリアや、CSVへの外部出力への切り替えも検討してください。

【まとめ】

  • WMIを活用することで、外部ツールに頼らずWindowsの内部状態を監視可能。

  • PtrSafe宣言による環境互換性の確保が、組織内配布の鍵。

  • Sleep関数の挿入により、監視処理自体が業務の妨げにならないよう設計する。

ライセンス:本記事のテキスト/コードは特記なき限り CC BY 4.0 です。引用の際は出典URL(本ページ)を明記してください。
利用ポリシー もご参照ください。

コメント

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