16 votes

Comment lancer une application GUI dans la session graphique d'un autre utilisateur ?

Je suis en train d'essayer de trouver comment lancer une application GUI en tant qu'un autre utilisateur connecté de manière interactive, dans la session graphique de cet utilisateur.

Par exemple, disons que j'ai deux utilisateurs, foo et bar. Les deux sont connectés, mais l'utilisateur interactif actuel est foo. Je voudrais lancer Calculator.app en tant qu'utilisateur "bar", de sorte que lorsque je bascule rapidement vers l'utilisateur bar, je trouve la fenêtre de la calculatrice ouverte dans la session de bar.

Voici ce que j'ai essayé qui ne fonctionne pas:

sudo -u bar /Applications/Calculator.app/Contents/MacOS/Calculator

Cela lance Calculator.app en tant que bar, mais la fenêtre s'ouvre dans la session graphique de foo.

sudo -u bar osascript -e "tell application \"Calculator\" to activate"

Même effet.

sudo -u bar open "/Applications/Calculator.app"

Le lance en tant que foo, pas bar.

launchctl asuser [uid de bar] [une des commandes ci-dessus]

Même effet.

Y a-t-il un moyen d'accomplir ceci? Je suis prêt à envisager toutes sortes de solutions possibles, y compris le scripting bash, AppleScript, l'écriture d'un programme Core Foundation ou Cocoa, etc. Dans ma situation, tout programme ou script pourrait s'exécuter en tant qu'utilisateur, y compris root.

Remarque : Je suis conscient qu'il est possible d'utiliser des Apple Events à distance, mais je ne peux pas l'utiliser car dans la situation où j'essaie de le faire, je n'ai aucune garantie que les "Apple Events à distance" seront activés dans les préférences de partage.

Toute aide serait grandement appréciée !

1 votes

Avez-vous essayé la commande open, en utilisant SSH ?

0 votes

Étrangement, l'icône de la barre de menu de l'application apparaît dans la session de foo, mais la fenêtre de l'application apparaît dans celle de bar. Donc cela ne semble pas fonctionner correctement, mais bonne suggestion. Malheureusement, il n'y a aucune garantie que la connexion sécurisée soit activée dans la situation où j'ai besoin de cela, qui est pour un installateur.

0 votes

Je pense qu'un élément de ce puzzle pourrait impliquer l'argument de ligne de commande -psn, que le système d'exploitation ajoute dans certaines situations. J'ai déjà rencontré cela par le passé en travaillant sur le portage de certains codes vers OS X. Voir cette question et la documentation Apple à laquelle elle fait référence.

8voto

Boris Vidolov Points 71

Aucune des réponses bsexec ci-dessus ne fonctionne sur El Capitan (10.11), en raison de la Protection de l'Intégrité du Système (SIP) qui ferme les ports. "launchctl asuser" fonctionne, mais nécessite d'être exécuté en tant que root. La commande ci-dessous fonctionne sur El Capitan (et la plupart des systèmes d'exploitation récents) :

sudo launchctl asuser 501 open /Applications/Calculator.app

Notez que 501 est l'identifiant utilisateur pour mon autre utilisateur.

0 votes

Voici mon résultat : bruno.medeiros@brunojcm-macbook:~ $ sudo launchctl asuser 501 open /Applications/Firefox.app, et j'ai reçu LSOpenURLsWithRole() a échoué avec l'erreur -600 pour le fichier /Applications/Firefox.app

0 votes

@BrunoJCM es-tu sûr que 501 est le code d'identification de l'utilisateur que tu veux ouvrir? C'est un peu plus clair si la commande ressemble à: sudo launchctl asuser $(id -u ) . Cela dit, j'obtiens une erreur différente de posix_spawn(): 13: Permission denied même si je lance avec le même code d'identification que celui avec lequel je suis connecté (et possède la session) pour sudo launchctl asuser $(id -u mtylutki) /Applications/Calculator.app

7voto

Graham Miln Points 39606

Ce que vous voulez réaliser est possible mais difficile. Vous devez lancer l'application dans la session utilisateur appropriée. Pour des raisons de sécurité, franchir la séparation des sessions utilisateur est difficile.

Vous avez besoin d'un processus déjà en cours d'exécution dans la session de l'autre utilisateur pour écouter votre demande et lancer l'application en votre nom.

bsexec de launchd

Heureusement, les versions récentes de launchd ont cette capacité; bien que les ingénieurs d'Apple n'aient pas recommandé son utilisation générale. Utilisez l'option bsexec dans launchctl pour cibler la session utilisateur appropriée :

 bslist [PID | ..] [-j]
          Cela affiche les services de démarrage de Mach et leurs états respectifs. Bien que l'espace
          de noms semble plat, il est en fait hiérarchique, permettant ainsi à certains services d'être uniquement disponibles pour un sous-ensemble de processus. Les trois états dans lesquels un service peut se trouver sont actif ("A"), inactif
          ("I") et à la demande ("D").

          Si [PID] est spécifié, afficher les services de démarrage de Mach disponibles pour ce PID. Si [..] est
          spécifié, afficher les services de démarrage de Mach disponibles dans le parent du démarrage actuel.
          Remarquez que dans Mac OS X v10.6, l'espace de noms de démarrage Mach par utilisateur est plat, donc vous ne verrez que
          un ensemble de services différents dans un démarrage par utilisateur si vous êtes dans un sous-ensemble de démarrage créé explicitement.

          Si [-j] est spécifié, chaque nom de service sera suivi du nom de la tâche qui l'a enregistré.

 bsexec PID commande [args]
          Cela exécute la commande donnée dans la même hiérarchie de l'espace de noms de démarrage de Mach que le
          PID donné.

 bstree [-j]
          Cela affiche une vue hiérarchique de l'ensemble de l'arbre de démarrage de Mach. Si [-j] est spécifié, chaque
          nom de service sera suivi du nom de la tâche qui l'a enregistré.  Nécessite des privilèges root.

L'approche recommandée est d'écrire un ticket de tâche launchd et de redémarrer le Mac - ou de demander à l'utilisateur de se déconnecter et de se reconnecter.

Origine des Problèmes

Les problèmes découlent du fait que l'application est connectée au mauvais processus WindowServer. Chaque session utilisateur a un WindowServer séparé; ce processus gère l'interface utilisateur. Vos méthodes antérieures placent la propriété du processus avec le bon utilisateur mais connecté à votre propre processus WindowServer.

Ce problème est mentionné dans la note technique Adémon et Agents d'Apple.

Expérience

Je sais cela par expérience personnelle. Pour Power Manager, j'ai écrit pmuser pour exister dans chaque session utilisateur. pmuser écoute notre démon et gère les lancements et commandes par utilisateur. Malgré notre démon ayant une autorité root, nous avions encore besoin d'un processus par utilisateur pour fonctionner de manière fiable dans les sessions utilisateur.

0 votes

Pouvez-vous fournir un script simple, comme dans la réponse de TJ là-bas, mais un qui fonctionne ? Ou est-ce simplement trop complexe pour une telle chose?

0 votes

La bonne solution est trop complexe pour un court script. Idéalement, un processus séparé de type trampoline est nécessaire dans la session utilisateur cible. C'est ce que nous avons dû faire pour Power Manager : dssw.co.uk/powermanager Qu'espérez-vous réaliser?

0 votes

En espérant réaliser exactement ce qui est dit dans le titre : lancer une application en GUI dans la session d'un autre utilisateur. Des "points bonus" si l'autre utilisateur n'a pas besoin d'être connecté ou s'il peut se connecter de manière programmée. Plus spécifiquement, je veux plusieurs Google Drive. Cela fonctionne si je me connecte manuellement et que c'est dans les Éléments de connexion de cet utilisateur dans les Préférences Système. Un processus de trampoline ne donnerait pas de points bonus, mais si c'est la seule solution, quel est précisément la recommandation des ingénieurs d'Apple contre cela ? Je pensais que c'était justement pour faire de tels scripts de piratage simples ! :P

2voto

Zyx Points 340

Comme enfin 10.10 fournit une implémentation correcte de "launchctl bsexec", vous pouvez utiliser :

sudo /bin/launchctl bsexec PID chroot -u UID -g GID / open /Applications/TextWrangler.app

l'homme dit

Ceci exécute la commande donnée dans un contexte d'exécution aussi similaire que possible au PID cible.

Donc en tant que paramètre de PID, vous pouvez utiliser le PID du processus loginwindow approprié. L'UID est l'identifiant d'utilisateur de l'utilisateur qui possède ce loginwindow et le GID est son groupe primaire.

Cela fonctionne bien pour n'importe quelle commande et bien sûr aussi pour les jobs launchd (par exemple, les launchagents) enfin comme :

/bin/launchctl bsexec 104 chroot -u 501 -g 20 / /bin/launchctl load -S Aqua /Library/LaunchAgents/com.youragent.plist 2>&1

0 votes

Je ne suis pas sûr que ce soit vrai pour les autres, mais j'obtiens maintenant une erreur task_for_pid(): 0x5 pour ceci, où j'ai vérifié que le PID est correct.

1voto

Atishay Jain Points 11

Vous pouvez utiliser le Finder comme hôte pour les bonnes permissions osascript -e "tell application \"Finder\" to open (\"${app}\" as POSIX file as alias)". De cette façon, il se lancera via le contexte GUI depuis lequel le Finder a été lancé.

0voto

moodforaday Points 2633

Cela fonctionne via ssh :

#!/bin/bash

PID=$(ps auxwww | egrep "^bar" |\
fgrep /System/Library/CoreServices/loginwindow.app/Contents/MacOS/loginwindow |\
awk '{print $2}')

sudo launchctl bsexec "$PID" open -a TextEdit

mais si vous essayez via Terminal.app, alors il ouvre TextEdit dans l'interface graphique de l'utilisateur actuel.

Si vous n'êtes pas sûr que ssh soit activé, peut-être pouvez-vous l'activer temporairement

sudo launchctl load -w /System/Library/LaunchDaemons/ssh.plist

et le désactiver à nouveau ensuite si nécessaire?

Sinon, je suis coincé.

Testé sur 10.9.

0 votes

Cela ouvre l'application comme vous le dites, mais cela l'ouvre dans la session de l'utilisateur actuel, et non dans la session de l'autre utilisateur comme demandé.

LesApples.com

LesApples est une communauté de Apple où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres utilisateurs d'appareils Apple, poser vos propres questions ou résoudre celles des autres.

Powered by:

X