I'm writing an application in C for the Mac (Leopard) that needs to do some work on receipt of power notifications, e.g. sleep, wake-up, shutdown, restart. It runs via launchd
as a launchagent on login then begins monitoring for notifications. The code I'm using to do this is as follows:
/* ask for power notifications */
static void StartPowerNotification(void)
{
static io_connect_t rootPort;
IONotificationPortRef notificationPort;
io_object_t notifier;
rootPort = IORegisterForSystemPower(&rootPort, ¬ificationPort,
PowerCallback, ¬ifier);
if (!rootPort)
exit (1);
CFRunLoopAddSource (CFRunLoopGetCurrent(),
IONotificationPortGetRunLoopSource(notificationPort),
kCFRunLoopDefaultMode);
}
/* perform actions on receipt of power notifications */
void PowerCallback (void *rootPort, io_service_t y,
natural_t msgType, void *msgArgument)
{
switch (msgType)
{
case kIOMessageSystemWillSleep:
/* perform sleep actions */
break;
case kIOMessageSystemHasPoweredOn:
/* perform wakeup actions */
break;
case kIOMessageSystemWillRestart:
/* perform restart actions */
break;
case kIOMessageSystemWillPowerOff:
/* perform shutdown actions */
break;
}
}
However, only the top two for sleep and wake (kIOMessageSystemWillSleep
and kIOMessageSystemHasPoweredOn
) ever get called. I never get any notifcations for restart or shutdown (kIOMessageSystemWillRestart
and kIOMessageSystemWillPowerOff
).
Am I doing something wrong? Or is there another API that would give me the restart and shutdown notifications? I'd prefer to keep it as a C program (as thats what I'm familiar with) but am open to any sensible suggestions of alternatives (I've had a look at login/logout hooks but these seem to be deprecated in favour of launchd).
Thanks in advance for any help/tips!
To change these preferences, choose Apple menu > System Preferences, click Notifications & Focus , then click Notifications. Select an app or website on the left, then view or change settings on the right. The options vary by app. Customize notifications for an app or website.
Manage notifications by conversation In the Messages app on your Mac, select a conversation. Click the Details button in the top-right corner, then select Hide Alerts to stop notifications; to get message notifications again, deselect Hide Alerts.
In Notification Center on your Mac, you can catch up on notifications you missed and use widgets to view appointments, birthdays, the weather, top headlines, and more right from the desktop.
I know you can register for the NSWorkspaceWillPowerOffNotification notification from NSWorkspace, which is not a C function but does work.
#import <AppKit/AppKit.h>
#import "WorkspaceResponder.h"
int main (int argc, const char * argv[]) {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
NSNotificationCenter *nc = [[NSWorkspace sharedWorkspace] notificationCenter];
WorkspaceResponder *mainController = [[WorkspaceResponder alloc] init];
//register for shutdown notications
[nc addObserver:mainController
selector:@selector(computerWillShutDownNotification:)
name:NSWorkspaceWillPowerOffNotification object:nil];
[[NSRunLoop currentRunLoop] run];
[pool release];
return 0;
}
Then in WorkspaceResponder.m:
- (void) computerWillShutDownNotification:(NSNotification *)notification {
NSLog(@"Received Shutdown Notification");
}
Using IORegisterForSystemPower
doesn't provide the events you seek. Quoting from function documentation :
/*! @function IORegisterForSystemPower
@abstract Connects the caller to the Root Power Domain IOService for the purpose of receiving sleep & wake notifications for the system.
Does not provide system shutdown and restart notifications.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With