查找我自己的.NET进程的所有子进程/查找给定进程是否是我自己的子进程?
我有一个.NET类库,它可以启动一个辅助进程,该进程将一直运行,直到我处理完对象为止 由于程序在内存中出现了一些延迟,我决定添加一个集成测试,以确保如果我让对象进入GC/终结,该过程将停止 但是,由于该进程是Mercurial命令行客户端,并且我的构建服务器已经在运行Mercurial作为其自身操作的一部分,因此我设想的情况是,Mercurial在测试启动时已经运行,或者在测试结束时,它已经启动,并且仍然在运行,与构建服务器相关,而不是我的测试 因此,我想确保我找到(或没有)的Mercurial客户机是我启动的客户机,而不仅仅是当前正在运行的任何客户机 所以问题是:查找我自己的.NET进程的所有子进程/查找给定进程是否是我自己的子进程?,.net,process,child-process,.net,Process,Child Process,我有一个.NET类库,它可以启动一个辅助进程,该进程将一直运行,直到我处理完对象为止 由于程序在内存中出现了一些延迟,我决定添加一个集成测试,以确保如果我让对象进入GC/终结,该过程将停止 但是,由于该进程是Mercurial命令行客户端,并且我的构建服务器已经在运行Mercurial作为其自身操作的一部分,因此我设想的情况是,Mercurial在测试启动时已经运行,或者在测试结束时,它已经启动,并且仍然在运行,与构建服务器相关,而不是我的测试 因此,我想确保我找到(或没有)的Mercurial
- 我如何才能确定我正在查看的Mercurial客户端是否是由我的流程启动的
我找到了这个页面:,但似乎我必须给它一个进程名。如果我只给它“hg”,这个问题对于我正在寻找的案例来说不是太模糊了吗?碰巧我有一点C#/WMI代码,它递归地杀死指定进程id生成的所有进程。杀戮显然不是你想要的,但是发现子进程似乎是你感兴趣的。我希望这会有所帮助:
private static void KillAllProcessesSpawnedBy(UInt32 parentProcessId)
{
logger.Debug("Finding processes spawned by process with Id [" + parentProcessId + "]");
// NOTE: Process Ids are reused!
ManagementObjectSearcher searcher = new ManagementObjectSearcher(
"SELECT * " +
"FROM Win32_Process " +
"WHERE ParentProcessId=" + parentProcessId);
ManagementObjectCollection collection = searcher.Get();
if (collection.Count > 0)
{
logger.Debug("Killing [" + collection.Count + "] processes spawned by process with Id [" + parentProcessId + "]");
foreach (var item in collection)
{
UInt32 childProcessId = (UInt32)item["ProcessId"];
if ((int)childProcessId != Process.GetCurrentProcess().Id)
{
KillAllProcessesSpawnedBy(childProcessId);
Process childProcess = Process.GetProcessById((int)childProcessId);
logger.Debug("Killing child process [" + childProcess.ProcessName + "] with Id [" + childProcessId + "]");
childProcess.Kill();
}
}
}
}
虽然这可能是你能得到的最接近的答案,但真正的答案是:你不能
Windows不维护真正的进程树,在该树中,当中间级别的进程死亡时,进程将被重新构造。但是,Windows确实记得父进程ID
有问题的情况如下:
原始流程结构:
YourApp.exe
- SubApp.exe
- Second.exe
如果现在SubApp.exe终止,则Second.exe的父进程ID将不会更新。新的结果是
YourApp.exe
Second.exe
您可以使用来验证这一点。它能够以树的形式显示流程。启动CMD,然后键入
Start CMD
。在新窗口中,再次键入start cmd
。您将打开3个窗口。现在终止中间的一个。谢谢!根据之前的KillAllProcessPawnedBy Answer,我做了以下几点:
public static void WaitForAllToExit(this Process process)
{
ManagementObjectSearcher searcher = new ManagementObjectSearcher(
"SELECT * " +
"FROM Win32_Process " +
"WHERE ParentProcessId=" + process.Id);
ManagementObjectCollection collection = searcher.Get();
if (collection.Count > 0)
{
foreach (var item in collection)
{
UInt32 childProcessId = (UInt32)item["ProcessId"];
if ((int)childProcessId != Process.GetCurrentProcess().Id)
{
Process childProcess = Process.GetProcessById((int)childProcessId);
WaitForAllToExit(childProcess);
}
}
}
process.WaitForExit();
}
这对我来说效果很好,尽管我使用
ManagementObject
和无搜索器来实现更简单的方法。我一直在努力终止我的子进程有一段时间了,谢谢!需要系统。管理程序集/参考这对我很有用,谢谢``对于那些希望使用我的答案代码的人来说,这篇文章是对其局限性的合理警告,然而最初的问题是关于嵌套在最多1层的父进程和子进程,而不是这里描述的>1层。