我已经编写了这个简单的算法来停止来自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%),该算法会关闭所有进程,而不仅仅是来自给定进程的子进程。这怎么可能?并且有什么需要从算法中修复?我想有最简单的方法可以做到这一点,但我想知道为什么会失败。
答案 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,时间戳等),然后尝试使用日志跟踪问题。