简体   繁体   English

C#/ mono:获取Windows和Linux上的子进程列表

[英]C#/mono: get list of child processes on Windows and Linux

I have the code below for getting a list of child processes on windows by interop'ing with ntdll. 我有以下代码,通过与ntdll交互来获取Windows上的子进程列表。 Is there an equivalent to 'NtQueryInformationProcess' on Linux, which get's me the process id of the parent of a specified process (like pbi.InheritedFromUniqueProcessId)? 在Linux上是否有等效的'NtQueryInformationProcess',它是我指定进程的父进程的进程ID(如pbi.InheritedFromUniqueProcessId)? I need the code to run on Linux through Mono so hopefully I am hoping I need to change only the part where I get the parent process ID so the code stays mostly the same as on Windows. 我需要通过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;
    }

One way of finding all the children of a given process in Linux is to do something like this inside your foreach : 在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
    }
}

For more information on what /proc/[id]/stat contains, see the manual page for 'proc'. 有关/ proc / [id] / stat包含的更多信息,请参阅'proc'的手册页。 You should also add a try/catch around the 'using' because the process might die before we open the file, etc... 你还应该在'using'周围添加一个try / catch,因为在打开文件之前进程可能会死掉,等等......

Actually, there is an issue with Gonzalo's answer, if the process name has spaces in it. 实际上,如果进程名称中包含空格,则Gonzalo的答案存在问题。 This code works for me: 这段代码适合我:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM