3

我有下面的代码,用于通过与 ntdll 互操作来获取 Windows 上的子进程列表。在 Linux 上是否有等效于“NtQueryInformationProcess”的方法,它可以让我获得指定进程的父进程的进程 ID(如 pbi.InheritedFromUniqueProcessId)?我需要代码通过 Mono 在 Linux 上运行,所以希望我只需要更改获取父进程 ID 的部分,以便代码与 Windows 上的代码基本相同。

public IList< Process > GetChildren( Process parent )
    {
        List< Process > children = new List< Process >();

        Process[] processes = Process.GetProcesses();
        foreach (Process p in processes)
        {
            ProcessBasicInformation pbi = new ProcessBasicInformation();
            try
            {
                uint bytesWritten;
                NtQueryInformationProcess(p.Handle,
                  0, ref pbi, (uint)Marshal.SizeOf(pbi),
                  out bytesWritten); // == 0 is OK

                if (pbi.InheritedFromUniqueProcessId == parent.Id)
                    children.AddRange(GetChildren(p));
            }
            catch
            {
            }
        }

        return children;
    }
4

2 回答 2

4

在 Linux 中查找给定进程的所有子进程的一种方法是在您的foreach中执行以下操作:

string line;
using (StreamReader reader = new StreamReader ("/proc/" + p.Id + "/stat")) {
      line = reader.ReadLine ();
}
string [] parts = line.Split (new char [] {' '}, 5); // Only interested in field at position 3
if (parts.Legth >= 4) {
    int ppid = Int32.Parse (parts [3]);
    if (ppid == parent.Id) {
         // Found a children
    }
}

有关 /proc/[id]/stat 所包含内容的更多信息,请参阅“proc”的手册页。您还应该在“使用”周围添加一个 try/catch,因为在我们打开文件之前进程可能会死,等等......

于 2010-03-24T16:53:54.790 回答
0

实际上,如果进程名称中有空格,那么 Gonzalo 的回答存在问题。这段代码对我有用:

public static int GetParentProcessId(int processId)
{
    string line;
    using (StreamReader reader = new StreamReader ("/proc/" + processId + "/stat"))
          line = reader.ReadLine ();

    int endOfName = line.LastIndexOf(')');
    string [] parts = line.Substring(endOfName).Split (new char [] {' '}, 4);

    if (parts.Length >= 3) 
    {
        int ppid = Int32.Parse (parts [2]);
        return ppid;
    }

    return -1;
}
于 2013-05-09T13:36:58.507 回答