2010-03-24 77 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; 
}