我相信 NSDistributedNotificationCenter 应该可以解决这个问题。请注意,使用 NSDistributedNotificationCenter 在不同用户帐户中的进程之间进行通信本身并不需要 root 权限。
为了帮助用户帐户之间的协调,它可能有助于区分 GUI 应用程序和守护程序的哪些实例当前处于活动状态且受控制,以及哪些实例是被动的。您可以使用 NSWorkspace 的通知(NSWorkspaceSessionDidBecomeActiveNotification、NSWorkspaceSessionDidResignActiveNotification)来确定用户何时在用户帐户之间切换等,并让您的实例进行相应的设置。
假设您的 GUI 应用程序和守护程序在 3 个不同的用户帐户中运行实例。例如,如果在活动用户帐户中,您想开始更新过程,您可以使用 NSDistributedNotificationCenter 轻松告诉所有其他实例立即关闭。为此,您需要定义如下内容。
在 .h 文件中,声明不同通知的名称:
extern NSString * const MDShouldTerminateImmediatelyNotification;
在(一个)实现文件中,创建名称,并将类设置为对该名称的分布式通知感兴趣,等等:
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 代理类型进程(后台进程,在用户级别运行,每个用户帐户都有自己的实例)。
更多信息:
Technical Note TN2083 Daemons and Agents
Root and Login Sessions
Creating launchd Daemons and Agents