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
【技術解説】
WMI (Windows Management Instrumentation): 外部ライブラリを追加せずにOSの深層情報を取得できる強力なインターフェースです。
Win32_Processクラスを利用することで、プロセスID、メモリ消費量(WorkingSetSize)、実行パスなどを容易に取得できます。PtrSafe API:
Sleep関数を使用する際、64bit Office環境でも動作するようにPtrSafe属性を付与しています。これにより、VBA標準のWaitよりも高精度かつ軽量な待機が可能になります。リソース負荷の抑制:
DoEventsをループ内に配置し、Excelがフリーズすることを防ぎつつ、SleepでCPU使用率のスパイクを回避しています。
【注意点と運用】
実行権限: WMIのクエリによっては、管理者権限が必要な場合があります。一般ユーザー権限で取得できない情報がある際は、実行環境の権限を確認してください。
無限ループの停止: 本コードは監視を続けるために無限ループ構造にしています。停止ボタンを作成するか、
Ctrl + Breakキーでの強制終了を前提としています。監視間隔:
INTERVAL_SECを短くしすぎると、監視プログラム自体の負荷が高まります。実務上は5秒〜30秒程度が推奨されます。
【まとめ】
標準機能で完結: 参照設定を汚さず、WMIとAPIのみで高度な監視を実現。
異常検知の自動化: 目視確認を排除し、設定した閾値に基づいた即時通知が可能。
拡張性: 異常時に
objProcess.Terminateを実行することで、ゾンビプロセスの自動強制終了にも応用可能。

