我正在开发一个具有Objective-C守护进程的Cocoa GUI应用程序。守护进程由LaunchDaemon启动,图形用户界面使用loginItems为每个用户启动。
在部署更新时,我需要更新守护进程,这很简单,还需要更新GUI。我希望能够退出GUI,替换应用程序,并在当前运行该应用程序的每个用户帐户上重新启动它。我想从守护进程执行所有这些操作,该守护进程当然是以root用户身份运行的。
我如何: 1)以根用户身份退出,然后在另一个用户的界面中重新启动应用程序? 2)以根用户身份,退出,然后为当前登录的每个用户重新启动特定的loginItem?
我已经尝试过搜索,有很多讨论,包括这个similar question,但似乎没有可用的工作解决方案。
任何帮助都是非常感谢的。
发布于 2010-12-17 21:51:51
因此,我使用苹果的支持请求来获得最佳答案,并结合一些在线研究。
攻击的基本计划是让每个GUI实例在守护进程告诉它时重新启动它自己。
首先,我让守护程序替换了图形用户界面的包(.app文件夹)。你可以在应用程序仍在惊人地运行时执行此操作。这就是苹果的支持帮了大忙的地方。我仍然感到惊讶的是,一个应用程序可以在运行时被替换,但他们告诉我这样做,它会没事的。
然后,我让守护进程向图形用户界面发出一条DistributedNotification,并显示一条重新启动自身的消息。为了让图形用户界面正确地响应,我创建了restarter类,它将获取它自己的pid和包路径,然后我在内存中构建了一个shell脚本来杀死pid,等待10秒,然后执行一个shell "open bundlepath.app“,然后它重新启动。
我使用NSTask来调用“在内存中”的外壳脚本,它实际上只是一个@"kill %@;leep10;open %@",pid,bundlePath...
效果令人惊讶!
谢谢你的建议!
发布于 2010-12-01 23:52:52
我相信NSDistributedNotificationCenter应该为此而努力。请注意,使用NSDistributedNotificationCenter在不同用户帐户中的进程之间通信本身并不需要根权限。
为了帮助协调用户帐户之间的关系,它可能有助于区分GUI应用程序和守护程序的哪些实例当前处于活动和控制状态,以及哪些实例处于被动状态。您可以使用NSWorkspace的通知(NSWorkspaceSessionDidBecomeActiveNotification,NSWorkspaceSessionDidResignActiveNotification)来确定用户何时在用户帐户等之间切换,并相应地设置实例。
假设您的GUI应用程序和守护程序在3个不同的用户帐户中运行实例。例如,如果在活动用户帐户中,您想要开始更新过程,则可以使用NSDistributedNotificationCenter轻松地通知所有其他实例立即关闭。要做到这一点,您需要定义如下内容。
在.h文件中,声明不同通知的名称:
extern NSString * const MDShouldTerminateImmediatelyNotification;在(an)实现文件中,创建名称,并将类设置为对该名称的分布式通知感兴趣,等等:
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];
}
}在将启动更新过程的类中,您将执行以下操作来发送通知:
- (void)beginUpdate {
[[NSDistributedNotificationCenter defaultCenter]
postNotificationName:MDShouldTerminateImmediatelyNotification
object:[self description] // or just nil
userInfo:nil
options:NSNotificationDeliverImmediately | NSNotificationPostToAllSessions];
// continue
}我想,这至少应该是一个开始。
实际上,如果您正在讨论以root身份运行的单个守护程序实例,该实例执行所有用户帐户中的所有操作,则可能需要考虑将该部分分解为Launchd代理类型的进程(后台进程,在用户级别运行,每个用户帐户将有其自己的实例)。
有关详细信息,请访问:
发布于 2010-12-01 08:24:15
在Apple的文档中查找“授权服务”。
https://stackoverflow.com/questions/4319210
复制相似问题