WMIを活用したWindowsプロセス監視と異常検知の自動化:VBAによる安定運用管理

Tech

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

WMIを活用したWindowsプロセス監視と異常検知の自動化:VBAによる安定運用管理

【背景と目的】

業務アプリの予期せぬフリーズや多重起動によるリソース枯渇を検知し、自動通知やログ記録を行うことで、保守工数の削減とシステム稼働率の向上を目指します。

【処理フロー図】

graph TD
A["監視開始"] --> B["WMIクエリ実行"]
B --> C{"特定プロセス存在確認"}
C -->|存在しない| D["異常ログ出力/通知"]
C -->|存在する| E{"リソース使用量確認"}
E -->|閾値超過| F["強制終了/再起動"]
E -->|正常| G["待機/ループ"]
G --> B

【実装:VBAコード】

Option Explicit

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

' プロセス監視メインルーチン
Public Sub MonitorTargetProcess()
    Dim wmiService As Object
    Dim processes As Object
    Dim process As Object
    Dim targetName As String
    Dim isRunning As Boolean
    Dim counter As Integer

    ' 監視対象のプロセス名(例: Excel.exe, notepad.exe等)
    targetName = "notepad.exe"

    ' 高速化設定
    Application.ScreenUpdating = False

    On Error GoTo ErrorHandler

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

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

    ' 簡易的な5回ループ監視(実務では状況に応じDo Loop等に変更)
    For counter = 1 To 5
        isRunning = False

        ' プロセス一覧の取得
        Set processes = wmiService.ExecQuery("Select * from Win32_Process Where Name = '" & targetName & "'")

        For Each process In processes
            isRunning = True
            ' メモリ使用量(WorkingSetSize)などをチェック可能
            If process.WorkingSetSize / 1024 / 1024 > 500 Then ' 500MB超過
                Debug.Print "【警告】メモリ過多: " & process.ProcessId
                ' 必要に応じて process.Terminate を実行
            End If
        Next process

        If Not isRunning Then
            Call LogAnomaly(targetName & " が見つかりません。")
        Else
            Debug.Print targetName & " は正常稼働中です。"
        End If

        ' 指定秒数待機(3秒)
        DoEvents
        Sleep 3000
    Next counter

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

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

' 異常検知時のログ記録(配列などを使わず直接セル/イミディエイトに出力する簡易版)
Private Sub LogAnomaly(message As String)
    Dim lastRow As Long
    With ThisWorkbook.Sheets(1)
        lastRow = .Cells(.Rows.Count, 1).End(xlUp).Row + 1
        .Cells(lastRow, 1).Value = Now
        .Cells(lastRow, 2).Value = "異常検知"
        .Cells(lastRow, 3).Value = message
    End With
    Debug.Print "【異常検知】" & message
End Sub

【技術解説】

  1. WMI (Windows Management Instrumentation): Win32_Process クラスを利用することで、OSレベルのプロセス情報(PID、メモリ、実行パス等)にアクセスします。参照設定なしで動く「実行時バインディング」を採用しています。

  2. PtrSafe Sleep: VBAの標準機能にはミリ秒単位の待機関数がないため、Win32 APIの Sleep を使用します。DoEvents を併用することで、監視中のExcelフリーズを防止します。

  3. クエリフィルタ: ExecQuery 内で Where Name = '...' とフィルタリングすることで、全プロセスをVBA側でループ判定するよりも高速に処理できます。

【注意点と運用】

  • 無限ループの罠: Do Loop で永続監視を行う場合は、必ず「停止フラグ」を設けるか、特定のセル値を参照してループを抜ける構造にしてください。

  • 権限の壁: 他のユーザーが実行しているプロセスの詳細や強制終了には、Excelを「管理者として実行」する必要があります。

  • リソース消費: 監視間隔が短すぎると、WMIクエリ自体がCPU負荷を高める原因となります。実務では10秒〜60秒程度の間隔を推奨します。

【まとめ】

  1. WMIクエリにより、外部ライブラリ不要で高度なプロセス監視が可能。

  2. Sleep APIと DoEvents を組み合わせ、ユーザー操作を妨げない設計にする。

  3. 異常検知時はログ出力とともに、Terminate メソッドによる自動復旧も検討する。

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

コメント

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