7
\$\begingroup\$

I was going to ask this on Unity Answers, but I keep getting an error when trying to get to the site so thought maybe you guys could help. I've also tried the Unity3d subreddit and didn't manage to solve this there either.

I am attempting to get a list of all running processes on my Mac from my Unity application. The final idea is to check if certain applications are running (eg, TextEdit).

I first tried checking for an open application with GetProcessByName, but got this exception even though the process is running:

InvalidOperationException: Process has exited, so the requested information is not available.

Then I decided to go as simple as possible. I figured I'd just print out a list of all running processes to start off with. Here's my code:

    Process[] processes = Process.GetProcesses();
    GUI.Label( new Rect(x, y, 100, 20), "Process: " + processes.Length );
    y += 20; 
    foreach (Process process in processes) {
        try
        {
            if (!process.HasExited)
            {
                GUI.Label( new Rect(x, y, 100, 20), "process: " + process.ProcessName );
                y += 20;
            }
        }
        catch (System.InvalidOperationException)
        {
            UnityEngine.Debug.Log("Holy batman we've got an exception!");
        }
    }

When I run this through the editor, here's what I see:

The number of running processes tends to fluctuate around the 200s, but the only process name being printed on screen is Unity.

If I try to print all processes by removing the HasExited if statement I get this (of course they don't all fit on the screen):

Which makes me think that it thinks every process except for Unity has exited...but I have quite a few unterminated processes running, so I wonder why it's not listing those? Basically I need to search through all currently running processes. Any ideas? Is there some sort of permission issue with not being able to access properties of external non-Unity processes?

EDIT: I should note that I've tried this both while running through the editor and after building. When run after building with !process.HasExited one process is listed with a blank name. I guess that might be the currently running application. The process count hovers around 240.

\$\endgroup\$
3
\$\begingroup\$

The exception messages are a bit misleading. In fact, Mono reports the same exception (Invalid Operation) with different messages for a variety of different situations.

GetProcesses gets a list of all pids from the system and creates a new Process object for each one, but at this point it doesn't check if they're actually valid. When you call ProcessName on a Process object, it will:

  1. Check if the Process has a valid pid. If not, it throws.
  2. Try to get the process name from the pid. If it gets a null value back, it throws.

Notice that at no point is it actually checking if the process has exited or not. The HasExited flag only gets set when you check it, and ProcessName doesn't trigger that. The confusing bit is that there are exceptions that get thrown saying the process has exited when it's not the case, so don't trust the messages too much.

You can check the logic on Unity's Mono repo on github.

If you need to access multiple properties on processes in your Process[] array and/or you want to know how many valid processes there are, you should preprocess the array and extract the properties you want into an array of your own, to minimize the amount of exceptions you're likely to trigger and split that code from the actual drawing code, something like:

var procList = Process.GetProcesses();
var validProcesses = new List<Proc>();
for (int i = 0; i < procList.Length; i++) {
    try {
        validProcesses.Add(new Proc(){
            Name = procList[i].ProcessName,
            Pid = procList[i].Id
        });
    } catch {}
}
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.