WMIを活用したWindowsプロセスの死活監視とリソース異常検知ツールの開発

Tech

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

WMIを活用したWindowsプロセスの死活監視とリソース異常検知ツールの開発

【背景と目的】 特定の基幹アプリのフリーズや多重起動によるPC低速化を自動検知。タスクマネージャーを監視する手間を省き、業務の安定稼働を支援します。(66文字)

【処理フロー図】

graph TD
A["監視開始"] --> B["WMIクエリ実行"]
B --> C{"対象プロセスは存在するか?"}
C -- No --> D["プロセス消失アラート"]
C -- Yes --> E["メモリ/CPU負荷を取得"]
E --> F{"閾値を超過しているか?"}
F -- Yes --> G["異常検知アラート/ログ出力"]
F -- No --> H["一定時間待機"]
H --> B

【実装:VBAコード】

Option Explicit

' --- Win32 API 宣言 (64bit/32bit両対応) ---
#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

' 監視設定定数
Private Const TARGET_PROCESS As String = "Excel.exe" ' 監視対象の実行ファイル名
Private Const MEMORY_THRESHOLD_MB As Long = 500      ' メモリ閾値 (MB)
Private Const INTERVAL_SEC As Long = 5               ' 監視間隔 (秒)

Sub StartProcessMonitoring()
    Dim objWMI As Object
    Dim colProcesses As Object
    Dim objProcess As Object
    Dim query As String
    Dim memUsage As Double
    Dim isFound As Boolean

    ' 高速化設定
    Application.ScreenUpdating = False

    On Error GoTo ErrorHandler

    ' WMIサービスへの接続 (Late Bindingにより参照設定不要)
    Set objWMI = GetObject("winmgmts:\\.\root\cimv2")

    Debug.Print "--- 監視開始: " & Now & " ---"

    ' 監視ループ (無限ループのため、停止時はCtrl+Pause/Break)
    Do
        isFound = False
        ' WMIクエリの作成
        query = "SELECT * FROM Win32_Process WHERE Name = '" & TARGET_PROCESS & "'"
        Set colProcesses = objWMI.ExecQuery(query)

        For Each objProcess In colProcesses
            isFound = True
            ' WorkingSetSize (バイト単位) を MB に変換
            memUsage = Round(objProcess.WorkingSetSize / 1024 / 1024, 2)

            ' 異常検知ロジック
            If memUsage > MEMORY_THRESHOLD_MB Then
                Call AlertAnomaly(objProcess.ProcessId, memUsage)
            Else
                Debug.Print "[" & Now & "] 正常稼働中: PID=" & objProcess.ProcessId & " Memory=" & memUsage & "MB"
            End If
        Next objProcess

        If Not isFound Then
            Debug.Print "[" & Now & "] 【警告】プロセスが見つかりません: " & TARGET_PROCESS
        End If

        ' システムへの負荷軽減のため待機
        DoEvents
        Sleep INTERVAL_SEC * 1000
    Loop

ExitProcedure:
    Application.ScreenUpdating = True
    Exit Sub

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

' 異常検知時の通知処理
Private Sub AlertAnomaly(ByVal pid As Long, ByVal usage As Double)
    Dim msg As String
    msg = "【リソース異常検知】" & vbCrLf & _
          "対象: " & TARGET_PROCESS & " (PID: " & pid & ")" & vbCrLf & _
          "使用メモリ: " & usage & " MB" & vbCrLf & _
          "閾値 (" & MEMORY_THRESHOLD_MB & " MB) を超過しました。"

    ' ログ出力(イミディエイトウィンドウ)
    Debug.Print "!!! ALERT !!! " & msg

    ' 必要に応じてメール送信やメッセージボックス表示をここに追加
End Sub

【技術解説】

  1. WMI (Windows Management Instrumentation): 外部ライブラリを追加せずにOSの深層情報を取得できる強力なインターフェースです。Win32_Process クラスを利用することで、プロセスID、メモリ消費量(WorkingSetSize)、実行パスなどを容易に取得できます。

  2. PtrSafe API: Sleep 関数を使用する際、64bit Office環境でも動作するように PtrSafe 属性を付与しています。これにより、VBA標準の Wait よりも高精度かつ軽量な待機が可能になります。

  3. リソース負荷の抑制: DoEvents をループ内に配置し、Excelがフリーズすることを防ぎつつ、Sleep でCPU使用率のスパイクを回避しています。

【注意点と運用】

  • 実行権限: WMIのクエリによっては、管理者権限が必要な場合があります。一般ユーザー権限で取得できない情報がある際は、実行環境の権限を確認してください。

  • 無限ループの停止: 本コードは監視を続けるために無限ループ構造にしています。停止ボタンを作成するか、Ctrl + Break キーでの強制終了を前提としています。

  • 監視間隔: INTERVAL_SEC を短くしすぎると、監視プログラム自体の負荷が高まります。実務上は5秒〜30秒程度が推奨されます。

【まとめ】

  1. 標準機能で完結: 参照設定を汚さず、WMIとAPIのみで高度な監視を実現。

  2. 異常検知の自動化: 目視確認を排除し、設定した閾値に基づいた即時通知が可能。

  3. 拡張性: 異常時に objProcess.Terminate を実行することで、ゾンビプロセスの自動強制終了にも応用可能。

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

コメント

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