Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people, just like you, are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
Solved

How Do I Kill a Proccess Using Visual Basic v6.0? ( Almost Solved )

Posted on 2008-10-09
3
282 Views
Last Modified: 2013-12-26
Hi experts, i am trying to terminate/kill a proccess using visual basic v6.0. The attached code below works but only if i provide the filename.exe of the window. The problem is that i want to KILL the proccess of a window by providing only the WindowTitle Name. See my example below:

>Let's say i do this..
KillApp "Notepad.exe" ' Filename.exe
>This will terminate all the notepad windows, something that i dont want!
>I need to do something like ...
KillApp "Today - Notepad" ' Window Caption
> I have tried with no luck, i dont get any error message just nothing happenes.

Can you help me please?
Option Explicit
 
Private Declare Function TerminateProcess Lib "kernel32" (ByVal ApphProcess As Long, ByVal uExitCode As Long) As Long
Private Declare Function OpenProcess Lib "kernel32" (ByVal dwDesiredAccess As Long, ByVal blnheritHandle As Long, ByVal dwAppProcessId As Long) As Long
Private Declare Function ProcessFirst Lib "kernel32" Alias "Process32First" (ByVal hSnapshot As Long, uProcess As PROCESSENTRY32) As Long
Private Declare Function ProcessNext Lib "kernel32" Alias "Process32Next" (ByVal hSnapshot As Long, uProcess As PROCESSENTRY32) As Long
Private Declare Function CreateToolhelpSnapshot Lib "kernel32" Alias "CreateToolhelp32Snapshot" (ByVal lFlags As Long, lProcessID As Long) As Long
Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
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
Private Const MAX_PATH& = 260
Private Const TOKEN_ADJUST_PRIVILEGES = &H20
Private Const TOKEN_QUERY = &H8
Private Const SE_PRIVILEGE_ENABLED = &H2
Private Const PROCESS_ALL_ACCESS = &H1F0FFF
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
Private 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
 
Private 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)
            KillProcess uProcess.th32ProcessID, 0
        End If
        rProcessFound = ProcessNext(hSnapshot, uProcess)
    Loop
    Call CloseHandle(hSnapshot)
    Exit Function
Finish:
    MsgBox "Error!"
End Function
 
Private 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
 
Private Sub Command1_Click()
   KillApp "Notepad.exe"
End Sub

Open in new window

0
Comment
Question by:KingSencat
  • 2
3 Comments
 
LVL 3

Expert Comment

by:sam_norian
ID: 22683026
Hi,

This might work...

Private Sub Command1_Click()
Shell ("taskkill /F /FI " & Chr(34) & "WINDOWTITLE eq Test.txt - Notepad" & Chr(34) & "")
End Sub

Open in new window

0
 
LVL 29

Expert Comment

by:nffvrxqgrcfqvvc
ID: 22684059
<<< The problem is that i want to KILL the proccess of a window by providing only the WindowTitle Name. >>>

This is actual very simple. First you need to use FindWindow to a handle from that window. Then you want to get a pid from that hwnd handle. Next you need to get a real process handle by using OpenProcess. Once you have this you can pass the real process handle to the TerminateProcess API. I wrote an example that should help you.
Option Explicit
 
Private Declare Function FindWindowW Lib "user32.dll" (ByVal lpClassName As Long, ByVal lpWindowTitle As Long) As Long
Private Declare Function GetWindowThreadProcessId Lib "user32.dll" (ByVal hWnd As Long, ByRef lpdwProcessId As Long) As Long
Private Declare Function OpenProcess Lib "kernel32" (ByVal dwDesiredAccess 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
 
' * process access rights for hProcess
Private Const PROCESS_QUERY_INFORMATION     As Long = 1024
Private Const PROCESS_TERMINATE             As Long = &H1
 
Public Sub TerminateProcessFromTitle(ByVal szTitle As String)
    
    Dim hWindow     As Long ' * handle to the window
    Dim hThread     As Long ' * identifier of the thread that created the window
    Dim hProcess    As Long ' * handle to the process
    Dim ppid        As Long ' * pointer to *ppid
    
    ' * get a handle to the window from the title
    hWindow = FindWindowW(StrPtr(vbNullString), StrPtr(szTitle))
    ' * sanity check
    If hWindow <> 0 Then
        ' * get a process id from this handle
        hThread = GetWindowThreadProcessId(hWindow, ppid)
        ' * return the real process handle from the *ppid
        hProcess = OpenProcess(PROCESS_QUERY_INFORMATION Or PROCESS_TERMINATE, 0, ppid)
        ' * terminate the specified process
        Call TerminateProcess(hProcess, 0)
    End If
    
End Sub

Open in new window

0
 
LVL 29

Accepted Solution

by:
nffvrxqgrcfqvvc earned 500 total points
ID: 22684091
I just want to mention that unless you really must terminate the process. You should instead send a WM_CLOSE message to the window.

Typically first you might want to check if the window is responding.

BOOL IsHungAppWindow(          HWND hWnd
);

If this returns TRUE then TerminateProcess, Otherwise you should gracefully close this window using WM_CLOSE.

;)
0

Featured Post

Free Tool: Subnet Calculator

The subnet calculator helps you design networks by taking an IP address and network mask and returning information such as network, broadcast address, and host range.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Enums (shorthand for ‘enumerations’) are not often used by programmers but they can be quite valuable when they are.  What are they? An Enum is just a type of variable like a string or an Integer, but in this case one that you create that contains…
When you see single cell contains number and text, and you have to get any date out of it seems like cracking our heads.
Get people started with the process of using Access VBA to control Excel using automation, Microsoft Access can control other applications. An example is the ability to programmatically talk to Excel. Using automation, an Access application can laun…
Get people started with the utilization of class modules. Class modules can be a powerful tool in Microsoft Access. They allow you to create self-contained objects that encapsulate functionality. They can easily hide the complexity of a process from…

791 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question