I believe NSDistributedNotificationCenter should work for this. Note that using NSDistributedNotificationCenter to communicate between processes in different user accounts does not, in and of itself, require root privileges.
To help with coordination between user accounts, it might help to distinguish which instance of the GUI app and daemon are currently active and in control, and which instances are passive. You can use NSWorkspace's notifications (NSWorkspaceSessionDidBecomeActiveNotification, NSWorkspaceSessionDidResignActiveNotification) to determine when a user switches between user accounts, etc. and have your instances set themselves accordingly.
Say your GUI app and daemon have instances running in 3 different user accounts. If in the active user account, you want to begin the update process, you could use NSDistributedNotificationCenter to easily tell all other instances to shutdown immediately, for example. To do that, you'd define something like the following.
In an .h file, declare the names of your different notifications:
extern NSString * const MDShouldTerminateImmediatelyNotification;
in (an) implementation file, create the names, and set the class up to be interested in a distributed notification by that name, etc.:
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];
}
}
In the class that would initiate the update process, you'd do something like this to send the notification:
- (void)beginUpdate {
[[NSDistributedNotificationCenter defaultCenter]
postNotificationName:MDShouldTerminateImmediatelyNotification
object:[self description] // or just nil
userInfo:nil
options:NSNotificationDeliverImmediately | NSNotificationPostToAllSessions];
// continue
}
That should at least be a beginning to work with, I'd think....
Actually, if you are talking about having one single daemon instance running as root that does everything in all user accounts, you may need to consider factoring that part out into a Launchd Agent type process (background process, runs at user level, each user account would have its own instance).
For more info:
Technical Note TN2083 Daemons and Agents
Root and Login Sessions
Creating launchd Daemons and Agents