Получение уведомлений о питании (особенно при отключении) на Mac OSX - PullRequest
7 голосов
/ 24 августа 2009

Я пишу приложение на 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 ]

5 голосов
/ 26 августа 2009

Я знаю, что вы можете зарегистрироваться на уведомление NSWorkspaceWillPowerOffNotification от NSWorkspace, которое не является функцией 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");
}
0 голосов
/ 02 декабря 2017

Использование IORegisterForSystemPower не обеспечивает события, которые вы ищете. Цитирование из документации по функции:

/ *! @function IORegisterForSystemPower

@ abstract Подключает вызывающего к IOService корневого домена питания с целью получения уведомлений о сне и пробуждении для системы.

Не обеспечивает отключение системы и уведомления о перезапуске.

...