0

我正在使用 ManagementEventWatcher 在进程启动和停止时获取消息。当文字处理启动时,我成功收到消息,它显示文件名和日期时间。我在停止进程时遇到问题。

Public Class Form1
    Dim list As New List(Of String)
    Dim list1 As New List(Of String)
    Private processStartEvent As ManagementEventWatcher = New ManagementEventWatcher("SELECT * FROM Win32_ProcessStartTrace")
    Private processStopEvent As ManagementEventWatcher = New ManagementEventWatcher("SELECT * FROM Win32_ProcessStopTrace")

    Public Sub New()
        InitializeComponent()
        AddHandler processStartEvent.EventArrived, New EventArrivedEventHandler(AddressOf processStartEvent_EventArrived)
        processStartEvent.Start()
        AddHandler processStopEvent.EventArrived, New EventArrivedEventHandler(AddressOf processStopEvent_EventArrived)
        processStopEvent.Start()
    End Sub

    Private Sub processStartEvent_EventArrived(ByVal sender As Object, ByVal e As EventArrivedEventArgs)
        Dim allProcesses = Process.GetProcesses().Where(Function(p) p.ProcessName.Contains("WINWORD"))
        Dim windowTitles = ChildWindowManager.GetChildWindowTitles(allProcesses.First().Id)
        For Each title In windowTitles
            If (title.Contains("- Word")) Then
                If Not (title.Contains("Opening - Word")) Then
                    If Not list.Contains(title) Then
                        list.Add(title)
                        MessageBox.Show("+ Process Started. File Name: " & String.Join(",", list.Item(list.Count - 1)) & " | Date & Time: " & System.DateTime.Now.ToString("dd/MM/yyyy HH:mm:ss") & vbNewLine & vbNewLine)
                    End If
                End If
            End If
        Next
    End Sub

    Private Sub processStopEvent_EventArrived(ByVal sender As Object, ByVal e As EventArrivedEventArgs)

    End Sub
End Class

Class ChildWindowManager
    Delegate Function EnumThreadDelegate(ByVal hWnd As IntPtr, ByVal lParam As IntPtr) As Boolean

    <DllImport("user32.dll")>
    Private Shared Function EnumThreadWindows(ByVal dwThreadId As Integer, ByVal lpfn As EnumThreadDelegate, ByVal lParam As IntPtr) As Boolean
    End Function

    <DllImport("user32.dll")>
    Public Shared Function GetWindowText(ByVal hwnd As Integer, ByVal lpString As System.Text.StringBuilder, ByVal cch As Integer) As Integer
    End Function

    <DllImport("user32.dll")>
    Private Shared Function GetWindowTextLength(ByVal hwnd As IntPtr) As Integer
    End Function

    Private Shared Function EnumerateProcessWindowHandles(ByVal processId As Integer) As List(Of IntPtr)
        Dim windowHandles = New List(Of IntPtr)()

        For Each thread As ProcessThread In Process.GetProcessById(processId).Threads
            EnumThreadWindows(thread.Id, Function(hWnd, lParam)
                                             windowHandles.Add(hWnd)
                                             Return True
                                         End Function, IntPtr.Zero)
        Next
        Return windowHandles
    End Function

    Private Shared Function GetWindowTitle(ByVal hWnd As IntPtr) As String
        Dim length As Integer = GetWindowTextLength(hWnd)
        If length = 0 Then Return Nothing

        Dim titleStringBuilder As New System.Text.StringBuilder("", length)

        GetWindowText(hWnd, titleStringBuilder, titleStringBuilder.Capacity + 1)
        Return titleStringBuilder.ToString()
    End Function

    Public Shared Function GetChildWindowTitles(processId As Integer) As List(Of String)
        Dim windowTitles As New List(Of String)

        For Each Handle In EnumerateProcessWindowHandles(processId)
            Dim windowText = GetWindowTitle(Handle)
            If windowText <> Nothing Then
                windowTitles.Add(windowText)
            End If
        Next

        Return windowTitles
    End Function
End Class
4

0 回答 0