<p><style_prompt: logic_business_standard=""></style_prompt:></p>
<p>本記事は<strong>Geminiの出力をプロンプト工学で整理した業務ドラフト(未検証)</strong>です。</p>
<h1 class="wp-block-heading">VBAとWMIを用いたWindowsプロセス監視と異常検知の自動化</h1>
<p>【背景と目的】
基幹システムのフリーズや特定アプリのメモリ異常消費を早期発見し、業務停止リスクを最小化します。手動監視を自動化し、ログ記録までを一貫して行います。(67文字)</p>
<p>【処理フロー図】</p>
<div class="wp-block-merpress-mermaidjs diagram-source-mermaid"><pre class="mermaid">
graph TD
A["監視メイン処理開始"] --> B["WMI接続確立"]
B --> C["Win32_Processから情報取得"]
C --> D{"特定プロセスの稼働確認"}
D -- 未起動 --> E["異常ログ記録/通知"]
D -- 稼働中 --> F["メモリ使用量等の閾値判定"]
F -- 閾値超過 --> G["強制終了または警告"]
F -- 正常 --> H["処理終了/待機"]
G --> H
</pre></div>
<p>【実装:VBAコード】</p>
<pre data-enlighter-language="generic">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
' プロセス監視マクロ
' 参照設定不要(実行時バインディング)
Sub WatchSpecificProcess()
Dim wmiService As Object
Dim processes As Object
Dim process As Object
Dim targetProcessName As String
Dim thresholdMemoryMB As Double
Dim isFound As Boolean
Dim logSheet As Worksheet
Dim lastRow As Long
' --- 設定項目 ---
targetProcessName = "Excel.exe" ' 監視対象プロセス名
thresholdMemoryMB = 500 ' メモリ閾値 (MB)
Set logSheet = ThisWorkbook.Sheets(1)
' 高速化設定
Application.ScreenUpdating = False
On Error GoTo ErrorHandler
' WMIサービスへの接続
Set wmiService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2")
' 実行中のプロセス一覧を取得
Set processes = wmiService.ExecQuery("SELECT * FROM Win32_Process WHERE Name = '" & targetProcessName & "'")
isFound = False
For Each process In processes
isFound = True
' WorkingSetSize (バイト) を MB に変換
Dim memUsageMB As Double
memUsageMB = Round(CDbl(process.WorkingSetSize) / 1024 / 1024, 2)
' 異常検知:メモリ使用量が閾値を超えている場合
If memUsageMB > thresholdMemoryMB Then
Call WriteLog(logSheet, targetProcessName, "警告:メモリ過多 (" & memUsageMB & " MB)")
' 必要に応じて process.Terminate で強制終了させることも可能
End If
Next process
' 異常検知:プロセスが見つからない場合
If Not isFound Then
Call WriteLog(logSheet, targetProcessName, "異常:プロセス未検出")
End If
CleanUp:
Application.ScreenUpdating = True
Set processes = Nothing
Set wmiService = Nothing
Exit Sub
ErrorHandler:
MsgBox "エラーが発生しました: " & Err.Description, vbCritical
Resume CleanUp
End Sub
' ログ記録用サブ関数
Private Sub WriteLog(ws As Worksheet, procName As String, message As String)
Dim nextRow As Long
nextRow = ws.Cells(ws.Rows.Count, 1).End(xlUp).Row + 1
' 配列を用いて一括書き込み(高速化)
Dim logData(1 To 1, 1 To 3) As Variant
logData(1, 1) = Now
logData(1, 2) = procName
logData(1, 3) = message
ws.Cells(nextRow, 1).Resize(1, 3).Value = logData
End Sub
</pre>
<p>【技術解説】</p>
<ol class="wp-block-list">
<li><p><strong>WMI (Windows Management Instrumentation)</strong>: 外部ライブラリの参照設定(DLL登録)なしで、OS内部のプロセス情報やハードウェアステータスにアクセスできる強力なインターフェースです。</p></li>
<li><p><strong>実行時バインディング</strong>: <code>CreateObject</code> や <code>GetObject</code> を使用することで、異なるバージョンのOffice間でも参照エラーを回避し、配布性を高めています。</p></li>
<li><p><strong>高速化技術</strong>: ログ出力の際、セル一つずつに書き込むのではなく、配列に格納してから <code>Resize</code> プロパティを用いて一括出力することで、I/O負荷を軽減しています。</p></li>
<li><p><strong>Win32 API</strong>: <code>PtrSafe</code> 宣言により、32bit/64bit双方のExcel環境で安全に動作するように設計されています。</p></li>
</ol>
<p>【注意点と運用】</p>
<ul class="wp-block-list">
<li><p><strong>管理者権限</strong>: WMIによる他ユーザーのプロセス情報の取得には、管理者権限が必要な場合があります。</p></li>
<li><p><strong>監視間隔</strong>: <code>Sleep</code> APIなどで無限ループさせる場合、CPU負荷を下げるために適切な待機時間(例:60,000ms = 1分)を設けてください。</p></li>
<li><p><strong>例外処理</strong>: ネットワーク経由でリモートPCを監視する場合、タイムアウト設定や接続エラー時の再試行ロジックの実装が推奨されます。</p></li>
</ul>
<p>【まとめ】</p>
<ul class="wp-block-list">
<li><p>WMIを活用することで、OSレベルの監視機能をVBAだけで簡単に実装可能。</p></li>
<li><p><code>PtrSafe</code> 対応の API 宣言により、モダンなビジネス環境(64bit)でも安定稼働。</p></li>
<li><p>ログの配列処理等、細かな高速化が大規模な監視データ蓄積時のストレスを軽減。</p></li>
</ul>
本記事はGeminiの出力をプロンプト工学で整理した業務ドラフト(未検証)です。
VBAとWMIを用いたWindowsプロセス監視と異常検知の自動化
【背景と目的】
基幹システムのフリーズや特定アプリのメモリ異常消費を早期発見し、業務停止リスクを最小化します。手動監視を自動化し、ログ記録までを一貫して行います。(67文字)
【処理フロー図】
graph TD
A["監視メイン処理開始"] --> B["WMI接続確立"]
B --> C["Win32_Processから情報取得"]
C --> D{"特定プロセスの稼働確認"}
D -- 未起動 --> E["異常ログ記録/通知"]
D -- 稼働中 --> F["メモリ使用量等の閾値判定"]
F -- 閾値超過 --> G["強制終了または警告"]
F -- 正常 --> H["処理終了/待機"]
G --> 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
' プロセス監視マクロ
' 参照設定不要(実行時バインディング)
Sub WatchSpecificProcess()
Dim wmiService As Object
Dim processes As Object
Dim process As Object
Dim targetProcessName As String
Dim thresholdMemoryMB As Double
Dim isFound As Boolean
Dim logSheet As Worksheet
Dim lastRow As Long
' --- 設定項目 ---
targetProcessName = "Excel.exe" ' 監視対象プロセス名
thresholdMemoryMB = 500 ' メモリ閾値 (MB)
Set logSheet = ThisWorkbook.Sheets(1)
' 高速化設定
Application.ScreenUpdating = False
On Error GoTo ErrorHandler
' WMIサービスへの接続
Set wmiService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2")
' 実行中のプロセス一覧を取得
Set processes = wmiService.ExecQuery("SELECT * FROM Win32_Process WHERE Name = '" & targetProcessName & "'")
isFound = False
For Each process In processes
isFound = True
' WorkingSetSize (バイト) を MB に変換
Dim memUsageMB As Double
memUsageMB = Round(CDbl(process.WorkingSetSize) / 1024 / 1024, 2)
' 異常検知:メモリ使用量が閾値を超えている場合
If memUsageMB > thresholdMemoryMB Then
Call WriteLog(logSheet, targetProcessName, "警告:メモリ過多 (" & memUsageMB & " MB)")
' 必要に応じて process.Terminate で強制終了させることも可能
End If
Next process
' 異常検知:プロセスが見つからない場合
If Not isFound Then
Call WriteLog(logSheet, targetProcessName, "異常:プロセス未検出")
End If
CleanUp:
Application.ScreenUpdating = True
Set processes = Nothing
Set wmiService = Nothing
Exit Sub
ErrorHandler:
MsgBox "エラーが発生しました: " & Err.Description, vbCritical
Resume CleanUp
End Sub
' ログ記録用サブ関数
Private Sub WriteLog(ws As Worksheet, procName As String, message As String)
Dim nextRow As Long
nextRow = ws.Cells(ws.Rows.Count, 1).End(xlUp).Row + 1
' 配列を用いて一括書き込み(高速化)
Dim logData(1 To 1, 1 To 3) As Variant
logData(1, 1) = Now
logData(1, 2) = procName
logData(1, 3) = message
ws.Cells(nextRow, 1).Resize(1, 3).Value = logData
End Sub
【技術解説】
WMI (Windows Management Instrumentation): 外部ライブラリの参照設定(DLL登録)なしで、OS内部のプロセス情報やハードウェアステータスにアクセスできる強力なインターフェースです。
実行時バインディング: CreateObject や GetObject を使用することで、異なるバージョンのOffice間でも参照エラーを回避し、配布性を高めています。
高速化技術: ログ出力の際、セル一つずつに書き込むのではなく、配列に格納してから Resize プロパティを用いて一括出力することで、I/O負荷を軽減しています。
Win32 API: PtrSafe 宣言により、32bit/64bit双方のExcel環境で安全に動作するように設計されています。
【注意点と運用】
管理者権限: WMIによる他ユーザーのプロセス情報の取得には、管理者権限が必要な場合があります。
監視間隔: Sleep APIなどで無限ループさせる場合、CPU負荷を下げるために適切な待機時間(例:60,000ms = 1分)を設けてください。
例外処理: ネットワーク経由でリモートPCを監視する場合、タイムアウト設定や接続エラー時の再試行ロジックの実装が推奨されます。
【まとめ】
WMIを活用することで、OSレベルの監視機能をVBAだけで簡単に実装可能。
PtrSafe 対応の API 宣言により、モダンなビジネス環境(64bit)でも安定稼働。
ログの配列処理等、細かな高速化が大規模な監視データ蓄積時のストレスを軽減。
コメント