Muj google něco našel. Jde to buď s API, nebo s pomocí Microsoft Scripting Reference. Scripting jsem nezkoušel.
API dává na výběr dvě možnosti: Unload nebo Terminate. "Unload" funguje, jen když process není zamrzlej a de facto spouští queryunload event toho processu, takže se může objevit dialog, "Chcete uložit změny v souboru?" :-) nebo tak něco, podle kódu té procedury, který může mimo jiné celý Unload zrušit (Cancel = True). Terminate je okamžitý odstřel třeba i zamrzlého procesu.
Obě metody získávají ProcessID skrz jméno processu, což není přesně ExeName. Chce to vyzkoušet, většinou je to ExeName bez ".exe".
Code:
Private Declare Function IsWindow Lib "user32" (ByVal hWnd As Long) As Long
Private Declare Function SendMessageTimeout Lib "user32" Alias "SendMessageTimeoutA" (ByVal hWnd As Long, ByVal msg As Long, ByVal wParam As Long, lParam As Any, ByVal fuFlags As Long, ByVal uTimeout As Long, lpdwResult As Long) As Long
Const WM_NULL As Long = &H0
Const WM_CLOSE = &H10
'Const SMTO_NORMAL As Long = &H0
'Const SMTO_BLOCK As Long = &H1
Const SMTO_ABORTIFHUNG As Long = &H2
Const ERROR_TIMEOUT As Long = &H5B4
Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Private Declare Function PostMessage Lib "user32" Alias "PostMessageA" (ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long
Private Declare Function GetWindowThreadProcessId Lib "user32.dll" (ByVal hWnd As Long, lpdwProcessId As Long) As Long
Private Declare Function OpenProcess Lib "kernel32" (ByVal dwDesiredAcess As Long, ByVal bInheritHandle As Long, ByVal dwProcessId As Long) As Long
Private Declare Function TerminateProcess Lib "kernel32" (ByVal hProcess As Long, ByVal uExitCode As Long) As Long
Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
Const SYNCHRONIZE = &H100000
Const PROCESS_TERMINATE As Long = &H1
Dim Process_hWnd As Long
Dim Process_ID As Long
Dim Process_Handle As Long
Public Function ProcessResponding(ByVal hWnd As Long, Optional ByVal Timeout As Long = 100) As Boolean
Dim nRet As Long
Dim nResult As Long
If IsWindow(hWnd) Then
nRet = SendMessageTimeout(hWnd, WM_NULL, 0&, 0&, SMTO_ABORTIFHUNG, Timeout, nResult)
IsResponding = (nRet <> 0)
End If
End Function
Private Sub Unload_Process(ProgramName As String)
Process_hWnd = FindWindow(vbNullString, ProgramTitle)
If Process_hWnd = 0 Then
MsgBox "Error finding process window handle"
Exit Sub
End If
If Not ProcessResponding(Process_hWnd) Then
MsgBox "Process is not responding and cannot be unloaded"
Exit Sub
End If
PostMessage Process_hWnd, WM_CLOSE, 0&, 0&
MsgBox "Process successfully unloaded"
End Sub
Private Sub Terminate_Process_If_Hung(ProgramName As String)
Process_hWnd = FindWindow(vbNullString, ProgramTitle)
If Process_hWnd = 0 Then
MsgBox "Error finding process window handle"
Exit Sub
End If
If ProcessResponding(Process_hWnd) Then
MsgBox "Process is responding"
Exit Sub
End If
GetWindowThreadProcessId Process_hWnd, Process_ID
If Process_ID = 0 Then
MsgBox "Error finding process ID"
Exit Sub
End If
Process_Handle = OpenProcess(SYNCHRONIZE Or PROCESS_TERMINATE, ByVal 0&, Process_ID)
If Process_ID = 0 Then
MsgBox "Error finding process object handle"
Exit Sub
End If
If TerminateProcess(Process_Handle, 0&) = 0 Then
MsgBox "Error terminating process"
Else
MsgBox "Process successfully terminated"
End If
CloseHandle Process_Handle
End Sub