2009-09-08 32 views
5

Ich schreibe ein Framework für OS X, das von Anwendungen mit oder ohne Verbindung zum OS X WindowServer verwendet werden kann (d. H. Sowohl GUI-Apps als auch Befehlszeilen-Apps werden über eine ssh-Sitzung ausgeführt). Eine Klasse im Framework dient zum Verfolgen von Dateien im Home-Ordner des Benutzers über Netework- und Mobile-Home-Verzeichnisse (unter OS X können Benutzer ihr Home-Verzeichnis über AFP von einem Server - einem "Netzwerk-Home-Verzeichnis" - bedienen lassen oder die Gleicher Home-Ordner für den Offline-Zugriff synchronisiert - ein "Mobil Home-Verzeichnis").Ermitteln, ob WindowServer verfügbar ist?

Da ich Dateien über Dateisysteme hinweg verfolgen muss, haben wir relative Pfade anstatt OS X-Aliase (oder die 10.6 NSURL Lesezeichen) gewählt. Wenn eine Datei nicht gefunden werden kann, muss der Benutzer nach einer Eingabe gefragt werden, um die Datei zu verschieben (z. B. wie der Alias-Manager den Benutzer auffordert, einen ungültigen Alias ​​erneut zu verbinden). Wenn die Anwendung eine Verbindung zum WindowServer hat (oder herstellen kann), ist dies so einfach wie die Verwendung eines NSOpenPanel. Wenn die App jedoch keine Verbindung zum WindowServer herstellen kann, muss ich eine alternative Methode verwenden, um die Benutzereingabe zu erhalten.

Also, wie kann ich sagen, welche Methode aus dem Rahmenwerk-Code zu verwenden? Gibt es eine Möglichkeit, programmatisch festzustellen, ob eine WindowsServer-Verbindung verfügbar (oder möglich) ist?

Ich erkenne, dass eine alternative Architektur, in der der Framework-Client einen Callback-Mechanismus bereitstellt, um den Benutzer aufzufordern, die Eingabeerfassungsstrategie von der aufrufenden Anwendung zur Verfügung stellen würde. Ich möchte die Dinge für die aufrufende Anwendung jedoch so einfach wie möglich machen, also wäre meine erste Wahl, diese Details in das Framework zu kapseln, wenn ich kann.

Antwort

7

Es gibt eine Umgebungsvariable mit dem Namen SECURITYSESSIONID, die von loginwindow.app festgelegt und an die Anwendungen des Benutzers übergeben wird. Die Variable wird nicht gesetzt, wenn Sie sich über ssh anmelden. Es dient als eine Art Griff, um mit dem Fensterserver zu sprechen.

Problem: Das Vorhandensein dieser Variable bedeutet nicht, dass dieser Benutzer derzeit den Fenstermanager steuert (denke schneller Benutzerwechsel).

Es gibt eine Funktion CGSessionCopyCurrentDictionary im Application Rahmen genannt, die vielversprechend aussieht:

Rückgabewert: Ein Fenster-Server-Sitzung Wörterbuch, oder NULL, wenn der Anrufer nicht innerhalb einer Quarz-GUI-Sitzung oder das Fenster läuft Server ist deaktiviert. Sie sollten das Wörterbuch freigeben, wenn Sie es nicht mehr verwenden. Informationen zu den Schlüssel/Wert-Paaren in diesem Wörterbuch finden Sie unter "Eigenschaften der Windows Server-Sitzung".

+2

Es sieht so aus, als ob CGWindowServerCFMachPort in diesem Fall auch dieselben Informationen bereitstellen kann (es gibt auch NULL zurück), wenn kein Fensterserver verfügbar ist. Danke für den Zeiger! –

+1

Vergessen Sie nicht zu überprüfen, ob die Sitzung aktuell ist (der Benutzer steuert den Fensterserver: ist nicht schnell ausgeschaltet) –

+1

Da Lion 'CGWindowServerCFMachPort' erfolgreich ist, auch wenn es keine aktuelle Sitzung gibt, ist es nicht gut. 'CGSessionCopyCurrentDictionary' ist ein wenig zuverlässiger, aber Sie können ssh immer noch nicht vom Terminal aus unterscheiden, da beide nun volle Session-Informationen geben, so dass' SSH_CONNECTION' die einzige Möglichkeit ist, dies zu sagen. –