CodeItBetter Programming Another VB Programming Blog

How to find and terminate running applications

Posted on January 5, 2009
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
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
'System & API - How to find and terminate running applications
Option Explicit
 
Const MAX_PATH& = 260
 
Declare Function TerminateProcess Lib "kernel32" (ByVal ApphProcess As Long, _
    ByVal uExitCode As Long) As Long
Declare Function OpenProcess Lib "kernel32" (ByVal dwDesiredAccess As Long, _
    ByVal blnheritHandle As Long, ByVal dwAppProcessId As Long) As Long
Declare Function ProcessFirst Lib "kernel32" Alias "Process32First" (ByVal hSnapshot As Long, _
    uProcess As PROCESSENTRY32) As Long
Declare Function ProcessNext Lib "kernel32" Alias "Process32Next" (ByVal hSnapshot As Long, _
    uProcess As PROCESSENTRY32) As Long
Declare Function CreateToolhelpSnapshot Lib "kernel32" Alias "CreateToolhelp32Snapshot" _
    (ByVal lFlags As Long, lProcessID As Long) As Long
Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
 
Private Type LUID
    lowpart As Long
    highpart As Long
End Type
 
Private Type TOKEN_PRIVILEGES
    PrivilegeCount As Long
    LuidUDT As LUID
    Attributes As Long
End Type
 
Const TOKEN_ADJUST_PRIVILEGES = &H20
Const TOKEN_QUERY = &H8
Const SE_PRIVILEGE_ENABLED = &H2
Const PROCESS_ALL_ACCESS = &H1F0FFF
 
Private Declare Function GetVersion Lib "kernel32" () As Long
Private Declare Function GetCurrentProcess Lib "kernel32" () As Long
Private Declare Function OpenProcessToken Lib "advapi32" (ByVal ProcessHandle As Long, _
    ByVal DesiredAccess As Long, TokenHandle As Long) As Long
Private Declare Function LookupPrivilegeValue Lib "advapi32" Alias "LookupPrivilegeValueA" _
    (ByVal lpSystemName As String, ByVal lpName As String, lpLuid As LUID) As Long
Private Declare Function AdjustTokenPrivileges Lib "advapi32" (ByVal TokenHandle As Long, _
    ByVal DisableAllPrivileges As Long, NewState As TOKEN_PRIVILEGES, ByVal BufferLength As Long, _
    PreviousState As Any, ReturnLength As Any) As Long
 
Type PROCESSENTRY32
    dwSize As Long
    cntUsage As Long
    th32ProcessID As Long
    th32DefaultHeapID As Long
    th32ModuleID As Long
    cntThreads As Long
    th32ParentProcessID As Long
    pcPriClassBase As Long
    dwFlags As Long
    szexeFile As String * MAX_PATH
End Type
 
Public Function KillApp(myName As String) As Boolean
    Const TH32CS_SNAPPROCESS As Long = 2&
    Const PROCESS_ALL_ACCESS = 0
    Dim uProcess As PROCESSENTRY32
    Dim rProcessFound As Long
    Dim hSnapshot As Long
    Dim szExename As String
    Dim exitCode As Long
    Dim myProcess As Long
    Dim AppKill As Boolean
    Dim appCount As Integer
    Dim i As Integer
    On Local Error GoTo Finish
    appCount = 0
    uProcess.dwSize = Len(uProcess)
    hSnapshot = CreateToolhelpSnapshot(TH32CS_SNAPPROCESS, 0&)
    rProcessFound = ProcessFirst(hSnapshot, uProcess)
    Do While rProcessFound
        i = InStr(1, uProcess.szexeFile, Chr ( 0 ) )
        szExename = LCase$(Left$(uProcess.szexeFile, i - 1))
        If Right$(szExename, Len(myName)) = LCase$(myName) Then
            KillApp = True
            appCount = appCount + 1
            myProcess = OpenProcess(PROCESS_ALL_ACCESS, False, uProcess.th32ProcessID)
            If KillProcess(uProcess.th32ProcessID, 0) Then
                'For debug.... Remove this
                MsgBox "Instance no. " & appCount & " of " & szExename & " was terminated!"
            End If
 
        End If
        rProcessFound = ProcessNext(hSnapshot, uProcess)
    Loop
    Call CloseHandle(hSnapshot)
    Exit Function
Finish:
    MsgBox "Error!"
End Function
 
'Terminate any application and return an exit code to Windows.
Function KillProcess(ByVal hProcessID As Long, Optional ByVal exitCode As Long) As Boolean
    Dim hToken As Long
    Dim hProcess As Long
    Dim tp As TOKEN_PRIVILEGES
 
 
    If GetVersion() >= 0 Then
 
        If OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES Or _
            TOKEN_QUERY, hToken) = 0 Then
            GoTo CleanUp
        End If
 
        If LookupPrivilegeValue("", "SeDebugPrivilege", tp.LuidUDT) = 0 Then
            GoTo CleanUp
        End If
 
        tp.PrivilegeCount = 1
        tp.Attributes = SE_PRIVILEGE_ENABLED
 
        If AdjustTokenPrivileges(hToken, False, tp, 0, ByVal 0&, ByVal 0&) = 0 Then
            GoTo CleanUp
        End If
    End If
 
    hProcess = OpenProcess(PROCESS_ALL_ACCESS, 0, hProcessID)
    If hProcess Then
 
        KillProcess = (TerminateProcess(hProcess, exitCode) <> 0)
        ' close the process handle
        CloseHandle hProcess
    End If
 
    If GetVersion() >= 0 Then
        ' under NT restore original privileges
        tp.Attributes = 0
        AdjustTokenPrivileges hToken, False, tp, 0, ByVal 0&, ByVal 0&
 
CleanUp:
        If hToken Then CloseHandle hToken
    End If
End Function
 
Sub main()
    Dim pID As Long
    Dim i As Integer
    Dim strExe As String
    strExe = "Notepad.Exe"
    For i = 0 To 4
        pID = Shell(strExe, vbNormalFocus)
    Next i
    'Five instances of notepad.exe is now created
    Debug.Assert False
    MsgBox "It is " & KillApp(strExe) & " that all instances of " & vbCrLf & strExe & _
        " have been terminated!"
End Sub
 
'Another way:

Option Explicit
 
Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, _
    ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long
Private Declare Function GetWindowText Lib "user32.dll" Alias "GetWindowTextA" _
    (ByVal hwnd As Long, ByVal lpString As String, ByVal nMaxCount As Long) As Long
Private Declare Function EnumWindows Lib "user32.dll" (ByVal lpEnumFunc As Long, _
    ByVal lParam As Long) As Long
 
Private Const WM_CLOSE = &H10
Private Const WM_QUIT = &H12
 
Private Target As String
Public TargetOpen As Boolean
 
Private Function EnumCallback(ByVal app_hWnd As Long, ByVal param As Long) As Long
    Dim buf As String * 256
    Dim title As String
    Dim length As Long
    length = GetWindowText(app_hWnd, buf, Len(buf))
    title = Left$(buf, length)
    If InStr(title, Target) <> 0 Then
        TargetOpen = True
        SendMessage app_hWnd, WM_CLOSE, 0, 0
    End If
    EnumCallback = 1
End Function
 
Public Sub TerminateTask(app_name As String, app_exe As String)
    Dim Process As Variant
    TargetOpen = False
    Target = app_name
    EnumWindows AddressOf EnumCallback, 0
    For Each Process In GetObject("winmgmts:").ExecQuery("Select * from Win32_Process " & _
        "Where Name = '" & app_exe & "'")
        TargetOpen = True
        Process.Terminate
    Next
End Sub
 
'How can I call this function:
'Call TerminateTask("url.txt","Notepad")

'Another way:

'How to terminate the running process

Option Explicit
 
Sub Main()
    Call TerminateProcess("Notepad.exe")
End Sub
 
Public Sub TerminateProcess(app_exe As String)
    Dim Process As Variant
    For Each Process In GetObject("winmgmts:").ExecQuery("Select * from Win32_Process " & _
        "Where Name = '" & app_exe & "'")
        Process.Terminate
    Next
End Sub
Comments (0) Trackbacks (0)

No comments yet.


Leave a comment


 

No trackbacks yet.