代码之家  ›  专栏  ›  技术社区  ›  binarybob

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

  •  6
  • binarybob  · 技术社区  · 16 年前

    我正在用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;
        }
    }
    

    然而,只有前两名适合睡眠和醒来( kIOMessageSystemWillSleep kIOMessageSystemHasPoweredOn ) 接到电话。我从未收到任何重启或关机的通知( kIOMessageSystemWillRestart kIOMessageSystemWillPowerOff ).

    我做错什么了吗?或者是否有另一个API可以给我重新启动和关闭通知?我更愿意把它作为一个C程序(这是我所熟悉的),但我愿意接受任何明智的替代建议(我已经看过登录/注销挂钩,但它们似乎不赞成launchd)。

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

    2 回复  |  直到 16 年前
        1
  •  6
  •   Rob Keniger    16 年前

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

    - (void) computerWillShutDownNotification:(NSNotification *)notification {
        NSLog(@"Received Shutdown Notification");
    }
    
        2
  •  2
  •   Irad K    7 年前

    使用 IORegisterForSystemPower 不提供你想要的事件。引用函数文档:

    /*! @函数IORegisterForSystemEmpower

    用于接收睡眠和;系统的唤醒通知。

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