서버 프로그래머라면 서버 프로그램이 이유없이 죽을때 시간 및 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 |
덧글을 달아 주세요