【问题标题】:Find all child processes of my own .NET process / find out if a given process is a child of my own?查找我自己的 .NET 进程的所有子进程/找出给定进程是否是我自己的子进程?
【发布时间】:2011-08-25 10:52:27
【问题描述】:

我有一个 .NET 类库,它启动了一个辅助进程,该进程一直运行直到我处理掉对象。

由于某些程序会在内存中逗留,我决定添加一个集成测试,以确保如果我让对象进入 GC/Finalization,该过程会被停止。

但是,由于该进程是 Mercurial 命令行客户端,并且我的构建服务器已经在运行 Mercurial 作为其自身操作的一部分,因此我设想在测试开始时 Mercurial 已经在运行或者它已启动的情况,并且在测试完成时仍在运行,与构建服务器相关,而不是我的测试。

所以,我想确保我找到(或不是)的 Mercurial 客户端是我启动的那个客户端,而不仅仅是当前正在运行的任何客户端。

所以问题是这样的:

  • 如何确定我正在查看的 Mercurial 客户端是否由我的进程启动?

通过“查看”,我正在查看使用Process.GetProcesses 方法,但这不是必需的。

如果另一个问题更好,“如何找到我自己进程的所有子进程”,即。更容易回答,一个也绰绰有余。

我找到了这个页面:How I can know the parent process ID of a process?,但似乎我必须给它进程名称。如果我只是给它“hg”,那么对于我正在寻找的案例来说,这个问题是不是太模棱两可了?

【问题讨论】:

    标签: .net process child-process


    【解决方案1】:

    碰巧我有一些 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();
                    }
                }
            }
        }
    

    【讨论】:

    • 这对我来说效果很好,尽管我采用了一种更简单的方法,使用 ManagementObject 而没有搜索器。我一直在努力杀死我的子进程,谢谢!
    • 需要 System.Management 程序集/参考
    【解决方案2】:

    虽然answer of mtijn 可能是你能得到的最接近的,但真正的答案是:你不能。

    Windows 不会维护一个真正的进程树,当中间级别的进程死亡时,进程会在其中重新构造。但是,Windows 确实会记住父进程 ID。

    有问题的情况如下:

    原流程结构:

    YourApp.exe
    - SubApp.exe
      - Second.exe
    

    如果现在 SubApp.exe 终止,则不会更新 Second.exe 的父进程 ID。新结果是

    YourApp.exe
    Second.exe
    

    您可以使用SysInternals Process Explorer 进行验证。它能够将进程显示为树。启动 CMD,然后键入 start cmd。在新窗口中,再次输入start cmd。您将打开 3 个窗口。现在终止中间那个。

    【讨论】:

    • 对于那些希望使用我的答案代码的人来说,这篇文章是对其局限性的公平警告,但最初的问题是关于嵌套最多 1 级深度的父进程和子进程,而不是 >1 级此处描述。
    【解决方案3】:

    谢谢!从以前的 KillAllProcessesSpawnedBy 答案我做了这个:

            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();
    
            }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-05-29
      • 1970-01-01
      • 2016-08-24
      • 2013-07-05
      • 1970-01-01
      相关资源
      最近更新 更多