|
Public Class Processes
Private Shared SecondPollTimeToDetectProcessClosingsAndOpenings As Integer = 5
Private WithEvents bwCheckProcesses As System.ComponentModel.BackgroundWorker = New System.ComponentModel.BackgroundWorker
Public WithEvents ObjectCreated As New SystemEvent(SystemEvents.EVENT_OBJECT_CREATE)
Public WithEvents ObjectDestroyed As New SystemEvent(SystemEvents.EVENT_OBJECT_DESTROY)
Public Event ProcessClosedEvent(ByVal processId As Integer)
Public Event ProcessOpenedEvent(ByVal processId As Integer)
Public Event ProcessListChangedNames(ByVal names() As String)
Public Event ProcessListChangedTitles(ByVal titles() As String)
Private ProcessList As New System.Collections.SortedList
'Private fIdentity As Byte() = (New Guid).ToByteArray
Private ProcessNames As New System.Collections.ArrayList
Private ProcessTitles As New System.Collections.ArrayList
Private ProcessListAll As New System.Collections.Hashtable
Private ProcessNamesAll As New System.Collections.ArrayList
Private ProcessTitlesAll As New System.Collections.ArrayList
Private ProcessNamesPrev As String = ""
Private ProcessTitlesPrev As String = ""
Private LastChecked As DateTime = New DateTime(0)
Private LastCheckDenied As Boolean = False
Private LastCheckedHwnd As String = "0000000000000000"
Private LastCheckedHwndAttempted As String = "8888888888888888"
Public Sub OnObjectCreated(ByVal hWinEventHook As IntPtr, ByVal eventType As UInteger, ByVal hwnd As IntPtr, ByVal idObject As Integer, ByVal idChild As Integer, ByVal dwEventThread As UInteger, ByVal dwmsEventTime As UInteger) Handles ObjectCreated.SystemEvent
'ProcessListAll.Clear()
'Dim mProcesses() As System.Diagnostics.Process = System.Diagnostics.Process.GetProcesses
'For x As Integer = 0 To mProcesses.Length - 1
' If Not ProcessListAll.Contains(mProcesses(x).MainWindowHandle) Then
' ProcessListAll.Add(mProcesses(x).MainWindowHandle, Nothing)
' End If
'Next
'If ProcessListAll.Contains(hwnd) Then
' CheckProcesses()
'End If
If idChild <> 0 Then
'Debug.WriteLine(hWinEventHook.ToString("X8") & Chr(9) & eventType.ToString("X8") & Chr(9) & hwnd.ToString("X8") & Chr(9) & idObject.ToString("X8") & Chr(9) & idChild.ToString("X8") & Chr(9) & dwEventThread.ToString("X8") & Chr(9) & dwmsEventTime.ToString("X8"))
CheckProcesses(hwnd.ToString("X16"))
End If
End Sub
Public Sub OnObjectDestroyed(ByVal hWinEventHook As IntPtr, ByVal eventType As UInteger, ByVal hwnd As IntPtr, ByVal idObject As Integer, ByVal idChild As Integer, ByVal dwEventThread As UInteger, ByVal dwmsEventTime As UInteger) Handles ObjectDestroyed.SystemEvent
If ProcessListAll.Contains(hwnd) Then
CheckProcesses()
End If
End Sub
Private Sub CheckProcesses(Optional ByVal Hwnd As String = "FFFFFFFFFFFFFFFF")
Dim last As New TimeSpan(Now.Ticks - LastChecked.Ticks)
If last.TotalSeconds < SecondPollTimeToDetectProcessClosingsAndOpenings Then
LastCheckDenied = True
LastCheckedHwndAttempted = Hwnd
Else
LastChecked = Now()
LastCheckDenied = False
If LastCheckedHwndAttempted <> LastCheckedHwnd Then
'Debug.WriteLine("checking... " & LastCheckedHwndAttempted & Chr(9) & LastCheckedHwnd)
LastCheckedHwnd = Hwnd
LastCheckedHwndAttempted = Hwnd
Try
ProcessListAll.Clear()
Dim mProcesses() As System.Diagnostics.Process = System.Diagnostics.Process.GetProcesses
For x As Integer = 0 To mProcesses.Length - 1
If (mProcesses(x).MainWindowHandle <> IntPtr.Zero) AndAlso (Not ProcessListAll.Contains(mProcesses(x).MainWindowHandle)) Then
ProcessListAll.Add(mProcesses(x).MainWindowHandle, Nothing)
End If
Dim thisName As String = CStr(mProcesses(x).ProcessName.Trim)
If (Not thisName Is Nothing) AndAlso (thisName.Length > 0) AndAlso (Not ProcessNamesAll.Contains(thisName)) Then
ProcessNamesAll.Add(thisName)
End If
ProcessNamesAll.Sort()
Dim thisTitle As String = CStr(mProcesses(x).MainWindowTitle.Trim)
If (Not thisTitle Is Nothing) AndAlso (thisTitle.Length > 0) AndAlso (Not ProcessTitlesAll.Contains(thisTitle)) Then
ProcessTitlesAll.Add(thisTitle)
End If
ProcessTitlesAll.Sort()
Next
Catch ex As Exception
Debug.WriteLine(ex.ToString)
End Try
Try
Dim newProcessList As System.Collections.SortedList = New System.Collections.SortedList
Dim mProcesses(ProcessNames.Count - 1)() As System.Diagnostics.Process
For x As Integer = 0 To ProcessNames.Count - 1
Dim thisName As String = CStr(ProcessNames.Item(x))
mProcesses(x) = System.Diagnostics.Process.GetProcessesByName(thisName)
For i = 0 To mProcesses(x).Length - 1
If ProcessTitles.Contains(mProcesses(x)(i).MainWindowTitle) Then
newProcessList.Add(mProcesses(x)(i).Id, mProcesses(x)(i))
End If
Next
Next
For Each processId As Integer In newProcessList.Keys
If Not ProcessList.ContainsKey(processId) Then
ProcessList.Add(processId, newProcessList(processId))
OnProcessChange(1, processId)
End If
Next
Dim k(ProcessList.Count - 1) As Integer
ProcessList.Keys.CopyTo(k, 0)
For i = 0 To k.Length - 1
If Not newProcessList.ContainsKey(k(i)) Then
ProcessList.Item(k(i)) = Nothing
ProcessList.Remove(k(i))
OnProcessChange(0, k(i))
End If
Next
Catch ex As Exception
Debug.WriteLine(ex.ToString)
End Try
ProcessNamesAll.Sort()
ProcessTitlesAll.Sort()
Dim names As String = Microsoft.VisualBasic.Join(ProcessNamesAll.ToArray, ",")
Dim titles As String = Microsoft.VisualBasic.Join(ProcessTitlesAll.ToArray, ",")
If ProcessNamesPrev <> names Then
ProcessNamesPrev = names
OnProcessChange(2, names)
End If
If ProcessTitlesPrev <> titles Then
ProcessTitlesPrev = titles
OnProcessChange(3, titles)
End If
End If
End If
End Sub
Public Sub OnProcessChange(ByVal progress As Integer, ByVal e As Object)
If Progress = 0 Then
If ((Not ProcessClosedEventEvent Is Nothing) AndAlso (ProcessClosedEventEvent.GetInvocationList.Length > 0)) Then
RaiseEvent ProcessClosedEvent(CInt(e))
End If
ElseIf progress = 1 Then
If ((Not ProcessOpenedEventEvent Is Nothing) AndAlso (ProcessOpenedEventEvent.GetInvocationList.Length > 0)) Then
RaiseEvent ProcessOpenedEvent(CInt(e))
End If
ElseIf progress = 2 Then
If ((Not ProcessListChangedNamesEvent Is Nothing) AndAlso (ProcessListChangedNamesEvent.GetInvocationList.Length > 0)) Then
RaiseEvent ProcessListChangedNames(CStr(e).Split(","c))
End If
ElseIf progress = 3 Then
If ((Not ProcessListChangedTitlesEvent Is Nothing) AndAlso (ProcessListChangedTitlesEvent.GetInvocationList.Length > 0)) Then
RaiseEvent ProcessListChangedTitles(CStr(e).Split(","c))
End If
End If
End Sub
Private Sub CheckProcesses(ByVal sender As Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles bwCheckProcesses.DoWork
While True
If bwCheckProcesses.CancellationPending = True Then
e.Cancel = True
Exit While
Else
End If
System.Threading.Thread.Sleep(SecondPollTimeToDetectProcessClosingsAndOpenings * 1000)
End While
End Sub
'Public Sub OnProcessChange(ByVal sender As Object, ByVal e As System.ComponentModel.ProgressChangedEventArgs) Handles bwCheckProcesses.ProgressChanged
' If e.ProgressPercentage = 0 Then
' If ((Not ProcessClosedEventEvent Is Nothing) AndAlso (ProcessClosedEventEvent.GetInvocationList.Length > 0)) Then
' RaiseEvent ProcessClosedEvent(CInt(e.UserState))
' End If
' ElseIf e.ProgressPercentage = 1 Then
' If ((Not ProcessOpenedEventEvent Is Nothing) AndAlso (ProcessOpenedEventEvent.GetInvocationList.Length > 0)) Then
' RaiseEvent ProcessOpenedEvent(CInt(e.UserState))
' End If
' ElseIf e.ProgressPercentage = 2 Then
' If ((Not ProcessListChangedNamesEvent Is Nothing) AndAlso (ProcessListChangedNamesEvent.GetInvocationList.Length > 0)) Then
' RaiseEvent ProcessListChangedNames(CStr(e.UserState).Split(","c))
' End If
' ElseIf e.ProgressPercentage = 3 Then
' If ((Not ProcessListChangedTitlesEvent Is Nothing) AndAlso (ProcessListChangedTitlesEvent.GetInvocationList.Length > 0)) Then
' RaiseEvent ProcessListChangedTitles(CStr(e.UserState).Split(","c))
' End If
' End If
'End Sub
Public Sub New(Optional ByVal Names As System.Collections.ArrayList = Nothing, Optional ByVal Titles As System.Collections.ArrayList = Nothing)
If Not Names Is Nothing Then ProcessNames = Names
If Not Titles Is Nothing Then ProcessTitles = Titles
bwCheckProcesses.WorkerReportsProgress = True
bwCheckProcesses.WorkerSupportsCancellation = True
bwCheckProcesses.RunWorkerAsync()
End Sub
Public Sub AddProcessName(ByVal name As String)
If Not ProcessNames.Contains(name) Then
ProcessNames.Add(name)
End If
End Sub
Public Sub RemoveProcessName(ByVal name As String)
If ProcessNames.Contains(name) Then
ProcessNames.Remove(name)
End If
End Sub
Public Sub AddProcessTitle(ByVal title As String)
If Not ProcessTitles.Contains(title) Then
ProcessTitles.Add(title)
End If
End Sub
Public Sub RemoveProcessTitle(ByVal title As String)
If ProcessTitles.Contains(title) Then
ProcessTitles.Remove(title)
End If
End Sub
Default Public ReadOnly Property process(ByVal index As Integer) As Process
Get
Dim result As Process = Nothing
If index >= 0 AndAlso index < ProcessList.Count Then
Try
result = DirectCast(ProcessList.GetByIndex(index), Process)
Catch ex As Exception
Debug.WriteLine(ex.ToString)
End Try
End If
Return result
End Get
End Property
Public ReadOnly Property length() As Integer
Get
Return ProcessList.Count
End Get
End Property
End Class
|
By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.
If a file you wish to view isn't highlighted, and is a text file (not binary), please
let us know and we'll add colourisation support for it.
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.