วิธีเปิดแอปพลิเคชัน GUI ในเซสชันกราฟิกของผู้ใช้รายอื่น


15

ฉันกำลังพยายามหาวิธีเปิดแอปพลิเคชัน GUI ในฐานะผู้ใช้อื่นที่เข้าสู่ระบบแบบโต้ตอบในเซสชันกราฟิกของผู้ใช้รายนั้น

ตัวอย่างเช่นสมมติว่าฉันมีผู้ใช้สองคนคือ foo และ bar ทั้งสองเข้าสู่ระบบ แต่ผู้ใช้แบบโต้ตอบปัจจุบันคือ foo ฉันต้องการเปิดใช้งาน Calculator.app ในฐานะผู้ใช้ "บาร์" ดังนั้นเมื่อฉันเปลี่ยนผู้ใช้อย่างรวดเร็วเป็นแถบฉันพบว่าหน้าต่างเครื่องคิดเลขเปิดอยู่ในเซสชันของแถบ

นี่คือสิ่งที่ฉันพยายามที่ไม่ทำงาน:

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

นี่เป็นการเปิดตัว Calculator.app เป็นแถบ แต่หน้าต่างจะเปิดในเซสชันกราฟิกของ foo

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

ผลเหมือนกัน

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

เปิดตัวเครื่องคิดเลขในฐานะ foo ไม่ใช่แถบ

launchctl asuser [uid of bar] [any of the above commands]

ผลเหมือนกัน

มีวิธีใดบ้างที่จะทำให้สิ่งนี้สำเร็จ? ฉันยินดีที่จะให้ความบันเทิงทุกรูปแบบของการแก้ปัญหาที่เป็นไปได้รวมถึง bash scripting, AppleScript, การเขียนโปรแกรม Core Foundation หรือ Cocoa เป็นต้น ในสถานการณ์ของฉันโปรแกรมหรือสคริปต์ใด ๆ สามารถดำเนินการในฐานะผู้ใช้ใด ๆ รวมถึงรูท

หมายเหตุ: ฉันทราบว่าเป็นไปได้ที่จะใช้เหตุการณ์ Apple ระยะไกล แต่ฉันไม่สามารถใช้งานได้เนื่องจากในสถานการณ์ที่ฉันพยายามทำสิ่งนี้ฉันไม่รับประกันว่าจะมีการเปิดใช้งาน "กิจกรรม Apple ระยะไกล" ในการตั้งค่าการแชร์

ความช่วยเหลือใด ๆ ที่จะได้รับการชื่นชมอย่างมาก!


1
คุณลองใช้openคำสั่งSSHใช่ไหม
Matthieu Riegler

อย่างผิดปกติไอคอนท่าเรือของแอปจะปรากฏในเซสชันของ foo แต่หน้าต่างแอปจะปรากฏในแถบ ดังนั้นดูเหมือนจะไม่ได้ผล แต่เป็นคำแนะนำที่ดี ขออภัยไม่มีการรับประกันว่าการเข้าสู่ระบบที่ปลอดภัยจะเปิดใช้งานในกรณีที่ฉันต้องการสิ่งนี้ซึ่งเป็นโปรแกรมติดตั้ง
GuyGizmo

ฉันคิดว่าจิ๊กซอว์ชิ้นเดียวอาจเกี่ยวข้องกับอาร์กิวเมนต์บรรทัดคำสั่ง -psn ซึ่งระบบปฏิบัติการเพิ่มในบางสถานการณ์ ฉันเคยพบสิ่งนี้ในอดีตเมื่อทำงานกับการย้ายรหัสบางส่วนไปยัง OS X โปรดดูคำถามนี้และเอกสารประกอบของ Apple ที่อ้างอิง
แอชลีย์

ณ วันที่ 10.10 ในที่สุด bsexec ที่กล่าวถึงทำงานได้อย่างสมบูรณ์
Hofi

คำตอบ:


7

สิ่งที่คุณต้องการบรรลุเป็นไปได้ แต่ยาก คุณต้องเปิดแอปพลิเคชันภายในเซสชันผู้ใช้ที่เหมาะสม เพื่อเหตุผลด้านความปลอดภัยการข้ามการแบ่งเซสชันผู้ใช้เป็นเรื่องยาก

คุณต้องมีกระบวนการที่ทำงานอยู่ในเซสชันของผู้ใช้รายอื่นเพื่อรับฟังคำขอของคุณและเปิดใช้แอปพลิเคชันแทนคุณ

bsexec ของ launchd

โชคดีที่เวอร์ชันล่าสุดlaunchdมีความสามารถนี้ แม้ว่าวิศวกรของ Apple จะไม่แนะนำให้ใช้งานทั่วไป ใช้bsexecตัวเลือกในlaunchctlเพื่อกำหนดเป้าหมายเซสชันผู้ใช้ที่เหมาะสม:

 bslist [PID | ..] [-j]
          This prints out Mach bootstrap services and their respective states. While the namespace
          appears flat, it is in fact hierarchical, thus allowing for certain services to be only avail-
          able to a subset of processes. The three states a service can be in are active ("A"), inactive
          ("I") and on-demand ("D").

          If [PID] is specified, print the Mach bootstrap services available to that PID. If [..] is
          specified, print the Mach bootstrap services available in the parent of the current bootstrap.
          Note that in Mac OS X v10.6, the per-user Mach bootstrap namespace is flat, so you will only
          see a different set of services in a per-user bootstrap if you are in an explicitly-created
          bootstrap subset.

          If [-j] is specified, each service name will be followed by the name of the job which regis-
          tered it.

 bsexec PID command [args]
          This executes the given command in the same Mach bootstrap namespace hierachy as the given
          PID.

 bstree [-j]
          This prints a hierarchical view of the entire Mach bootstrap tree. If [-j] is specified, each
          service name will be followed by the name of the job which registered it.  Requires root priv-
          ileges.

วิธีที่แนะนำคือการเขียนตั๋วงาน launchd และรีสตาร์ท Mac - หรือขอให้ผู้ใช้ออกจากระบบและกลับมาอีกครั้ง

สาเหตุของปัญหา

ปัญหาเกิดจากแอปพลิเคชันที่เชื่อมต่อกับWindowServerกระบวนการที่ไม่ถูกต้อง แต่ละเซสชั่นผู้ใช้มี WindowServer แยกต่างหาก กระบวนการนี้จัดการกับส่วนต่อประสานผู้ใช้ วิธีการก่อนหน้านี้ของคุณเป็นเจ้าของกระบวนการด้วยผู้ใช้ที่ถูกต้อง แต่เชื่อมต่อกับกระบวนการ WindowServer ของคุณเอง

ปัญหานี้ถูกกล่าวถึงในบันทึกย่อทางเทคนิคของDaemons และ Agentจาก Apple

ประสบการณ์

ฉันรู้สิ่งนี้จากประสบการณ์ส่วนตัว สำหรับ Power Manager ฉันเขียนpmuserให้อยู่ภายในเซสชันผู้ใช้แต่ละครั้ง pmuserฟัง daemon ของเราและจัดการการเรียกใช้และคำสั่งต่อผู้ใช้ แม้ daemon ของเราจะมีสิทธิ์ใช้งานรูทเรายังต้องการกระบวนการต่อผู้ใช้ในการทำงานได้อย่างน่าเชื่อถือภายในเซสชันผู้ใช้


คุณสามารถให้สคริปต์ง่ายๆเช่นในคำตอบของ TJ ที่นั่น แต่สคริปต์ที่ใช้งานได้ หรือมันซับซ้อนเกินไปสำหรับเรื่องแบบนี้?
cregox

วิธีแก้ไขที่ถูกต้องนั้นซับซ้อนเกินไปสำหรับสคริปต์สั้น ๆ เป็นการดีที่ต้องการกระบวนการแยกแทรมโพลีนในเซสชันผู้ใช้เป้าหมาย นี่คือสิ่งที่เราต้องทำเพื่อ Power Manager: dssw.co.uk/powermanagerคุณคาดหวังอะไรที่จะบรรลุ?
Graham Miln

หวังว่าจะประสบความสำเร็จในสิ่งที่กล่าวในชื่อเรื่อง: เปิดตัวแอปพลิเค GUI ในเซสชั่นของผู้ใช้อื่น "คะแนนโบนัส" หากผู้ใช้รายอื่นไม่จำเป็นต้องเข้าสู่ระบบหรือสามารถเข้าสู่ระบบได้โดยทางโปรแกรม โดยเฉพาะฉันต้องการ google ไดรฟ์หลายตัว มันทำงานได้ถ้าฉันเพียงเข้าสู่ระบบด้วยตนเองและมันอยู่ภายใต้รายการเข้าสู่ระบบของผู้ใช้ในการตั้งค่าระบบ กระบวนการแทรมโพลีนไม่ได้นำคะแนนโบนัส แต่ถ้าเป็นวิธีเดียวที่วิศวกรของ Apple แนะนำคืออะไร ฉันคิดว่ามันจะแม่นยำสำหรับการทำแฮ็คสคริปต์อย่างง่าย ๆ ! : P
cregox

@Cawas โปรดถามคำถามนี้เป็นคำถามใหม่และมุ่งเน้นไปที่เป้าหมายที่ต้องการ Google ไดรฟ์หลายตัวมากกว่าที่จะทำได้ การเปลี่ยนโฟกัสจะช่วยให้คำถามไม่ถูกทำเครื่องหมายว่าซ้ำซ้อน
Graham Miln

พอเป็นธรรมและทำ
cregox

7

ไม่มีคำตอบ bsexec ข้างต้นทำงานกับ El Capitan (10.11) เนื่องจาก System Integration Protection (SIP) ปิดพอร์ต "launchctl asuser" ใช้งานได้ แต่ต้องการให้ทำงานเป็นรูท คำสั่งด้านล่างใช้ได้กับ El Capitan (และระบบปฏิบัติการล่าสุด):

sudo launchctl asuser 501 open /Applications/Calculator.app

โปรดทราบว่า 501 เป็นหมายเลขผู้ใช้สำหรับผู้ใช้อื่นของฉัน


นี่คือผลลัพธ์ของฉัน: bruno.medeiros@brunojcm-macbook:~ $ sudo launchctl asuser 501 open /Applications/Firefox.appและได้รับLSOpenURLsWithRole() failed with error -600 for the file /Applications/Firefox.app
BrunoJCM

@BrunoJCM คุณแน่ใจหรือไม่ว่า 501 เป็นรหัส ID ผู้ใช้สำหรับผู้ใช้ที่คุณต้องการเปิดด้วย ชัดเจนกว่านี้เล็กน้อยถ้าคำสั่งเป็นดังนี้: sudo launchctl asuser $(id -u <user_id_name>) <app>. ที่กล่าวว่าฉันได้รับข้อผิดพลาดที่แตกต่างกันของposix_spawn(): 13: Permission deniedแม้ว่าฉันจะทำงานด้วย ID ผู้ใช้เดียวกันกับที่ฉันเข้าสู่ระบบด้วย (และเป็นเจ้าของเซสชั่น) สำหรับsudo launchctl asuser $(id -u mtylutki) /Applications/Calculator.app
Marcus

2

ในที่สุด 10.10 จะให้การปรับใช้ "launchctl bsexec" ที่ถูกต้องซึ่งคุณสามารถใช้:

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

ผู้ชายพูดว่า

สิ่งนี้จะดำเนินการคำสั่งที่กำหนดในบริบทการดำเนินการที่คล้ายกันให้มากที่สุดกับ PID เป้าหมาย

ดังนั้นเมื่อ PID param คุณสามารถใช้ pid ของกระบวนการloginwindowที่เหมาะสม UID เป็นรหัสผู้ใช้ของผู้ใช้ที่เป็นเจ้าของ loginwindow และ GID เป็นกลุ่มหลัก

มันใช้งานได้ดีสำหรับคำสั่งใด ๆ และแน่นอนสำหรับงาน launchd (fe launchagents) เช่นกันในที่สุด:

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

ไม่แน่ใจว่านี่เป็นเรื่องจริงสำหรับคนอื่นหรือไม่ แต่ฉันได้รับtask_for_pid(): 0x5ข้อผิดพลาดในตอนนี้ซึ่งฉันได้ตรวจสอบแล้วว่า PID นั้นถูกต้อง
Marcus

1

คุณสามารถใช้ Finder osascript -e "tell application \"Finder\" to open (\"${app}\" as POSIX file as alias)"เป็นเจ้าภาพสำหรับสิทธิ์ที่เหมาะสม ด้วยวิธีนี้มันจะเปิดใช้งานผ่านบริบทของ GUI ที่เปิดตัว Finder


0

สิ่งนี้ทำงานผ่าน 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

แต่ถ้าลองผ่าน Terminal.app มันจะเปิด TextEdit ใน GUI ของผู้ใช้ปัจจุบัน

หากคุณไม่แน่ใจว่าsshเปิดใช้งานอยู่หรือไม่คุณสามารถเปิดใช้งานได้ชั่วคราว

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

และปิดใช้งานอีกครั้งหลังจากนั้นถ้าจำเป็น?

มิฉะนั้นฉันก็นิ่งงัน

ทดสอบใน 10.9


มันจะเปิดแอปพลิเคชันตามที่คุณพูด แต่จะเปิดในเซสชันผู้ใช้ปัจจุบันไม่ใช่ในเซสชันของผู้ใช้รายอื่นตามที่ถาม
cregox

-1

ง่าย

sudo su name_of_user

จากนั้นเรียกใช้คำสั่งตามปกติ


คำสั่งจะถูกเรียกใช้โดยbarแต่จะยังคงทำงานในfooกราฟิกของเซสชัน
John N

ขออภัยใช่ฉันสับสนเกี่ยวกับคำถามที่ไม่ได้ดำเนินการในเซสชั่นกราฟิกฟู
ซอฟต์แวร์ PandB
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.