4

我有一个在 Mac OSX 10.6 机器的登录上下文中运行的启动守护程序。我想从该代理为每个用户启动一个代理,并让该代理在用户的登录上下文中运行。但是,我需要非常小心地控制代理应用程序的精确参数,这就是为什么我不能像使用守护进程那样使用启动代理。

如何创建在登录用户的上下文中运行的进程?我已经确认seteuidsetuid调用了,但这些不会改变代理应用程序的执行上下文。

我知道这不是推荐的 Apple 做事方式,但我真的没有选择 - 守护程序应用程序的设计非常不灵活(它必须跨许多不同的系统运行)。是否有一种解决方法允许我从在登录上下文中运行的守护程序在登录用户的 GUI 上下文中运行应用程序?

我正在使用 C++、Carbon 和 Cocoa。

4

1 回答 1

1

使用启动代理。所有其他方式都会用大量无用的细节和隐藏的技巧让你大吃一惊。一般来说,这是一项非常复杂的任务,有很多极端情况,而且很难正确实施。Launchd 代理将让您专注于您的任务并节省大量时间。

对您来说最好的解决方案是重写代理不使用命令行,而是连接到 launchd 守护程序并要求正确的选项/设置。

如果不可能或很难,您可以编写将开始连接到守护进程的包装启动代理,询问选项,然后使用正确的命令行启动原始代理。

如果您认为实现“连接到守护程序”机制太难了......也许是这样,但它比从守护程序在其他会话中启动代理要容易得多(当在不同的极端情况支持下正确实施时)。

但是,如果您真的非常无所谓地想要它以肮脏的方式,您可以使用“launchctl bsexec”。一些有效的示例: 为所有具有 GUI 会话的用户启动/停止启动代理(而不是“launchctl load”,它可以在会话上下文中启动任何可执行文件)。

对此进行了一些更新。

通过“使用launchctl bsexec”我的意思是这样的:

ps aux | grep loginwindow | grep user | awk '{ system("sudo launchctl bsexec "$2" sudo -u user /Applications/TextEdit.app/Contents/MacOS/TextEdit") }'

在会话中找到您想要的一些应用程序,获取其 PID 并调用“launchctl bsexec”以在同一会话中运行您想要的内容。上面的示例将在登录的“用户”会话中启动 TextEdit,即使该行在另一个登录的用户帐户下或从服务中执行。

但我在 Lion 上对其进行了测试——它不起作用。它仅适用于我的 Leopards (10.5 / 10.6)。那就是我想说的 - 不使用启动代理会导致你的屁股持续疼痛,仅此而已。经过十几次这样的事情,我们完全启用了启动代理,现在很高兴:)

于 2011-07-04T08:16:40.070 回答