2009-08-24 10 views
5

Estoy escribiendo una aplicación en C para Mac (Leopard) que necesita un poco de trabajo para recibir las notificaciones de encendido, p. Ej. dormir, despertar, apagar, reiniciar. Se ejecuta a través de launchd como iniciador de inicio de sesión y luego comienza a monitorear las notificaciones. El código que estoy usando para hacer esto es como sigue:Recibo de notificaciones de encendido (especialmente apagado) en Mac OSX

/* 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; 
    } 
} 

Sin embargo, sólo los dos primeros para el sueño y la vigilia (kIOMessageSystemWillSleep y kIOMessageSystemHasPoweredOn) vez ser llamado. Nunca recibo ninguna notificación para reiniciar o apagar (kIOMessageSystemWillRestart y kIOMessageSystemWillPowerOff).

¿Estoy haciendo algo mal? ¿O hay otra API que me daría las notificaciones de reinicio y apagado? Preferiría mantenerlo como un programa C (ya que eso es lo que estoy familiarizado), pero estoy abierto a cualquier sugerencia sensata de alternativas (He echado un vistazo a los enganches de inicio de sesión/cierre de sesión pero estos parecen estar en desuso a favor de launchd).

¡Gracias de antemano por cualquier ayuda/consejo!

Respuesta

4

Sé que puede registrarse para la notificación NSWorkspaceWillPowerOffNotification desde NSWorkspace, que no es una función C pero funciona.

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

Luego, en WorkspaceResponder.m:

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

¡Gracias por eso! ¿Sabes si necesito un ícono de ventana o dock para recibir estas notificaciones? – binarybob

+1

No, no es así. Agregué un código de muestra. –

+0

Gracias de nuevo Rob, eso es muy apreciado. – binarybob

0

Usando IORegisterForSystemPower no proporciona los eventos que buscan. Citando de la documentación de la función:

/*! función @ IORegisterForSystemPower

@Abstract conecta la llamada al dominio IOService potencia raíz con el propósito de recibir las notificaciones de sueño vigilia & para el sistema.

No proporciona el apagado del sistema ni reinicia las notificaciones.

Cuestiones relacionadas