首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >从root帐户启动应用

从root帐户启动应用
EN

Stack Overflow用户
提问于 2010-12-01 06:10:45
回答 3查看 1.3K关注 0票数 3

我正在开发一个具有Objective-C守护进程的Cocoa GUI应用程序。守护进程由LaunchDaemon启动,图形用户界面使用loginItems为每个用户启动。

在部署更新时,我需要更新守护进程,这很简单,还需要更新GUI。我希望能够退出GUI,替换应用程序,并在当前运行该应用程序的每个用户帐户上重新启动它。我想从守护进程执行所有这些操作,该守护进程当然是以root用户身份运行的。

我如何: 1)以根用户身份退出,然后在另一个用户的界面中重新启动应用程序? 2)以根用户身份,退出,然后为当前登录的每个用户重新启动特定的loginItem?

我已经尝试过搜索,有很多讨论,包括这个similar question,但似乎没有可用的工作解决方案。

任何帮助都是非常感谢的。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2010-12-17 21:51:51

因此,我使用苹果的支持请求来获得最佳答案,并结合一些在线研究。

攻击的基本计划是让每个GUI实例在守护进程告诉它时重新启动它自己。

首先,我让守护程序替换了图形用户界面的包(.app文件夹)。你可以在应用程序仍在惊人地运行时执行此操作。这就是苹果的支持帮了大忙的地方。我仍然感到惊讶的是,一个应用程序可以在运行时被替换,但他们告诉我这样做,它会没事的。

然后,我让守护进程向图形用户界面发出一条DistributedNotification,并显示一条重新启动自身的消息。为了让图形用户界面正确地响应,我创建了restarter类,它将获取它自己的pid和包路径,然后我在内存中构建了一个shell脚本来杀死pid,等待10秒,然后执行一个shell "open bundlepath.app“,然后它重新启动。

我使用NSTask来调用“在内存中”的外壳脚本,它实际上只是一个@"kill %@;leep10;open %@",pid,bundlePath...

效果令人惊讶!

谢谢你的建议!

票数 3
EN

Stack Overflow用户

发布于 2010-12-01 23:52:52

我相信NSDistributedNotificationCenter应该为此而努力。请注意,使用NSDistributedNotificationCenter在不同用户帐户中的进程之间通信本身并不需要根权限。

为了帮助协调用户帐户之间的关系,它可能有助于区分GUI应用程序和守护程序的哪些实例当前处于活动和控制状态,以及哪些实例处于被动状态。您可以使用NSWorkspace的通知(NSWorkspaceSessionDidBecomeActiveNotification,NSWorkspaceSessionDidResignActiveNotification)来确定用户何时在用户帐户等之间切换,并相应地设置实例。

假设您的GUI应用程序和守护程序在3个不同的用户帐户中运行实例。例如,如果在活动用户帐户中,您想要开始更新过程,则可以使用NSDistributedNotificationCenter轻松地通知所有其他实例立即关闭。要做到这一点,您需要定义如下内容。

在.h文件中,声明不同通知的名称:

代码语言:javascript
复制
extern NSString * const MDShouldTerminateImmediatelyNotification;

在(an)实现文件中,创建名称,并将类设置为对该名称的分布式通知感兴趣,等等:

代码语言:javascript
复制
NSString * const MDShouldTerminateImmediatelyNotification = @"MDShouldTerminateImmediately";


- (id)init {
   if (self = [super init]) {
       [[NSDistributedNotificationCenter defaultCenter]
       addObserver:self
       selector:@selector(shouldTerminateImmediately:)
       name:MDShouldTerminateImmediatelyNotification
       object:nil];
   }
   return self;
}

- (void)dealloc {
   [[NSDistributedNotificationCenter defaultCenter] removeObserver:self];
   [super dealloc];
}

- (void)shouldTerminateImmediately:(NSNotification *)notification {
   if (ourInstanceIsInControl == NO) {
     [NSApp terminate:nil];
    }
}

在将启动更新过程的类中,您将执行以下操作来发送通知:

代码语言:javascript
复制
- (void)beginUpdate {
   [[NSDistributedNotificationCenter defaultCenter]
    postNotificationName:MDShouldTerminateImmediatelyNotification
       object:[self description] // or just nil
       userInfo:nil
       options:NSNotificationDeliverImmediately | NSNotificationPostToAllSessions];
    // continue

}

我想,这至少应该是一个开始。

实际上,如果您正在讨论以root身份运行的单个守护程序实例,该实例执行所有用户帐户中的所有操作,则可能需要考虑将该部分分解为Launchd代理类型的进程(后台进程,在用户级别运行,每个用户帐户将有其自己的实例)。

有关详细信息,请访问:

Technical Note TN2083 Daemons and Agents

Root and Login Sessions

Creating launchd Daemons and Agents

票数 3
EN

Stack Overflow用户

发布于 2010-12-01 08:24:15

在Apple的文档中查找“授权服务”。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4319210

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档