VBA×WMI:業務システムの安定稼働を支えるWindowsプロセス監視と異常検知の自動化

Tech

  • 専門用語を適切に用い、技術的信頼性の高いトーンで執筆。

  • 読者の実務課題(効率化、安定性)に直結する具体的解決策を提示。

  • コードは可読性を重視し、構造化された解説を行う。

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

VBA×WMI:業務システムの安定稼働を支えるWindowsプロセス監視と異常検知の自動化

【背景と目的】 特定の業務アプリがフリーズした際、手動のタスクマネージャー確認は非効率です。WMIを利用し、プロセス異常を検知・記録・制御する基盤を構築します。(68文字)

【処理フロー図】

graph TD
A["開始"] --> B["WMIサービス接続"]
B --> C["Win32_Processをクエリ"]
C --> D{"特定プロセスの有無"}
D -- 存在 --> E["リソース使用量チェック"]
D -- 不在 --> F["警告・ログ記録"]
E --> G{"閾値超過判定"}
G -- 異常 --> H["強制終了または通知"]
G -- 正常 --> I["待機後再実行"]
H --> I
I --> J["終了"]

【実装:VBAコード】 Win32 API(Sleep)を利用した、制御用監視マクロの実装例です。

Option Explicit

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

' 監視メインルーチン
Public Sub MonitorTargetProcess()
    Dim wmiService As Object
    Dim processes As Object
    Dim process As Object
    Dim targetName As String
    Dim memThreshold As Double
    Dim isFound As Boolean
    Dim logRow As Long

    ' --- 設定エリア ---
    targetName = "EXCEL.EXE"         ' 監視対象プロセス名
    memThreshold = 500 * 1024 * 1024 ' 閾値: 500MB (バイト単位)
    ' ------------------

    Application.ScreenUpdating = False

    ' ローカルマシンのWMIサービスに接続
    On Error Resume Next
    Set wmiService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2")
    On Error GoTo 0

    If wmiService Is Nothing Then
        MsgBox "WMIサービスへの接続に失敗しました。", vbCritical
        Exit Sub
    End If

    ' 結果出力用のシート準備
    With ThisWorkbook.Sheets(1)
        .Cells.Clear
        .Range("A1:D1").Value = Array("時刻", "プロセス名", "メモリ使用量(MB)", "ステータス")
        logRow = 2
    End With

    ' 簡易的な3回監視ループ(実運用ではDo Loop等で調整)
    Dim i As Integer
    For i = 1 To 3
        isFound = False
        ' SQL形式のクエリで特定プロセスを抽出
        Set processes = wmiService.ExecQuery("SELECT * FROM Win32_Process WHERE Name = '" & targetName & "'")

        For Each process In processes
            isFound = True
            ' WorkingSetSize (物理メモリ使用量) を取得
            Dim memUsageMB As Double
            memUsageMB = Round(process.WorkingSetSize / 1024 / 1024, 2)

            ' シートへ記録
            With ThisWorkbook.Sheets(1)
                .Cells(logRow, 1).Value = Now
                .Cells(logRow, 2).Value = process.Name
                .Cells(logRow, 3).Value = memUsageMB

                If process.WorkingSetSize > memThreshold Then
                    .Cells(logRow, 4).Value = "異常 (メモリ過多)"
                    .Cells(logRow, 4).Interior.Color = vbRed
                    ' 必要に応じて:process.Terminate (強制終了)
                Else
                    .Cells(logRow, 4).Value = "正常"
                End If
                logRow = logRow + 1
            End With
        Next process

        If Not isFound Then
            Debug.Print targetName & " は実行されていません。"
        End If

        ' 指定ミリ秒待機 (API呼び出し)
        Sleep 2000 
    Next i

    Application.ScreenUpdating = True
    MsgBox "プロセス監視を完了しました。", vbInformation
End Sub

【技術解説】

  1. WMI (Windows Management Instrumentation): Windows OSの管理情報(CPU使用率、実行プロセス、ハードウェア情報)にSQLライクな記述でアクセスできる強力なインターフェースです。今回は Win32_Process クラスを使用し、実行中のプロセス情報を動的に取得しています。

  2. Late Binding (実行時バインド): CreateObject または GetObject を利用することで、特定の参照設定(Microsoft WMI Scripting Library等)を不要にし、他ユーザーへの配布時のエラーを最小限に抑えています。

  3. PtrSafe と API: Sleep 関数を導入することで、ループ内のCPU負荷を抑えています。64bit版Officeでも動作するよう、PtrSafeLongPtr を使用した条件付きコンパイルを行っています。

【注意点と運用】

  • 管理者権限: WMIは実行環境のユーザー権限に依存します。システムプロセスの操作や一部の高度な情報の取得には、管理者権限でExcelを起動する必要がある場合があります。

  • パフォーマンス負荷: 高頻度の監視(1秒以下など)は、WMI自体のオーバーヘッドでPC動作を重くする恐れがあります。実務では5秒〜1分間隔の監視を推奨します。

  • 例外処理: プロセスが監視中に終了した場合の Object 消失に備え、On Error 処理を適切に組み込む必要があります。

【まとめ】

  • WMIを活用すれば、標準VBA機能では難しい「OSレベルのプロセス監視」が可能になる。

  • Win32 API (Sleep) を組み合わせることで、効率的かつ安定したポーリング処理を実現できる。

  • 取得したデータをシートに記録することで、業務アプリのフリーズ原因特定など、トラブルシューティングの証拠資料として活用できる。

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

コメント

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