Process tree

I am looking for an easy way to find a process tree (as shown by tools like Process Explorer) in C # or another .Net language. It would also be useful to find the command line arguments of another process (StartInfo on System.Diagnostics.Process seems invalid for a process other than the current process).

I think that these things can only be done by calling win32 api, but I would be happy if it turns out that this is wrong.

Thanks!

Robert

+3
source share
4 answers

If you don't want P / Invoke, you can grab the parent id with a 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" }; } } 

now just put it in any tree structure and you're done.

+4
source

You can also try learning WMI (for example, the Win32_Process class).

Here is an example to get the command line of a process by its process 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()); } } } } } 

I tore this up from some code I recently wrote. For your purposes, you can use other methods (for example, immediately get several properties and / or processes). But you have an idea.

EDIT: The parent process identifier that you will need to build the tree, for example, is the "ParentProcessId" property.

I assume that using the Win32 API is faster. Please note that not all the features you need are also available. For some things, you would resort to the (somewhat) unsupported function NtQueryProcessInformation () or another from NTDLL.

+2
source

I do not understand why you do not want p / invoke. If you look at System.Diagnostics in Reflector, you will see that it uses p / invokes inside. In any case, the Process class has no way of getting the parent PID of the process. Instead of this:

Structure Definition:

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

Import function (simplified):

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

Code:

 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 

You will need to insert these headers at the beginning of the file:

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

If you want to list processes, you would be better off using NtQuerySystemInformation - although this code is too long to post here.

+2
source

I am sure that for this you will need WinAPI. See this code snippet for an example. This will be a fairly standard algorithm for creating a tree from a list of objects and their parent objects.

0
source

Source: https://habr.com/ru/post/1286192/


All Articles