2010-03-24 81 views
3

我有下面的代码,通过与ntdll互操作获取Windows上的子进程列表。在Linux上有没有等同于'NtQueryInformationProcess',它是我的指定进程的父进程ID(如pbi.InheritedFromUniqueProcessId)?我需要通过Mono在Linux上运行代码,所以希望我希望只需要更改获取父进程ID的部分,以便代码保持与Windows上的大致相同。发现在Linux的特定过程的所有孩子的C#/ mono:获取Windows和Linux上的子进程列表

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

一种方法是做你的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,因为在我们打开文件之前这个过程可能会死亡,等等......

+0

谢谢!从来没有想到/ proc文件系统!我只是在寻找系统调用,但这个解决方案同样好。 – johnrl 2010-03-24 17:15:00

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