C # / mono: получить список дочерних процессов в Windows и Linux - PullRequest
3 голосов
/ 24 марта 2010

У меня есть код ниже для получения списка дочерних процессов в Windows путем взаимодействия с ntdll. Есть ли в Linux эквивалент NtQueryInformationProcess, который дает мне идентификатор процесса родителя указанного процесса (например, pbi.InheritedFromUniqueProcessId)? Мне нужен код для запуска в Linux через Mono, поэтому я надеюсь, что мне нужно изменить только часть, в которой я получаю идентификатор родительского процесса, чтобы код оставался в основном таким же, как в 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;
    }

Ответы [ 2 ]

4 голосов
/ 24 марта 2010

Один из способов найти всех потомков данного процесса в 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 вокруг «using», потому что процесс может прекратиться до того, как мы откроем файл, и т. Д ...

0 голосов
/ 09 мая 2013

На самом деле, существует проблема с ответом Гонсало, если в имени процесса есть пробелы. Этот код работает для меня:

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