프로세스 시작/종료 이벤트시에 하고 싶은 것들이 많다.
서버 프로그래머라면 서버 프로그램이 이유없이 죽을때 시간 및 Log를 남길 수도 있고,
프로그램이 죽으면, 다시 시작하도록 설정해서 24시간 스스로 유지되길 바라는 경우가 있다.
이럴때 윈도우에서 실행가능한 VBS(WMI)스크립트로 간단하게 관리해 보자.

아래의 스크립트는 다음과 같은 작동을 합니다.
1. 무한 루프를 반복하면서 1초마다 프로세스가 생성되거나 삭제되는 이벤트를 감시한다.
2. notepad.exe 프로세스가 생성되면, calc.exe를 실행합니다.
3. notepad.exe 프로세스가 삭제되면, calc.exe를 종료합니다.


Option Explicit

Dim strComputer
strComputer = "."

'기본 Object 가져오기
Dim Shell : Set Shell = WScript.CreateObject("WScript.Shell")
Dim FSO : Set FSO = CreateObject("Scripting.FileSystemObject")
Dim objWMIService : Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
Dim colMonitorCreateProcessesEvent : Set colMonitorCreateProcessesEvent = objWMIService.ExecNotificationQuery("select * from __InstanceCreationEvent within 1 where TargetInstance isa 'Win32_Process'" )
Dim colMonitorDeleteProcessesEvent : Set colMonitorDeleteProcessesEvent = objWMIService.ExecNotificationQuery("select * from __InstanceDeletionEvent within 1 where TargetInstance isa 'Win32_Process'" )

'CMD 윈도우 98에서도 적용 가능하게 COMSPEC으로 가져온다.
Dim COMSPEC : COMSPEC = Shell.ExpandEnvironmentStrings("%comspec%")

'메인 함수 실행
Call MainFunction()


Sub MainFunction
	'중복 실행 방지 코드 - vbs 파일명을 입력합니다.
	If( IsExistSameVBS( "ProcessEvent.vbs" ) ) Then
		Wscript.Quit
	End If
	
	Do While True
		Call ProcessCreatedEvent()
		Call ProcessDeletedEvent()
		Wscript.Sleep( 1000 )
	Loop
	
	Wscript.Quit
End Sub


Sub ProcessCreatedEvent
	'프로세스 시작시
	
	'모니터링할 프로세스 이름
	Dim strMonitorProcessName : strMonitorProcessName = "notepad.exe"
	
	'실행할 파일
	Dim strExecuteFilePath : strExecuteFilePath = "C:\Windows\system32"
	Dim strExecuteFileName : strExecuteFileName = "calc.exe"
	
	'프로세스 시작 이벤트 검사
	Dim objLastestProcess : Set objLastestProcess = colMonitorCreateProcessesEvent.NextEvent
	If( StrComp(Lcase(objLastestProcess.TargetInstance.Name), Lcase(strMonitorProcessName), 1 ) = 0 ) Then
		'프로그램 실행
		Call ExecuteOnce( strExecuteFilePath, strExecuteFileName, "" )
	End If
End Sub


Sub ProcessDeletedEvent
	'프로세스 종료시
	
	'모니터링할 프로세스 이름
	Dim strMonitorProcessName : strMonitorProcessName = "Notepad.exe"
	
	'종료할 프로세스 이름
	Dim strKillProcessName : strKillProcessName = "calc.exe"
	
	'프로세스 종료 이벤트 검사
	Dim objLastestProcess : Set objLastestProcess = colMonitorDeleteProcessesEvent.NextEvent
	If( StrComp(Lcase(objLastestProcess.TargetInstance.Name), Lcase(strMonitorProcessName), 1) = 0 ) Then
		'프로세스 종료
		Call KillProcess( strKillProcessName )
	End If
End Sub


Sub ExecuteFile (strFileFullPath, Arguments)
	If( FSO.FileExists( strFileFullPath ) ) Then
		Shell.Run COMSPEC & " /c " & strFileFullPath & Arguments & " & Exit", 0
	Else
		Shell.Popup strFileFullPath & " 을(를) 찾을 수 없습니다.", 3, "File Dose not exist", 48
		Wscript.Quit
	End If
End Sub


Function IsExistProcess( strProcessName )
	IsExistProcess = False
	
	Dim colProcessList, objProcess
	Set colProcessList = objWMIService.ExecQuery( "select * from Win32_Process" )
	For Each objProcess in colProcessList
		If( StrComp(Lcase(strProcessName), Lcase(objProcess.Name), 1) = 0 ) Then
			IsExistProcess = True
		End If
	Next
End Function


Sub ExecuteOnce( strFilePath, strFileName, Arguments )
	If( IsExistProcess( strFileName ) = False ) Then
		Call ExecuteFile( strFilePath & "\" & strFileName, Arguments )
		Wscript.Sleep 2000
	End If
End Sub


Sub KillProcess( strProcessName )
	Dim colProcessList, objProcess
	Set colProcessList = objWMIService.ExecQuery( "select * from Win32_Process" )
	For Each objProcess in colProcessList
		If( StrComp(Lcase(strProcessName), Lcase(objProcess.Name), 1) = 0 ) Then
			objProcess.Terminate()
		End If
	Next
End Sub


Function IsExistSameVBS( strFileName )
	IsExistSameVBS = False
	Dim nSameVBSCount : nSameVBSCount = 0
	
	Dim colProcessList, objProcess
	Set colProcessList = objWMIService.ExecQuery("SELECT * FROM Win32_Process WHERE Name = 'wscript.exe' OR Name = 'cscript.exe'")
	For Each objProcess in colProcessList
		If InStr( Lcase(objProcess.CommandLine), Lcase(strFileName) ) Then
			nSameVBSCount = nSameVBSCount + 1
		End If
	Next
	
	If( nSameVBSCount > 1 ) Then
		IsExistSameVBS = True
		Wscript.echo strFileName & " 은 이미 실행중인 스크립트 입니다."
	End If
End Function
2009/11/06 21:53 2009/11/06 21:53

덧글을 달아 주세요