Мониторинг процессов и дочерних процессов VB - PullRequest
0 голосов
/ 09 февраля 2020

Я создаю программу, которая должна отслеживать все дочерние процессы после начального.

Я делаю это с помощью функции ProcessExtensions.GetProcess из расширений процессов, таких как:

        Dim counter
        counter = 0

        Dim pr2 = ProcessExtensions.GetProcesses.ToList()
        Console.WriteLine(pr2.Count)
        For Each pr3 As Process In pr2
            counter = counter + 1
            Dim parentpr As Process = ProcessExtensions.Parent(pr3)  '' <- problem right here
               If parentpr IsNot Nothing Then
                   Console.WriteLine(counter & "  " & pr3.Id & "   " & pr3.ProcessName & "  " & pr3.StartTime & "   " & parentpr.Id)
               End If
        Next
        Console.ReadKey()

Проблема в том, что это слишком медленно, проверка каждого процесса на windows 10 занимает около полсекунды, а в среднем более 200 процессов не позволяют мне проверить, был ли дочерний процесс запущен эффективно .

Я рассмотрел вопрос о создании фильтра с датой начала, но этот фильтр также будет проходить через все процессы oop и не даст достаточно быстрого результата.

Между тем tasklist или wmic process get в командной строке дают мгновенные результаты, но заставит меня переписать весь код.

Можно ли отслеживать моментальный запуск процесса на windows 10, мгновенно ?

Приветствуются и другие идеи.

Я новичок в VB, заранее благодарю за любую помощь.

Редактировать: Проблема в получении ParentID. Я использую пользовательский модуль ProcessExtensions, который получает его, но он немного медленный.

Public NotInheritable Class ProcessExtensions
    Inherits Process
    Public Sub New()
    End Sub
    Private Shared Function FindIndexedProcessName(ByVal pid As Integer) As String
        Try
            Dim processName = Process.GetProcessById(pid).ProcessName
            Dim processesByName = Process.GetProcessesByName(processName)
            Dim processIndexdName As String = Nothing

            For index As Integer = 0 To processesByName.Length - 1
                processIndexdName = If(index = 0, processName, Convert.ToString(processName) & "#" & index)
                Dim processId = New PerformanceCounter("Process", "ID Process", processIndexdName)
                If CInt(processId.NextValue()).Equals(pid) Then
                    Return processIndexdName
                End If
            Next

            Return processIndexdName
        Catch ex As ArgumentException
            Return Nothing
        End Try

    End Function

    Private Shared Function FindPidFromIndexedProcessName(ByVal indexedProcessName As String) As Process
        Dim parentId = New PerformanceCounter("Process", "Creating Process ID", indexedProcessName)
        Try
            Return Process.GetProcessById(CInt(parentId.NextValue()))
        Catch ex As Exception
            Return Nothing
        End Try

    End Function

    Public Function Parent() As Process
        Return FindPidFromIndexedProcessName(FindIndexedProcessName(Me.Id))
    End Function

    Public Shared Function Parent(ByVal pr As Process) As Process
        Return FindPidFromIndexedProcessName(FindIndexedProcessName(pr.Id))
    End Function

End Class

1 Ответ

1 голос
/ 09 февраля 2020

Я произвел рефакторинг некоторых частей вашего кода и создал многопоточный пример для вас. в моей системе у меня было

0,100 мс время выполнения до рефакторинга

0,086 мс после рефакторинга

0,020 мс с использованием нескольких потоков.


Sub Main

    Dim sw = New Stopwatch()
    sw.Start()
    ' you should await this task -> await StartMonitoring
    StartMonitoring().GetAwaiter().GetResult()
    sw.Stop()
    Console.WriteLine($"Done in {sw.ElapsedMilliseconds} ms.")
End Sub

Public Async Function StartMonitoring() As Task
    Dim pr2 = ProcessExtensions.GetProcesses.ToList()
    Console.WriteLine(pr2.Count)
    Dim counter = 0
    Dim taskList = New List(Of Task)
    For Each pr3 As Process In pr2
        taskList.Add(CreateTask(pr3, counter))
        counter = counter + 1
    Next
    Await Task.WhenAll(taskList)
End Function

Public  Function CreateTask(pr As Process ,counter As Integer) As Task 
    Return Task.Run(
        Sub()
            Dim parentpr As Process = ProcessExtensions.Parent(pr)
            If parentpr IsNot Nothing Then
                Console.WriteLine(counter & "  " & pr.Id & "   " & pr.ProcessName & "  " & parentpr.Id & " "  & Thread.CurrentThread.ManagedThreadId)
            End If
        End Sub)
End Function


Public NotInheritable Class ProcessExtensions
    Inherits Process

    Public Sub New()
    End Sub

    Private Shared Function FindIndexedProcessName(pr As Process) As String
        Try
            Dim processName = pr.ProcessName
            Dim childProcesses = Process.GetProcessesByName(processName) 
            Dim processIndexdName As String = Nothing

            For index As Integer = 0 To childProcesses.Length - 1
                processIndexdName = If(index = 0, processName,  processName & "#" & index)
                Dim processId = New PerformanceCounter("Process", "ID Process", processIndexdName)
                If CInt(processId.NextValue()).Equals(pr.Id) Then
                    Return processIndexdName
                End If
            Next
            Return processIndexdName
        Catch ex As Exception
            Return Nothing
        End Try

    End Function

    Private Shared Function FindPidFromIndexedProcessName(ByVal indexedProcessName As String) As Process
        Dim parentId = New PerformanceCounter("Process", "Creating Process ID", indexedProcessName)
        Try
            Return Process.GetProcessById(CInt(parentId.NextValue()))
        Catch ex As Exception
            Return Nothing
        End Try

    End Function

    Public Function Parent() As Process
        Return FindPidFromIndexedProcessName(FindIndexedProcessName(Me))
    End Function

    Public Shared Function Parent(ByVal pr As Process) As Process
        Return FindPidFromIndexedProcessName(FindIndexedProcessName(pr))
    End Function

End Class

надеюсь, это даст вам некоторое представление о том, как можно улучшить эту функцию.

...