<p><!-- style_prompt_check: active -->
本記事は<strong>Geminiの出力をプロンプト工学で整理した業務ドラフト(未検証)</strong>です。</p>
<h1 class="wp-block-heading">WMIを活用したWindowsプロセス監視と異常検知の自動化:VBAによる安定運用管理</h1>
<h3 class="wp-block-heading">【背景と目的】</h3>
<p>業務アプリの予期せぬフリーズや多重起動によるリソース枯渇を検知し、自動通知やログ記録を行うことで、保守工数の削減とシステム稼働率の向上を目指します。</p>
<h3 class="wp-block-heading">【処理フロー図】</h3>
<div class="wp-block-merpress-mermaidjs diagram-source-mermaid"><pre class="mermaid">
graph TD
A["監視開始"] --> B["WMIクエリ実行"]
B --> C{"特定プロセス存在確認"}
C -->|存在しない| D["異常ログ出力/通知"]
C -->|存在する| E{"リソース使用量確認"}
E -->|閾値超過| F["強制終了/再起動"]
E -->|正常| G["待機/ループ"]
G --> B
</pre></div>
<h3 class="wp-block-heading">【実装:VBAコード】</h3>
<pre data-enlighter-language="generic">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
</pre>
<h3 class="wp-block-heading">【技術解説】</h3>
<ol class="wp-block-list">
<li><p><strong>WMI (Windows Management Instrumentation)</strong>: <code>Win32_Process</code> クラスを利用することで、OSレベルのプロセス情報(PID、メモリ、実行パス等)にアクセスします。参照設定なしで動く「実行時バインディング」を採用しています。</p></li>
<li><p><strong>PtrSafe Sleep</strong>: VBAの標準機能にはミリ秒単位の待機関数がないため、Win32 APIの <code>Sleep</code> を使用します。<code>DoEvents</code> を併用することで、監視中のExcelフリーズを防止します。</p></li>
<li><p><strong>クエリフィルタ</strong>: <code>ExecQuery</code> 内で <code>Where Name = '...'</code> とフィルタリングすることで、全プロセスをVBA側でループ判定するよりも高速に処理できます。</p></li>
</ol>
<h3 class="wp-block-heading">【注意点と運用】</h3>
<ul class="wp-block-list">
<li><p><strong>無限ループの罠</strong>: <code>Do Loop</code> で永続監視を行う場合は、必ず「停止フラグ」を設けるか、特定のセル値を参照してループを抜ける構造にしてください。</p></li>
<li><p><strong>権限の壁</strong>: 他のユーザーが実行しているプロセスの詳細や強制終了には、Excelを「管理者として実行」する必要があります。</p></li>
<li><p><strong>リソース消費</strong>: 監視間隔が短すぎると、WMIクエリ自体がCPU負荷を高める原因となります。実務では10秒〜60秒程度の間隔を推奨します。</p></li>
</ul>
<h3 class="wp-block-heading">【まとめ】</h3>
<ol class="wp-block-list">
<li><p>WMIクエリにより、外部ライブラリ不要で高度なプロセス監視が可能。</p></li>
<li><p><code>Sleep</code> APIと <code>DoEvents</code> を組み合わせ、ユーザー操作を妨げない設計にする。</p></li>
<li><p>異常検知時はログ出力とともに、<code>Terminate</code> メソッドによる自動復旧も検討する。</p></li>
</ol>
本記事は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
【技術解説】
WMI (Windows Management Instrumentation): Win32_Process クラスを利用することで、OSレベルのプロセス情報(PID、メモリ、実行パス等)にアクセスします。参照設定なしで動く「実行時バインディング」を採用しています。
PtrSafe Sleep: VBAの標準機能にはミリ秒単位の待機関数がないため、Win32 APIの Sleep を使用します。DoEvents を併用することで、監視中のExcelフリーズを防止します。
クエリフィルタ: ExecQuery 内で Where Name = '...' とフィルタリングすることで、全プロセスをVBA側でループ判定するよりも高速に処理できます。
【注意点と運用】
無限ループの罠: Do Loop で永続監視を行う場合は、必ず「停止フラグ」を設けるか、特定のセル値を参照してループを抜ける構造にしてください。
権限の壁: 他のユーザーが実行しているプロセスの詳細や強制終了には、Excelを「管理者として実行」する必要があります。
リソース消費: 監視間隔が短すぎると、WMIクエリ自体がCPU負荷を高める原因となります。実務では10秒〜60秒程度の間隔を推奨します。
【まとめ】
WMIクエリにより、外部ライブラリ不要で高度なプロセス監視が可能。
Sleep APIと DoEvents を組み合わせ、ユーザー操作を妨げない設計にする。
異常検知時はログ出力とともに、Terminate メソッドによる自動復旧も検討する。
ライセンス:本記事のテキスト/コードは特記なき限り
CC BY 4.0 です。引用の際は出典URL(本ページ)を明記してください。
利用ポリシー もご参照ください。
コメント