VBA×WMI:業務アプリのプロセス監視とパフォーマンス異常検知の自動化

Tech

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

VBA×WMI:業務アプリのプロセス監視とパフォーマンス異常検知の自動化

【背景と目的】

複数の業務システムを並行稼働させる環境で、特定のアプリがフリーズしたり、メモリを異常消費してPC全体が重くなる課題を、VBAからWMIを叩いて自動解決します。

実務では「バッチ処理中のバックグラウンド落ち」や「メモリリークによるシステム遅延」が頻発しますが、これらをいちいちタスクマネージャーで確認するのは非効率です。本ツールは、VBAのみでプロセスの死活監視とリソース使用状況の可視化を実現します。

【処理フロー図】

graph TD
A["監視開始"] --> B["WMIサービスへ接続"]
B --> C["Win32_Processクラスのクエリ実行"]
C --> D{"対象プロセスは存在するか?"}
D -- No --> E["プロセス停止アラート"]
D -- Yes --> F["メモリ/CPU使用率の算出"]
F --> G{"閾値を超過しているか?"}
G -- Yes --> H["異常検知アラート/ログ出力"]
G -- No --> I["正常終了"]

【実装:VBAコード】

標準モジュールに以下のコードを貼り付けてください。Win32 APIによる待機処理を含み、64bit/32bit両環境に対応しています。

Option Explicit

' 64bit環境を考慮した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>
''' 指定したプロセスのリソース状況を監視し、異常を検知する
''' </summary>
Public Sub MonitorProcessAnomaly()
    Dim wmiService As Object
    Dim processes As Object
    Dim process As Object
    Dim targetName As String
    Dim memThresholdMB As Double
    Dim isFound As Boolean
    Dim msg As String

    ' --- 設定値 ---
    targetName = "EXCEL.EXE" ' 監視対象のプロセス名
    memThresholdMB = 500      ' 異常とみなすメモリ閾値 (MB)
    ' --------------

    On Error GoTo ErrorHandler

    ' 高速化処理
    Application.ScreenUpdating = False

    ' WMIサービスへの接続(遅延バインディング)
    Set wmiService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2")

    ' プロセス情報の取得
    Set processes = wmiService.ExecQuery("SELECT * FROM Win32_Process WHERE Name = '" & targetName & "'")

    isFound = False
    For Each process In processes
        isFound = True

        ' ワーキングセットサイズ(物理メモリ使用量)をMB換算
        Dim memUsage As Double
        memUsage = Round(process.WorkingSetSize / 1024 / 1024, 2)

        ' ログ用メッセージ構築
        msg = "Process: " & process.Name & " (ID: " & process.ProcessId & ")" & vbCrLf & _
              "Memory Usage: " & memUsage & " MB"

        ' 異常検知ロジック
        If memUsage > memThresholdMB Then
            MsgBox "【警告】プロセス異常検知" & vbCrLf & vbCrLf & _
                   msg & vbCrLf & "閾値(" & memThresholdMB & "MB)を超過しています。", vbCritical
        Else
            Debug.Print "正常稼働中: " & msg
        End If
    Next process

    If Not isFound Then
        MsgBox "対象プロセス '" & targetName & "' が起動していません。", vbExclamation
    End If

CleanUp:
    Set processes = Nothing
    Set wmiService = Nothing
    Application.ScreenUpdating = True
    Exit Sub

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

【技術解説】

  1. WMI (Windows Management Instrumentation) の活用 Win32_Process クラスを使用することで、タスクマネージャーに表示される情報をプログラムから取得できます。WorkingSetSize プロパティはプロセスが物理メモリをどれだけ占有しているかを示します。

  2. 遅延バインディング (Late Binding) CreateObjectGetObject を使用することで、参照設定(Microsoft WMI Scripting V1.x Library)を不要にしています。これにより、他ユーザーのPCでも環境設定なしで動作します。

  3. PtrSafe 宣言 #If VBA7 定数を使用し、Excel 2010以降の64bit版と旧来の32bit版の両方で動作する互換性を担保しています。

  4. リソース負荷の軽減 ExecQuery で最初から WHERE 句を使いフィルタリングすることで、全プロセスをループ処理する無駄を省き、実行速度を向上させています。

【注意点と運用】

  • WMIの権限: 管理者権限が必要なプロセス情報は取得できない場合があります。標準的なユーザー権限で動作するアプリであれば問題ありません。

  • サンプリング間隔: ループ内で Sleep を入れずに監視し続けると、VBA自体がCPU負荷を上げてしまいます。タイマー処理や、特定の処理の前後でスポット的に呼び出す運用が推奨されます。

  • メモリ単位: WMIから返される WorkingSetSize は「バイト単位」です。人間が読みやすいよう 1024^2 で割って MB 単位に変換する必要があります。

【まとめ】

  1. 外部参照なしで完結: WMIを利用すれば、追加ライブラリなしで高度なシステム監視が可能。

  2. 異常の早期発見: メモリ使用量や起動状態を自動監視し、サイレント・フリーズによる業務停止を防止。

  3. ポータビリティ: PtrSafe 対応により、古い端末から最新の64bit環境まで使い回せるツールとして運用可能。

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

コメント

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