【问题标题】:Monitor processes and child processes vb监控进程和子进程 vb
【发布时间】:2020-02-09 16:41:35
【问题描述】:

我正在创建一个程序,该程序应在初始子进程之后监视所有子进程。

我正在使用来自流程扩展的 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 个进程,它不允许我检查子进程是否有效启动。

我考虑过创建一个带有开始日期的过滤器,但该过滤器也会循环遍历所有进程,并且无法足够快地提供结果。

同时tasklistwmic 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

【问题讨论】:

  • 我认为您正在使用自定义 ProcessExtensions 模块。你也应该添加它。
  • 只写这段代码Dim pr = ProcessExtensions.GetProcesses.ToList()需要多长时间?
  • 我问是因为我认为你的问题不在于获取进程列表只是想确保
  • 也许您想测试 WMI 的 Win32_Process。查询被缓存。
  • 请检查一下:Dim x = Process.GetProcesses.ToList() 或者简单地说这应该可以工作dim x = Process.GetProcesses

标签: vb.net process windows-10-desktop


【解决方案1】:

我重构了您的部分代码并为您创建了一个多线程示例。在我的系统中,我有

0.100ms重构前的执行时间

0.086ms重构后

0.020ms 使用多个线程。


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

希望它能让您了解如何改进此功能。

【讨论】:

  • 嗨 Ali,只是一个小修复,在函数 CheckParent 上,对于 vb.net 应该是 Dim tsk = Task.Factory.StartNew(。另外,您能否指出您如何以及在哪里测量代码运行所需的时间?我的意思是你是如何找到毫秒值的?
  • 您可以使用秒表来检查您的执行时间。 docs.microsoft.com/en-us/dotnet/api/…
  • @CésarAmorim 我仔细检查了我的答案,发现我在等待结果时犯了一个错误。对于那个很抱歉。检查这个我解决了这个问题。
  • 另外,我添加了秒表来测量执行时间。
  • 如果你想知道我为什么使用Task.Runstackoverflow.com/questions/38423472/…,可以查看这个链接
猜你喜欢
  • 2013-07-29
  • 2023-03-24
  • 1970-01-01
  • 2015-08-27
  • 1970-01-01
  • 2011-07-07
  • 2021-10-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多