스크립트 언어에서는 API를 사용할 수 없다. 따라서 스크립트 언어에서 API와 같은 기능에 접근하기 위한 방법으로 WMI를 재공한다.
VB6에서 WMI를 사용하기 위해서는 Microsoft WMI Scripting V1.2 Library 참조(프로젝트 메뉴의 참조)가 필요하다.
다음 소스는 종료 하고자 하는 프로세스에서 포함하는 윈도우를 클릭하는 경우, 윈도우에 해당하는 프로세스 ID를 얻고, WMI를 사용하여 프로세스를 종료하는 방법이다.
훅 프로시저에서 WMI를 사용할 수 없으므로(이유는 모름) 타이머를 사용하여 WMI를 사용 프로세스를 종료시키는 프로시저를 호출하게 했다.
다음은 소스이다.
'폼 모듈 소스
' WMI를 사용한 프로세스 강제 종료
Option Explicit ' 모든 변수는 선언된 뒤에 사용할 수 있다.
Private Declare Function SetWindowsHookEx Lib "user32" Alias "SetWindowsHookExA" (ByVal idHook As Long, ByVal lpfn As Long, ByVal hmod As Long, ByVal dwThreadId As Long) As Long ' 훅체인에 훅프로시저를 선두에 끼워넣는다, 성공하면 훅프로시저의 핸들을 복귀한다.
Private Declare Function UnhookWindowsHookEx Lib "user32" (ByVal hHook As Long) As Long ' 훅체인에서 훅 핸들이 나타내는 훅 프로시저를 제거한다.
Private Const WH_MOUSE_LL = 14
Private hhkLowLevelMouse As Long ' 훅 설치가 완료되는경우, 그 훅을 나타내는 핸들
Private Sub Form_Load()
GetWindowThreadProcessId Me.hWnd, MyPid
hhkLowLevelMouse = SetWindowsHookEx(WH_MOUSE_LL, AddressOf LowLevelMouseProc, App.hInstance, 0)
End Sub
Private Sub Form_Unload(Cancel As Integer)
If hhkLowLevelMouse = 0 Then Exit Sub
UnhookWindowsHookEx hhkLowLevelMouse ' 훅을 체인에서 훅 제거한다.
hhkLowLevelMouse = 0
End Sub
' 일반 모듈 소스
' Microsoft WMI Scripting V1.2 Library 참조
' WMI 사용을 위해서는 Microsoft WMI Scripting V1.2 Library 참조가 필요하다.
' 훅 프로시저에서 WMI가 실행이 않된다(이유 모름)
Option Explicit ' 모든 변수는 선언된 뒤에 사용할 수 있다.
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long) ' 메모리 내용을 복사한다.
Private Declare Function CallNextHookEx Lib "user32" (ByVal hHook As Long, ByVal nCode As Long, ByVal wParam As Long, lParam As Any) As Long ' 훅체인에서 다음 훅프로시저를 호출한다.
Private Declare Function WindowFromPoint Lib "user32" (ByVal xPoint As Long, ByVal yPoint As Long) As Long
Private Declare Function SetTimer Lib "user32" (ByVal hWnd As Long, ByVal nIDEvent As Long, ByVal uElapse As Long, ByVal lpTimerFunc As Long) As Long
Private Declare Function KillTimer Lib "user32" (ByVal hWnd As Long, ByVal nIDEvent As Long) As Long
Public Declare Function GetWindowThreadProcessId Lib "user32" (ByVal hWnd As Long, lpdwProcessId As Long) As Long
Private Const HC_ACTION = 0
Private Const WM_LBUTTONDOWN = &H201
Private Type POINTAPI
X As Long
Y As Long
End Type
Private Type MSLLHOOKSTRUCT
pt As POINTAPI
mouseData As Long
flags As Long
time As Long
dwExtraInfo As Long
End Type
Public MyPid As Long ' 현재 프로세스의 PID
Private KillPid As Long ' 삭제할 프로세스 PID
Public Function LowLevelMouseProc(ByVal nCode As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Dim p As MSLLHOOKSTRUCT
Dim Windowhwnd As Long ' 마우스 위치의 윈도우 핸들
Dim Pid As Long ' 해당 윈도우를 갖는 프로세스 ID
If (nCode = HC_ACTION) And wParam = WM_LBUTTONDOWN Then
CopyMemory p, ByVal lParam, Len(p)
Windowhwnd = WindowFromPoint(p.pt.X, p.pt.Y)
GetWindowThreadProcessId Windowhwnd, Pid
If Not Pid = MyPid Then 'KillByPidUseWMI Pid ' 현재 프로세스 인경우는 제외
KillPid = Pid
SetTimer 0&, &H5000, 100, AddressOf KillByPidUseWMI
End If
End If
LowLevelMouseProc = CallNextHookEx(0, nCode, wParam, ByVal lParam)
End Function
Public Sub KillByPidUseWMI(ByVal hWnd As Long, ByVal uMsg As Long, ByVal idEvent As Long, ByVal dwTime As Long) ' WMI를 사용한 프로세스 ID에 해당하는 프로세스 강제 종료
Dim oWMI As SWbemLocator
Dim oItms As SWbemServices
Dim oresu As SWbemObjectSet
Dim ore As SWbemObject
KillTimer hWnd, idEvent ' 타이머를 제거한다.
Set oWMI = New SWbemLocator
Set oItms = oWMI.ConnectServer(Environ("ComputerName"), "root\CIMV2")
Set oresu = oItms.ExecQuery("SELECT * FROM Win32_Process WHERE Handle=" & KillPid)
For Each ore In oresu
ore.Terminate
Next
Set oresu = Nothing
Set ore = Nothing
Set oWMI = Nothing
Set oItms = Nothing
End Sub