ソース掲示板




すべてから検索

キーワード   条件 表示 現行ログ 過去ログ トピックス 名前 本文
WMI によるプロセスの監視 ( No.0 )
日時: 2013/05/01 23:32
名前: lightbox



http://lightbox.on.coocan.jp/download/wsh/PROCESS_CHECK_NEXT.vbs

VBSCript(同期メソッド)の場合
Set objWMIService = GetObject("winmgmts:" _ 
	& "{impersonationLevel=impersonate}!\\.\root\cimv2") 
Set objMonitor = objWMIService. _
	ExecNotificationQuery("select * from __instancecreationevent " _
	& " within 1 where TargetInstance isa 'Win32_Process'")

Do
	' 次に新しいプロセスが開始されるまで、待ちます
	Set objProcess = objMonitor.NextEvent

	' 終了する手段として winver.exe を実行します
	if Ucase( objProcess.TargetInstance.Name ) = "WINVER.EXE" then
		Wscript.Echo "プロセスの監視を終了します"
		Exit Do
	end if

	Wscript.Echo objProcess.TargetInstance.Name
	Wscript.Echo objProcess.TargetInstance.ExecutablePath
Loop 
WQL:SQL for WMI VBSCript(非同期メソッド)の場合
Set objWMIService = GetObject("winmgmts:" _ 
	& "{impersonationLevel=impersonate}!\\.\root\cimv2") 
Set objSink = WScript.CreateObject( _
	"WbemScripting.SWbemSink","SINK_")

objWMIservice.ExecNotificationQueryAsync objSink, _
	"SELECT * FROM __InstanceCreationEvent WITHIN 1 WHERE " _
	& "TargetInstance ISA 'Win32_Process'"

' イベントを待つ為にプログラムを終わらさないようにする
MsgBox("待機しています...")

Sub SINK_OnObjectReady(objObject, objAsyncContext)

	' 名前
	WScript.Echo objObject.TargetInstance.Name
	' 実行パス
	WScript.Echo objObject.TargetInstance.ExecutablePath

	' プロパティの列挙
	For Each obj IN objObject.Properties_
		strProp = obj.Name & vbCrLf
		Set objTarget = obj.Value
		For Each obj2 IN objTarget.Properties_
			strProp = strProp & vbTab & obj2.Name & vbCrLf
		Next
	Next

	WScript.Echo strProp

End Sub
VB.NET(同期メソッド)の場合
Imports System.Threading
Imports System.Management

Public Class Form1

	' スレッドの終了をコントロールするフラグ
	Private stopFlg As Integer = 0

	' **************************************************
	' 初期処理
	' **************************************************
	Private Sub Form1_Load(ByVal sender As System.Object, _
	ByVal e As System.EventArgs) Handles MyBase.Load

		Me.LboxGrid1.UseParentFitForm = Me

		Me.LboxGrid1.AddColumn("TIME", "時刻")
		Me.LboxGrid1.AddColumn("NAME", "名称")
		Me.LboxGrid1.AddColumn("PATH", "ファイル")

		' スレッド処理するメソッドを作成
		Dim ThreadProc As New Thread(AddressOf ThreadEntry)
		' スレッド開始
		ThreadProc.Start()

	End Sub

	' **************************************************
	' スレッドの入り口
	' **************************************************
	Private Sub ThreadEntry()

		Dim Bridge As New ProcBridge(AddressOf SetData)

		Dim Query As New EventQuery( _
		  "SELECT * FROM" & _
		  " __InstanceCreationEvent WITHIN 1 " & _
		  "WHERE TargetInstance isa ""Win32_Process""")

		' 監視用オブジェクト
		Dim Monitor As New ManagementEventWatcher(Query)
		' 時分秒[ WaitForNextEvent 内での監視時間 ]
		Monitor.Options.Timeout = New TimeSpan(0, 0, 1)

		Dim targetProcess As ManagementBaseObject = Nothing

		' 参照する為に、常に 0 で比較後等しければ 0 をセット。1 の時にループ終了
		Do While Interlocked.CompareExchange(stopFlg, 0, 0) = 0

			Try
				' タイムアウトでは、エラーで Try を抜ける
				targetProcess = Monitor.WaitForNextEvent()
				Dim str1 = _
				CType(targetProcess("TargetInstance"), _
				 ManagementBaseObject)("Name")
				Dim str2 = _
				CType(targetProcess("TargetInstance"), _
				 ManagementBaseObject)("ExecutablePath")

				Me.Invoke(Bridge, New Object() {1, str1, str2})
			Catch ex As Exception
			End Try

		Loop

		Monitor.Stop()
		Monitor.Dispose()
		' 実際の終了を通知する
		Me.Invoke(Bridge, New Object() {-1, "終了処理中です...", ""})

	End Sub

	' **************************************************
	' 橋渡し用デリゲート
	' **************************************************
	Delegate Sub ProcBridge(ByVal type As Integer, _
	ByVal str1 As String, ByVal str2 As String)

	' **************************************************
	' 橋渡し用実体
	' **************************************************
	Private Sub SetData(ByVal type As Integer, _
	ByVal Name As String, ByVal Path As String)

		If type = 1 Then
			Me.LboxGrid1.AddRow()
			Me.LboxGrid1.SetColumnText("TIME", Now.ToString())
			Me.LboxGrid1.SetColumnText("NAME", Name)
			Me.LboxGrid1.SetColumnText("PATH", Path)
		End If
		If type = -1 Then
			Me.LboxGrid1.AddRow()
			Me.LboxGrid1.SetColumnText("TIME", Now.ToString())
			Me.LboxGrid1.SetColumnText("NAME", Name)
			Me.LboxGrid1.Update()
			Thread.Sleep(1000)
			' 終了通知うけて、実際終了する
			' [ FormClosing と FormClosed が発生する ]
			Application.Exit()
		End If

	End Sub


	' **************************************************
	' フォームが閉じる前[ e.Cancel = True でキャンセル可能 ]
	' **************************************************
	Private Sub Form1_FormClosing(ByVal sender As System.Object, _
	ByVal e As System.Windows.Forms.FormClosingEventArgs) _
	Handles MyBase.FormClosing

		' スレッド実行中ならば、スレッドが終了する状態にして、終了処理をキャンセル
		If Interlocked.CompareExchange(stopFlg, 0, 0) = 0 Then
			Interlocked.Exchange(stopFlg, 1)
			e.Cancel = True
		End If

	End Sub

End Class
TargetInstance を持つ __InstanceCreationEvent Name と ExecutablePath を持つ Win32_Process VB.NET(非同期メソッド)の場合
Imports System.Threading
Imports System.Management

Public Class 非同期

	' 監視用オブジェクト
	Private Monitor As ManagementEventWatcher = Nothing

	' **************************************************
	' 初期処理
	' **************************************************
	Private Sub Form1_Load(ByVal sender As System.Object, _
	 ByVal e As System.EventArgs) Handles MyBase.Load

		Me.LboxGrid1.UseParentFitForm = Me

		Me.LboxGrid1.AddColumn("TIME", "時刻")
		Me.LboxGrid1.AddColumn("NAME", "名称")
		Me.LboxGrid1.AddColumn("PATH", "ファイル")


		Dim Query As New EventQuery( _
		  "SELECT * FROM" & _
		  " __InstanceCreationEvent WITHIN 1 " & _
		  "WHERE TargetInstance isa ""Win32_Process""")

		' 監視用オブジェクト作成
		Monitor = New ManagementEventWatcher(Query)
		' イベントハンドラ登録
		AddHandler Monitor.EventArrived, AddressOf Monitor_EventArrived

		' 監視開始
		Monitor.Start()


	End Sub

	' **************************************************
	' イベント
	' **************************************************
	Public Sub Monitor_EventArrived(ByVal sender As Object, _
	  ByVal e As EventArrivedEventArgs)

		Dim Bridge As New ProcBridge(AddressOf SetData)
		Dim targetProcess As ManagementBaseObject = e.NewEvent

		Dim str1 = _
		CType(targetProcess("TargetInstance"), _
		 ManagementBaseObject)("Name")
		Dim str2 = _
		CType(targetProcess("TargetInstance"), _
		 ManagementBaseObject)("ExecutablePath")
		Me.Invoke(Bridge, New Object() {1, str1, str2})

	End Sub

	' ************************************************************
	' 橋渡し用デリゲート
	' ************************************************************
	Delegate Sub ProcBridge(ByVal type As Integer, _
	ByVal str1 As String, ByVal str2 As String)

	' ************************************************************
	' 橋渡し用実体
	' ************************************************************
	Private Sub SetData(ByVal type As Integer, _
	ByVal Name As String, ByVal Path As String)

		If type = 1 Then
			Me.LboxGrid1.AddRow()
			Me.LboxGrid1.SetColumnText("TIME", Now.ToString())
			Me.LboxGrid1.SetColumnText("NAME", Name)
			Me.LboxGrid1.SetColumnText("PATH", Path)
		End If

	End Sub

	' **************************************************
	' フォームが閉じる前[ e.Cancel = True でキャンセル可能 ]
	' **************************************************
	Private Sub Form1_FormClosing(ByVal sender As System.Object, _
	 ByVal e As System.Windows.Forms.FormClosingEventArgs) _
	 Handles MyBase.FormClosing

		' 監視終了
		Monitor.Stop()
		Monitor.Dispose()

	End Sub

End Class