There are going to be two parts to this tutorial. One part is going to be for less advanced users, and the second part is going to be for those who know a little more about VB and Windows.
So, to start with, create a new WinForms Project.
Go to the designer for your main form, and add a listbox, and two buttons.
Name the listbox "lstMain", the first button "btnRefresh", and the second button "btnKill".
Your form should now look somewhat like this:

If you are just beginning in Visual Basic, follow these instructions, otherwise skip down to the next underlined title:
1: Double click "btnRefresh" to switch to the code view. In the Button_Click event, add this code:
'Clear all the items in the listbox
lstMain.Items.Clear()
'For every process which is running on the computer
For Each p As Process In Process.GetProcesses
'If the MainWindowTitle of the process is not empty
If p.MainWindowTitle = String.Empty = False Then
'Add the process name, the main window title, and the process ID (what windows uses to identify the process) to the listbox)
lstMain.Items.Add(p.ProcessName & " # " & p.MainWindowTitle & " # " & p.Id)
End If
Next
Now press F5 to debug your project. On your form, press "btnRefresh". The listbox should be populated with the window titles of most of the running applications*.
So, stop debugging, and go back to your designer. Double click "btnKill", and add this code:
Try
'Get the selected item on the listbox
Dim whole As String = lstMain.SelectedItem.ToString
'Get all the text after the last "#" in the item
Dim pid = whole.Substring(whole.LastIndexOf(" # "))
'Replace " # " with nothing, to leave the ID of the process alone
pid = pid.Replace(" # ", "")
'Get the process which has the same ID as the one selected in the listbox
Dim p As Process = Process.GetProcessById(pid)
Try
'Try to kill the process (this may not work if you're not an Administrator, if the process has already ended, or if the process has been protected at kernel ring zero (maybe I'll do a tutorial on that later...)
p.Kill()
Catch ex As Exception
'If we can't kill the process, show an error
MessageBox.Show(ex.Message)
End Try
Catch ex As Exception
'If we can't get the selected item of the listbox (most likely because the user has not selected it), then show an error.
MessageBox.Show(ex.Message)
End Try
So, press F5 to debug your code, press "btnRefresh", and then select a process you want to kill, and press "btnKill". Don't select your antivirus's window because if it's any good, the kill command won't work on it.
___END OF BEGINNER TUTORIAL___
*You may notice that this code does not retrieve all open windows. This is because one process can have multiple open windows, and a process does not have to register a MainWindowTitle when starting, so you could have a process open without it having a MainWindowTitle attribute, but the process might have a window open.
If you are more advanced, and you are more experienced using Visual Basic, and know about calling APIs from Windows, then this is the tutorial you should follow:
Firstly, switch to the code view, and import the following:
Imports System.Runtime.InteropServices Imports System.Text
So, having created our main form (see picture above), double click anywhere on the form, and then add the following declarations (separate from any events):
<DllImport("USER32.DLL")> _
Private Shared Function GetShellWindow() As IntPtr
End Function
<DllImport("USER32.DLL")> _
Private Shared Function GetWindowText(ByVal hWnd As IntPtr, ByVal lpString As StringBuilder, ByVal nMaxCount As Integer) As Integer
End Function
<DllImport("USER32.DLL")> _
Private Shared Function GetWindowTextLength(ByVal hWnd As IntPtr) As Integer
End Function
<DllImport("user32.dll", SetLastError:=True)> _
Private Shared Function GetWindowThreadProcessId(ByVal hWnd As IntPtr, <Out()> ByRef lpdwProcessId As UInt32) As UInt32
End Function
<DllImport("USER32.DLL")> _
Private Shared Function IsWindowVisible(ByVal hWnd As IntPtr) As Boolean
End Function
Private Delegate Function EnumWindowsProc(ByVal hWnd As IntPtr, ByVal lParam As Integer) As Boolean
<DllImport("USER32.DLL")> _
Private Shared Function EnumWindows(ByVal enumFunc As EnumWindowsProc, ByVal lParam As Integer) As Boolean
End Function
Private hShellWindow As IntPtr = GetShellWindow()
Private dictWindows As New Dictionary(Of IntPtr, String)
Private currentProcessID As Integer
Public Function GetOpenWindowsFromPID(ByVal processID As Integer) As IDictionary(Of IntPtr, String)
dictWindows.Clear()
currentProcessID = processID
EnumWindows(AddressOf enumWindowsInternal, 0)
Return dictWindows
End Function
Private Function enumWindowsInternal(ByVal hWnd As IntPtr, ByVal lParam As Integer) As Boolean
If (hWnd <> hShellWindow) Then
Dim windowPid As UInt32
If Not IsWindowVisible(hWnd) Then
Return True
End If
Dim length As Integer = GetWindowTextLength(hWnd)
If (length = 0) Then
Return True
End If
GetWindowThreadProcessId(hWnd, windowPid)
If (windowPid <> currentProcessID) Then
Return True
End If
Dim stringBuilder As New System.Text.StringBuilder(length)
GetWindowText(hWnd, stringBuilder, (length + 1))
dictWindows.Add(hWnd, stringBuilder.ToString)
End If
Return True
End Function
Well, there's quite a lot there. The bottom line is that these declarations well help us use some pretty complicated OS calls which will let us get all the open windows, including Dialogs, and MessageBoxes.
Now, double click your "btnRefresh". Add this code to the Click Event:
'For every process running
For Each P As Process In Process.GetProcesses
'Get a list of ALL of the open windows associated with the process
Dim windows As IDictionary(Of IntPtr, String) = GetOpenWindowsFromPID(p.Id)
For Each kvp As KeyValuePair(Of IntPtr, String) In windows
'This small if statement lets us ignore the start menu...
If kvp.Value.ToLower = "start" = False Then
'''If it's not the start menu, then add the ProcessName, windowtitle, and ID to the list...
lstMain.Items.Add(P.ProcessName & " # " & kvp.Value & " # " & P.ID)
End If
Next
Next
Press F5 to begin debugging, and click "btnRefresh". You should see the titles, process names & process IDs of all the open windows, incuding dialogs, OpenFileWindows, and MessageBoxes.
When finished, stop debugging, and add the follwing code to the Click event of the "btnKill":
So, stop debugging, and go back to your designer. Double click "btnKill", and add this code:
Try
'Get the selected item on the listbox
Dim whole As String = lstMain.SelectedItem.ToString
'Get all the text after the last "#" in the item
Dim pid = whole.Substring(whole.LastIndexOf(" # "))
'Replace " # " with nothing, to leave the ID of the process alone
pid = pid.Replace(" # ", "")
'Get the process which has the same ID as the one selected in the listbox
Dim p As Process = Process.GetProcessById(pid)
Try
'Try to kill the process (this may not work if you're not an Administrator, if the process has already ended, or if the process has been protected at kernel ring zero (maybe I'll do a tutorial on that later...)
p.Kill()
Catch ex As Exception
'If we can't kill the process, show an error
MessageBox.Show(ex.Message)
End Try
Catch ex As Exception
'If we can't get the selected item of the listbox (most likely because the user has not selected it), then show an error.
MessageBox.Show(ex.Message)
End Try
So the code basically stays the same as in the basic tutorial...
I hope you enjoyed this tutorial, and I hope you were able to make an application from it.






MultiQuote





|