VBAで実現するWMIプロセス監視:特定アプリの暴走とリソース枯渇の自動検知

VBA・Officeカテゴリを表すパンダのイラスト VBA・Office

VBAで実現するWMIプロセス監視:特定アプリの暴走とリソース枯渇の自動検知

【背景と目的】

外部連携ソフトのフリーズや、VBA実行中のメモリリークによるPC停止を未然に防ぐため、WMI(Windows Management Instrumentation)を用いてOSのプロセス負荷を監視し、異常時に警告を発するVBAマクロの構築方法を解説します。

【処理フロー図】

graph TD
A["開始"] --> B["WMIサービスへ接続"]
B --> C["特定プロセスのリソース取得"]
C --> D{"閾値を超過しているか?"}
D -- Yes --> E["異常検知ログの書き出し"]
D -- No --> F["正常終了/待機"]
E --> G["指定プロセスの強制終了検討"]
G --> H["終了"]
F --> H

【実装:VBAコード】

Option Explicit

' --- Win32 API 宣言 (64bit環境対応) ---
#If Win64 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

'' 
'' 指定したプロセスのCPU使用率とメモリ使用量を監視し、Excelシートへ記録する
'' 
Public Sub MonitorProcessPerformance()
    Dim strComputer As String: strComputer = "."
    Dim strProcessName As String: strProcessName = "Excel.exe" ' 監視対象プロセス名
    Dim objWMIService As Object
    Dim colProcesses As Object
    Dim objProcess As Object
    Dim results() As Variant
    Dim i As Long: i = 1

    ' 描画停止による高速化
    Application.ScreenUpdating = False

    On Error GoTo ErrorHandler

    ' WMIサービスへの接続
    Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")

    ' プロセス情報の取得 (Win32_PerfFormattedData_PerfProc_Process を使用して計算済み負荷を取得)
    Set colProcesses = objWMIService.ExecQuery( _
        "SELECT * FROM Win32_PerfFormattedData_PerfProc_Process WHERE Name = '" & Left(strProcessName, InStrRev(strProcessName, ".") - 1) & "'")

    ' 結果格納用の配列準備 (行: 項目, 列: データ)
    ReDim results(1 To 2, 1 To 4)
    results(1, 1) = "プロセス名"
    results(1, 2) = "CPU使用率(%)"
    results(1, 3) = "メモリ使用量(MB)"
    results(1, 4) = "取得時刻"

    For Each objProcess In colProcesses
        i = i + 1
        ReDim Preserve results(1 To 2, 1 To i)
        results(2, 1) = objProcess.Name
        results(2, 2) = objProcess.PercentProcessorTime
        results(2, 3) = Round(objProcess.WorkingSetPrivate / 1024 / 1024, 2) ' Byte -> MB
        results(2, 4) = Now

        ' 異常検知ロジック (例: CPU 90%以上 または メモリ 1GB以上)
        If objProcess.PercentProcessorTime > 90 Or (objProcess.WorkingSetPrivate / 1024 / 1024) > 1024 Then
            MsgBox "警告: " & objProcess.Name & " の負荷が閾値を超えました。", vbCritical
        End If
    Next

    ' シートへの一括書き出し (セルへの個別アクセスを避けて高速化)
    If i > 1 Then
        Range("A1").Resize(UBound(results, 2), UBound(results, 1)).Value = Application.Transpose(results)
    Else
        Debug.Print "対象プロセスが見つかりませんでした。"
    End If

CleanUp:
    Set colProcesses = Nothing
    Set objWMIService = Nothing
    Application.ScreenUpdating = True
    Exit Sub

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

【技術解説】

  1. WMI (Windows Management Instrumentation): Windowsのシステム情報を取得するための標準インターフェースです。今回は Win32_PerfFormattedData_PerfProc_Process クラスを利用し、OS側で計算済みのCPU使用率を直接取得しています。

  2. PtrSafe 宣言: Sleep などの API を使用する場合、64bit Office環境でのクラッシュを防ぐために必須の記述です。

  3. 配列による一括出力: セルに対してループ内で書き込みを行うと動作が重くなるため、一度配列に格納してから Resize メソッドで一括出力しています。

【注意点と運用】

  • WMIの負荷: WMIクエリを頻繁(1秒未満の間隔など)に実行すると、監視自体がCPUリソースを消費します。監視間隔は5秒〜1分程度を推奨します。

  • 権限の問題: 他ユーザーのプロセス情報を取得する場合、Excelを「管理者として実行」する必要がある場合があります。

  • プロセス名の指定: Win32_PerfFormattedData クラスでは、拡張子(.exe)を除いた名前を指定する必要がある点に注意してください。

【まとめ】

  • WMIを活用することで、VBAからOSレベルのリソース監視が容易になります。

  • 配列処理とAPIの適切な宣言(PtrSafe)により、高速かつ安定したツールが構築可能です。

  • 異常検知時はメッセージボックスだけでなく、ログファイルへの追記や自動メール送信へ拡張するのが実用的です。

この記事の更新履歴

この記事は、生成AIを活用した自動レビュー・更新フローにより内容を見直し、必要な修正を反映しています。

2026年9月20日

  • 削除記事冒頭の内部プロンプト指示および未検証ドラフトの注意書きを削除しました。
  • 変更WMIプロセス監視VBAコードの実装を整理し、実用的なエラーハンドリングと解説を補強しました。

文書情報

記事タイトル
VBAで実現するWMIプロセス監視:特定アプリの暴走とリソース枯渇の自動検知
作成日
更新日
Source URL
https://papanda925.com/?p=6510

ライセンス: 本記事のうち、当サイトが権利を有する本文・自作図表は、特記なき限り CC BY 4.0 で利用できます。生成AIを活用して作成・編集した内容を含みます。コードについて、別途ライセンス表示またはリンク先GitHubリポジトリのライセンスがある場合は、その条件を優先します。引用・第三者資料・画像・商標等は本ライセンスの対象外です。 利用ポリシー

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