在vb.net上停止完整的进程树

时间:2014-04-20 17:51:38

标签: vb.net algorithm process

我已经编写了这个简单的算法来停止来自vb.net的完整流程树:

Private Sub TerminateProcessTree2(P As Process)
    Dim Tree = GenerateProcessTree(P)
    For Each childproc As Process In Tree
        Try
            If childproc.HasExited = False Then childproc.Kill()
        Catch ex As Exception
            AddError("Could not delete process " & childproc.ProcessName & ". " & ex.Message)
        End Try
    Next
    Dim pName As String = "<unknown>"
    Try
        If P IsNot Nothing Then
            pName = P.ProcessName
            If P.HasExited = False Then P.Kill()
        End If
    Catch ex As Exception
        AddError("Error killing process " & pName & ". " & ex.Message)
    End Try

End Sub

Function GenerateProcessTree(p As Process) As Collections.Generic.HashSet(Of Process)
    Dim hash As New Collections.Generic.HashSet(Of Process)
    GenerateProcessTreeNode(p, hash)
    Return hash
End Function

Private Sub GenerateProcessTreeNode(parent As Process, hash As Collections.Generic.HashSet(Of Process))
    Dim searcher As New ManagementObjectSearcher("Select * From Win32_Process Where ParentProcessID=" & parent.Id)
    Dim moc As ManagementObjectCollection = searcher.[Get]()
    For Each mo As ManagementObject In moc
        Dim i As Integer = CInt(mo("ProcessID"))
        Dim childP As Process
        Try
            childP = Process.GetProcessById(i)
            If childP IsNot Nothing AndAlso hash.Contains(childP) = False Then
                hash.Add(childP)
                GenerateProcessTreeNode(childP, hash)
            End If
        Catch ex As Exception
            AddError("Could not get process ID for " & mo.ToString)
            Continue For
        End Try
    Next
End Sub

但是,我的一些程序用户告诉我,每隔一段时间(比如1%或2%),该算法会关闭所有进程,而不仅仅是来自给定进程的子进程。这怎么可能?并且有什么需要从算法中修复?我想有最简单的方法可以做到这一点,但我想知道为什么会失败。

1 个答案:

答案 0 :(得分:0)

您的代码按预期工作且正确无误。由于WMI property ParentProcessId,IMO出现问题。 MSDN说:

ParentProcessId

Data type: uint32
Access type: Read-only

Unique identifier of the process that creates a process. 
Process identifier numbers are reused, so they only identify
a process for the lifetime of that process. It is possible that
the process identified by ParentProcessId is terminated, so 
ParentProcessId may not refer to a running process. It is also 
possible that ParentProcessId incorrectly refers to a process 
that reuses a process identifier. You can use the CreationDate 
property to determine whether the specified parent was created
after the process represented by this Win32_Process instance 
was created.

我假设您的 HashSet 在某个时刻持有,而且系统使用新流程和新流程替换子进程不再存在但仍在集合中,并在从列表中获取时终止。

您可以广泛记录process.Kill()的每个调用(名称,进程ID,时间戳等),然后尝试使用日志跟踪问题。