2009-08-24 7 views
5

J'écris une application en C pour le Mac (Leopard) qui a besoin de faire un peu de travail à la réception des notifications de puissance, par ex. sommeil, réveil, arrêt, redémarrage. Il fonctionne via launchd en tant que launchagent lors de la connexion, puis commence à surveiller les notifications. Le code que je utilise pour ce faire est la suivante:Recevoir des notifications de puissance (en particulier shutdown) sur 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; 
    } 
} 

Cependant, seuls les deux premiers pour dormir et se réveiller (kIOMessageSystemWillSleep et kIOMessageSystemHasPoweredOn) jamais obtenir appelé. Je ne reçois jamais aucune notification pour le redémarrage ou l'arrêt (kIOMessageSystemWillRestart et kIOMessageSystemWillPowerOff).

Est-ce que je fais quelque chose de mal? Ou y a-t-il une autre API qui me donnerait les notifications de redémarrage et d'arrêt? Je préférerais le garder comme un programme C (comme c'est ce que je connais) mais je suis ouvert à toutes les suggestions judicieuses d'alternatives (j'ai regardé les hooks de connexion/déconnexion mais ceux-ci semblent être dépréciés en faveur de launchd).

Merci d'avance pour toute aide/conseils!

Répondre

4

Je sais que vous pouvez vous inscrire à la notification NSWorkspaceWillPowerOffNotification de NSWorkspace, qui n'est pas une fonction C mais fonctionne.

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

Puis, en WorkspaceResponder.m:

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

Merci pour cela! Savez-vous si j'ai besoin d'une icône de fenêtre ou de dock pour recevoir ces notifications? – binarybob

+1

Non, vous ne le faites pas. J'ai ajouté un exemple de code. –

+0

Merci encore Rob, c'est très apprécié. – binarybob

0

L'utilisation IORegisterForSystemPower ne fournit pas les événements que vous recherchez. Citant de la documentation de la fonction:

/*! @function IORegisterForSystemPower

@Abstract connecte l'appelant à la puissance domaine racine IOService dans le but de recevoir le sommeil & notifications de réveil pour le système.

Ne fournit pas les notifications d'arrêt et de redémarrage du système.

Questions connexes