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

发布于 2024-08-02 21:48:43 字数 1710 浏览 5 评论 0原文

我正在用 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 程序(因为这就是我所熟悉的),但对任何明智的替代方案建议持开放态度(我已经查看过登录/注销挂钩,但这些似乎已被弃用)发射的d)。

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

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!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

打小就很酷 2024-08-09 21:48:43

我知道您可以从 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");
}

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");
}
归属感 2024-08-09 21:48:43

使用 IORegisterForSystemPower 不会提供您寻求的事件。引用函数文档:

/*! @函数IORegisterForSystemPower

@abstract 将调用者连接到根电源域 IOService
为了获得睡眠和睡眠的目的系统的唤醒通知。

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

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文