c # - proces træ

Indlæg af Hanne Mølgaard Plasc

Problem



Jeg søger en nem måde at finde proces træet på (som vist med værktøjer som Process Explorer), i C # eller andet. Net-sprog. Det ville også være nyttigt at finde kommandolinjeparametrene for en anden proces (StartInfo på System.Diagnostics.Process virker ugyldigt for anden proces end den aktuelle proces).


Jeg tror, ​​at disse ting kun kan gøres ved at påberåbe win32 api, men jeg vil være glad for at blive vist forkert.


Tak!


Robert

Bedste reference


Hvis du ikke vil P/Invoke, kan du få fat i de overordnede id'er med en performance counter:


foreach (var p in Process.GetProcesses())
{
   var performanceCounter = new PerformanceCounter("Process", "Creating Process ID", p.ProcessName);
   var parent = GetProcessIdIfStillRunning((int)performanceCounter.RawValue);
   Console.WriteLine(" Process {0}(pid {1} was started by Process {2}(Pid {3})",
              p.ProcessName, p.Id, parent.ProcessName, parent.ProcessId );
}

//Below is helper stuff to deal with exceptions from 
//looking-up no-longer existing parent processes:

struct MyProcInfo
{
    public int ProcessId;
    public string ProcessName;
}

static MyProcInfo GetProcessIdIfStillRunning(int pid)
{
    try
    {
        var p = Process.GetProcessById(pid);
        return new MyProcInfo() { ProcessId = p.Id, ProcessName = p.ProcessName };
    }
    catch (ArgumentException)
    {
        return new MyProcInfo() { ProcessId = -1, ProcessName = "No-longer existant process" };
    }
}


nu bare sætte det ind i hvad træstruktur vil have, og du er færdig.

Andre referencer 1


Du kan også forsøge at se WMI (Win32\_Process klasse for eksempel).


Her er et eksempel for at få kommandolinjen i en proces med dens proces id:


                using (var mos = new ManagementObjectSearcher(
                    "SELECT CommandLine FROM Win32\_Process WHERE ProcessId = " + pid))
                {
                    foreach (var obj in mos.Get())
                    {
                        object data = obj.Properties["CommandLine"].Value;
                        if (data != null)
                        {
                            Console.WriteLine("{0}: commandline = {1}", pid, data.ToString());
                        }
                    }
                }
            }
        }


Jeg har rippet det fra en kode, jeg har for nylig skrevet. Til dine formål kan du bruge andre teknikker (som at få flere egenskaber og/eller processer på én gang). Men du får ideen.


EDIT: Forældre proces id, som du skal bruge til at opbygge træet er for eksempel 'ParentProcessId' Ejendom.


Jeg gætter dog, at bruge Win32 API er hurtigere. Bemærk at ikke alle funktioner, du har brug for, også er med rette. For nogle ting vil du ty til den (noget) ikke understøttede NtQueryProcessInformation () -funktion eller andre fra NTDLL.

Andre referencer 2


Jeg ser ikke hvorfor du ikke vil p/påberåbe. Hvis du ser på System.Diagnostics in Reflector, ser du at den bruger p/invokes internt. I alle tilfælde har procesklassen ikke mulighed for at hente en proces 'forælder PID. I stedet:


Struktur definitionen:


[StructLayout(LayoutKind.Sequential)]
struct PROCESS\_BASIC\_INFORMATION
{
    public int ExitStatus;
    public int PebBaseAddress;
    public int AffinityMask;
    public int BasePriority;
    public int UniqueProcessId;
    public int InheritedFromUniqueProcessId;
}


Den (forenklede) funktion import:


[DllImport("ntdll.dll")]
static extern int NtQueryInformationProcess(
    IntPtr ProcessHandle,
    int ProcessInformationClass,
    out PROCESS\_BASIC\_INFORMATION ProcessInformation,
    int ProcessInformationLength,
    out int ReturnLength
    );


Koden:


Process p = Process.GetProcessById(1234);
PROCESS\_BASIC\_INFORMATION pbi;
int size;

NtQueryInformationProcess(p.Handle, 0, out pbi, Marshal.SizeOf(typeof(PROCESS\_BASIC\_INFORMATION)), out size);
// pbi.InheritedFromUniqueProcessId now contains the process' parent PID


Du skal indsætte disse brugsanvisninger øverst i din fil:


using System.Runtime.InteropServices;
using System.Diagnostics;


Hvis du vil opregne processer, vil du være bedre ved at bruge NtQuerySystemInformation - selv om den kode er lidt for lang til at skrive her.

Andre referencer 3


Jeg er ganske sikker på at du skal bruge WinAPI til dette. Se dette kodestykke som et eksempel. Det vil være en ret standard algoritme at opbygge et træ fra en liste over objekter og deres overordnede objekter. [7]