本記事はGeminiの出力をプロンプト工学で整理した業務ドラフト(未検証)です。
WMIとVBAで実現する!特定Windowsプロセスの死活監視と異常検知の自動化システム
【背景と目的】
基幹システムと連携する外部プロセスのハングアップや強制終了を検知できず、データ連携エラーや業務遅延が発生する課題を解決します。
【処理フロー図】
graph TD
A["監視開始"] --> B["WMIクエリ実行"]
B --> C{"対象プロセスは存在するか?"}
C -->|No: 異常検出| D["異常ログの記録 & ユーザー通知"]
C -->|Yes: 正常稼働| E{"メモリ使用量は閾値内か?"}
E -->|No: 異常検出| D
E -->|Yes: 正常稼働| F["一定時間スリープ"]
F --> B
※上記のフローに従い、バックグラウンドで指定したプロセスのステータスを一定間隔で巡回監視します。
【実装:VBAコード】
外部参照設定を不要にするため、WMIへの接続は後期バインディング(Late Binding)で行います。また、ミリ秒単位で待機処理を行うため、64bit環境に対応した Sleep APIを宣言しています。
Option Explicit
' 64bit/32bit両対応のSleep API宣言
#If VBA7 Then
Private Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
#Else
Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
#End If
' 監視制御用のフラグ
Private IsMonitoring As Boolean
''' <summary>
''' プロセス監視を開始するメインルーチン
''' </summary>
Public Sub StartProcessMonitoring()
Dim targetProcess As String
Dim memoryThresholdMB As Double
Dim intervalSeconds As Long
' --- 設定値 ---
targetProcess = "chrome.exe" ' 監視対象のプロセス名
memoryThresholdMB = 500# ' メモリ異常検知の閾値 (MB)
intervalSeconds = 5 ' 監視インターバル (秒)
' --------------
Dim wmiService As Object
Dim query As String
Dim processList As Object
Dim proc As Object
Dim processCount As Long
Dim memUsageMB As Double
Dim logRow As Long
' 画面更新と自動計算を停止して高速化・チラつき防止
With Application
.ScreenUpdating = False
.Calculation = xlCalculationManual
.EnableEvents = False
End With
On Error GoTo ErrorHandler
' WMIサービスへの接続
Set wmiService = GetObject("winmgmts:\\.\root\cimv2")
IsMonitoring = True
logRow = Sheet1.Cells(Sheet1.Rows.Count, "A").End(xlUp).Row + 1
' ログシートのヘッダー準備
If logRow = 2 And Sheet1.Range("A1").Value = "" Then
Sheet1.Range("A1:D1").Value = Array("日時", "プロセス名", "状態", "メモリ使用量(MB)")
End If
MsgBox "プロセス監視を開始します(Escキーまたはブレークで停止可能)", vbInformation, "監視開始"
Do While IsMonitoring
processCount = 0
memUsageMB = 0
' WMIクエリの作成と実行
query = "SELECT * FROM Win32_Process WHERE Name = '" & targetProcess & "'"
Set processList = wmiService.ExecQuery(query)
' プロセス情報の解析
For Each proc In processList
processCount = processCount + 1
' WorkingSetSize (バイト単位) を MB 単位に変換
memUsageMB = memUsageMB + (CDbl(proc.WorkingSetSize) / 1024 / 1024)
Next proc
' シートへログを出力(高速化のため配列に格納して一括出力)
Dim logData(1 To 1, 1 To 4) As Variant
logData(1, 1) = Now
logData(1, 2) = targetProcess
' 異常検知ロジック
If processCount = 0 Then
logData(1, 3) = "【異常】プロセス未起動"
logData(1, 4) = 0
Call WriteLog(logData, logRow)
Call AlertUser(targetProcess & " が起動していません!")
ElseIf memUsageMB > memoryThresholdMB Then
logData(1, 3) = "【警告】メモリ過大消費"
logData(1, 4) = Round(memUsageMB, 2)
Call WriteLog(logData, logRow)
Call AlertUser(targetProcess & " のメモリ使用量が閾値を超過しています: " & Round(memUsageMB, 2) & " MB")
Else
logData(1, 3) = "正常稼働中"
logData(1, 4) = Round(memUsageMB, 2)
Call WriteLog(logData, logRow)
End If
logRow = logRow + 1
' OSに制御を戻し、Excelのフリーズを防止
DoEvents
' 指定秒数待機 (Sleepはミリ秒指定)
Sleep intervalSeconds * 1000
Loop
CleanExit:
' 画面更新と自動計算を元に戻す
With Application
.ScreenUpdating = True
.Calculation = xlCalculationAutomatic
.EnableEvents = True
End With
Exit Sub
ErrorHandler:
MsgBox "エラーが発生しました: " & Err.Description, vbCritical, "エラー終了"
IsMonitoring = False
Resume CleanExit
End Sub
''' <summary>
''' 監視を安全に停止させるルーチン
''' </summary>
Public Sub StopProcessMonitoring()
IsMonitoring = False
MsgBox "監視停止リクエストを受け付けました。", vbInformation, "監視停止"
End Sub
''' <summary>
''' ログシートへの高速書き込み処理
''' </summary>
Private Sub WriteLog(ByRef data() As Variant, ByVal targetRow As Long)
Sheet1.Cells(targetRow, 1).Resize(1, 4).Value = data
End Sub
''' <summary>
''' 異常検知時のアラート通知処理
''' </summary>
Private Sub AlertUser(ByVal message As String)
' 簡易的にステータスバーとビープ音で通知
Application.StatusBar = "⚠️ " & message
Beep
' 必要に応じてここにメール送信やTeams通知ロジックを組み込み可能
End Sub
【技術解説】
WMI(Windows Management Instrumentation)の活用
GetObject("winmgmts:\\.\root\cimv2")を利用して、Windows OSのシステム管理情報へアクセスしています。Win32_Processクラスに対してSQLに似たクエリを投げることで、実行中のプロセス一覧やそのリソース消費状況(メモリ使用量等)をリアルタイムに取得できます。Win32 API
SleepによるCPU負荷軽減 VBA標準のApplication.Waitは1秒単位でしか待機できず、待機中もExcelがビジー状態になることがあります。Win32 APIのSleepを使うことで、ミリ秒単位の制御が可能になり、待機中のCPU使用率を極限まで下げることができます。配列書き出しによるシート操作の高速化 毎サイクルごとにセルへ個別書き込みを行うと動作が重くなるため、1行分のデータを一度配列(
logData)に格納し、Resizeメソッドを用いてセルへ一括転記しています。これにより描画負荷を最小限に抑えています。
【注意点と運用】
無限ループとExcelのフリーズ回避
DoEventsをループ内に配置しないと、Excelが完全に操作不能(ホワイトアウト)になります。必ずDoEventsを挟み、必要に応じてStopProcessMonitoringを実行できるように設計してください。管理者権限の壁 他ユーザーが実行しているプロセスや、システム特権で動作しているサービスプロセスを取得する場合、Excel(VBA)を「管理者として実行」しなければWMIクエリが一部の情報を取得できず、エラーまたは0件となる場合があります。
メモリリークの監視単位
WorkingSetSizeは物理メモリの使用量を示します。対象プロセスの構造(マルチプロセス型など)によっては、親プロセスだけでなく子プロセスのメモリも合算して監視対象にする必要があります。
【まとめ】
定期実行の間隔は業務に合わせる:頻繁な監視(1秒以下)はPC本体の負荷になるため、5秒〜30秒間隔での運用を推奨します。
記録シートのクリーンアップ:ログが数万行に達するとExcelの動作が重くなるため、一定行数を超えたら古いログを削除、または別ファイルへ退避するロジックを併用してください。
通知の多重化:本コードの
AlertUser内に、OutlookやAPI連携を用いたチャットツール(Teams/Slack)への自動投稿を組み込むことで、完全な無人監視体制が構築できます。

コメント