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

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


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
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

글 걸기 주소 : 이 글에는 트랙백을 보낼 수 없습니다

덧글을 달아 주세요