Joey Powell
Joey Powell

Reputation: 89

How to detect if a process is running for the current logged-in user?

Environment - C#, .net 4.0, VS 2010

Hello, I have written a simple shell replacement for Windows. The shell is launched automatically when users log in. The normal Windows "explorer.exe" is launched when users exit my shell.

Now, when users exit (and to properly support this) I need to be able to check if "explorer.exe" is running for the current logged-in user. This prevents the code from unnecessarily launching it again, which results in a "Windows Explorer" application window.

I have seen countless examples of how to check and see if a process is running...but none to see if it is running for the current logged-in user.

The code below will check to see if "explorer.exe" is already running and will start it if it isn't. But there are situations when this code will test positive when it doesn't need to!

For example, when using fast-user switching...Another user is logged in to the machine and, as a result, "explorer.exe" shows in the process list. But, while "explorer.exe" is running, it is NOT running for the current logged-in user! So when my shell exits, the code tests positive, and "explorer.exe" is not launched. The user is left with a black screen and no shell!

So, how can I mod the code below to test if "explorer.exe" is running for the current logged-in user?

Process[] Processes = Process.GetProcessesByName("explorer");
if (Processes.Length == 0)
{
   string ExplorerShell = string.Format("{0}\\{1}", Environment.GetEnvironmentVariable("WINDIR"), "explorer.exe");
   System.Diagnostics.Process prcExplorerShell = new System.Diagnostics.Process();
   prcExplorerShell.StartInfo.FileName = ExplorerShell;
   prcExplorerShell.StartInfo.UseShellExecute = true;
   prcExplorerShell.Start();
}

Upvotes: 4

Views: 6959

Answers (1)

Antonio Bakula
Antonio Bakula

Reputation: 20693

You could get SessionID from your process and then query Processes and get Explorer instance that have the same SessionID, let's say that your program is named "NewShell" :

  Process myProc = Process.GetProcesses().FirstOrDefault(pp => pp.ProcessName.StartsWith("NewShell"));
  Process myExplorer = Process.GetProcesses().FirstOrDefault(pp => pp.ProcessName == "explorer" && pp.SessionId == myProc.SessionId);

  if (myExplorer == null)
    StartExplorer()

btw. if you use ProcessName.StartsWith("NewShell") instead of ProcessName == "NewShell" then it will work under VS debugger also (it adds vshost to the exe)

Upvotes: 3

Related Questions