在Mac OSX上接收电源通知(尤其是关机)

时间:2009-08-24 08:57:23

标签: c macos shutdown

我正在用C语言为Mac(Leopard)编写一个应用程序,它需要在接收电源通知时做一些工作,例如:睡眠,唤醒,关机,重启。它通过launchd作为登录时的启动运行,然后开始监控通知。我用来执行此操作的代码如下:

/* ask for power notifications */
static void StartPowerNotification(void)
{
    static io_connect_t rootPort;   
    IONotificationPortRef notificationPort;
    io_object_t notifier;

    rootPort = IORegisterForSystemPower(&rootPort, &notificationPort, 
                                        PowerCallback, &notifier);
    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;
    }
}

然而,只有前两个用于睡眠和唤醒(kIOMessageSystemWillSleepkIOMessageSystemHasPoweredOn永远被调用。我从未收到重启或关机的任何通知(kIOMessageSystemWillRestartkIOMessageSystemWillPowerOff)。

我做错了吗?或者是否有其他API可以提供重启和关机通知?我更喜欢把它作为一个C程序(就像我熟悉的那样)但是对任何合理的替代建议都持开放态度(我已经看过登录/注销钩子但这些看起来似乎已被弃用了发射)。

提前感谢任何帮助/提示!

2 个答案:

答案 0 :(得分:4)

我知道您可以从NSWorkspace注册NSWorkspaceWillPowerOffNotification通知,该通知不是C函数,但可以正常工作。

#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;
}

然后在WorkspaceResponder.m中:

- (void) computerWillShutDownNotification:(NSNotification *)notification {
    NSLog(@"Received Shutdown Notification");
}

答案 1 :(得分:0)

使用IORegisterForSystemPower不会提供您要搜索的事件。从功能文档中引用:

  

/ *! @function IORegisterForSystemPower

     

@abstract将呼叫者连接到Root Power Domain IOService   为了接受睡眠和唤醒系统的通知。

     

不提供系统关闭和重启通知。