8

我正在为 Mac (Leopard) 编写一个 C 应用程序,它需要在接收电源通知时做一些工作,例如睡眠、唤醒、关机、重启。它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;
    }
}

然而,只有前两个 sleep 和 wake ( kIOMessageSystemWillSleepand kIOMessageSystemHasPoweredOn)被调用。我从来没有收到任何重启或关机的通知(kIOMessageSystemWillRestartkIOMessageSystemWillPowerOff)。

难道我做错了什么?或者是否有另一个 API 可以给我重启和关闭通知?我更愿意将其保留为 C 程序(这就是我所熟悉的),但我愿意接受任何明智的替代建议(我已经查看了登录/注销挂钩,但这些似乎已被弃用)的发射d)。

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

4

2 回答 2

6

我知道您可以从 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");
}
于 2009-08-26T08:38:17.110 回答
2

使用IORegisterForSystemPower不提供您寻求的事件。引用功能文档:

/*!@function IORegisterForSystemPower

@abstract 将调用者连接到根电源域 IOService 以接收系统的睡眠和唤醒通知。

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

于 2017-12-02T20:40:59.730 回答