0

I am trying to print all running processes in C#, similarly to how tasklist or ps does. I tried it with the following code:

foreach(Process process in Process.GetProcesses()) {
    if(!process.HasExited) {
        Console.WriteLine(process.ProcessName);
    }
}

But with it, I run into some issues on Windows (did not try it on Linux):

  • When I execute the above code with user-privileges, it only prints processes started by this user. If I run it as administrator, all processes are printed.
  • When I open a cmd window with user privileges and list the processes (i.e. execute tasklist), all processes are printed, even those started by the system / by an administrator account.

Is there a way to get all processes, even those started by a higher privileged user, without requiring the program to be run as administrator?

One solution came to my mind:

System.Diagnostics.Process.Start("CMD.exe", "tasklist > C:\file.txt");
String[] processes = File.ReadAllLines(@"C:\file.txt");

But this is really hacky and does not work on linux.

plainerman
  • 435
  • 8
  • 18

2 Answers2

3

You can't. You can't let the same process run parts in elevated and in user mode. That's just the way they built it, mainly for security reasons. You can't just bypass it.

Enough about what you can't. What can you do? You could start a second (different) program that runs in elevated mode, or you could restart your current application when there is a section you need elevated privileges. You need Process.Start for this and you will have to set the ProcessStartInfo.Verb to "runas":

ProcessStartInfo startInfo = new ProcessStartInfo(exePath);
startInfo.Verb = "runas";

Process.Start(startInfo);
Patrick Hofman
  • 153,850
  • 22
  • 249
  • 325
0

After some testing I found out, that administrator processes will show in the Process.GetProcesses() list but the boolean HasExited of admin privileged processes is always true (even if it hasn't closed)

So I just looped through the list without checking for process.HasExited

foreach(Process process in Process.GetProcesses()) {
    if(!process.HasExited) { //running process with user privileges
        //do some stuff here
    }
    else { //closed process or administrator process
        //do some stuff here
    }
}

And for the case that the process has actually stopped, I wrap it inside a try-catch block.

As this solution does not seem optimal to me, I am leaving this question open.

plainerman
  • 435
  • 8
  • 18