Problem beim Abrufen von Informationen zum Ausführen von Prozessen mit .GetProcesses () in Unity3D unter OS X.


7

Ich wollte dies bei Unity Answers nachfragen, aber es wird immer wieder ein Fehler angezeigt, wenn ich versuche, auf die Website zu gelangen. Ich dachte also, ihr könntet vielleicht helfen. Ich habe auch den Unity3d-Subreddit ausprobiert und es auch dort nicht geschafft, ihn zu lösen.

Ich versuche, eine Liste aller auf meinem Mac ausgeführten Prozesse von meiner Unity-Anwendung abzurufen. Die letzte Idee besteht darin, zu überprüfen, ob bestimmte Anwendungen ausgeführt werden (z. B. TextEdit).

Ich habe zuerst versucht, mit GetProcessByName nach einer offenen Anwendung zu suchen, habe aber diese Ausnahme erhalten, obwohl der Prozess ausgeführt wird :

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

Dann habe ich beschlossen, so einfach wie möglich zu gehen. Ich dachte, ich würde einfach eine Liste aller laufenden Prozesse ausdrucken, um damit zu beginnen. Hier ist mein 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!");
        }
    }

Wenn ich dies durch den Editor starte, sehe ich Folgendes:

Die Anzahl der ausgeführten Prozesse schwankt tendenziell um die 200er Jahre, aber der einzige Prozessname, der auf dem Bildschirm gedruckt wird, ist Unity.

Wenn ich versuche, alle Prozesse durch Entfernen der HasExited if-Anweisung zu drucken , wird dies angezeigt (natürlich passen nicht alle auf den Bildschirm):

Was mich denken lässt, dass es denkt, dass jeder Prozess außer Unity beendet wurde ... aber ich habe einige nicht abgeschlossene Prozesse ausgeführt, also frage ich mich, warum diese nicht aufgelistet werden? Grundsätzlich muss ich alle aktuell laufenden Prozesse durchsuchen . Irgendwelche Ideen? Gibt es ein Berechtigungsproblem, wenn nicht auf Eigenschaften externer Nicht-Unity-Prozesse zugegriffen werden kann?

EDIT: Ich sollte beachten, dass ich dies sowohl beim Durchlaufen des Editors als auch nach dem Erstellen versucht habe. Beim Ausführen nach dem Erstellen mit! Process.HasExited wird ein Prozess mit einem leeren Namen aufgelistet. Ich denke, das könnte die aktuell laufende Anwendung sein. Die Prozessanzahl liegt bei 240.


2 Dinge: 1) Was versuchst du zu finden? 2) Möglicherweise stoßen
Kirbinator

@Kirbinator Es scheint, dass dies nur für den Web-Player gilt.
Vaughan Hilts

Antworten:


3

Die Ausnahmemeldungen sind etwas irreführend. Tatsächlich meldet Mono dieselbe Ausnahme (ungültiger Vorgang) mit unterschiedlichen Meldungen für verschiedene Situationen.

GetProcesses ruft eine Liste aller Pids vom System ab und erstellt für jedes ein neues Process-Objekt. Zu diesem Zeitpunkt wird jedoch nicht überprüft, ob sie tatsächlich gültig sind. Wenn Sie ProcessName für ein Process-Objekt aufrufen, wird Folgendes ausgeführt:

  1. Überprüfen Sie, ob der Prozess eine gültige PID hat. Wenn nicht, wirft es.
  2. Versuchen Sie, den Prozessnamen von der PID abzurufen. Wenn es einen Nullwert zurückerhält, wird geworfen.

Beachten Sie, dass zu keinem Zeitpunkt tatsächlich geprüft wird, ob der Prozess beendet wurde oder nicht. Das HasExited-Flag wird nur gesetzt, wenn Sie es überprüfen, und ProcessName löst dies nicht aus. Das Verwirrende ist, dass es Ausnahmen gibt, die besagen, dass der Prozess beendet wurde, wenn dies nicht der Fall ist. Vertrauen Sie den Nachrichten also nicht zu sehr.

Sie können die Logik von Unitys Mono-Repo auf Github überprüfen .

Wenn Sie auf mehrere Eigenschaften von Prozessen in Ihrem Process [] -Array zugreifen müssen und / oder wissen möchten, wie viele gültige Prozesse vorhanden sind, sollten Sie das Array vorverarbeiten und die gewünschten Eigenschaften in ein eigenes Array extrahieren, um die Eigenschaften zu minimieren Anzahl der Ausnahmen, die Sie wahrscheinlich auslösen und vom eigentlichen Zeichnungscode trennen, etwa:

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 {}
}
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.