스크립트 언어에서는 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

+ Recent posts