2014-04-24 94 views
4

我有一個守護進程(寫在Obj C中)正在運行,並且我想在某些用戶登錄時執行某些操作。守護進程有可能知道某個特定用戶在OSX中登錄或註銷?登錄發生時是否有任何通知?我想避免使用登錄項或啓動代理。另外我想避免在定時器上輪詢以檢查登錄用戶。守護進程知道用戶何時登錄到MAC

+0

程序如何既可以是守護進程又可以是Cocoa應用程序? – trojanfoe

+0

我打算寫它在Obj C ..編輯Ques –

+0

這是一個很好的問題。你能否確認你的守護進程在* root會話中*(https://developer.apple.com/library/mac/documentation/macosx/conceptual/BPMultipleUsers/Concepts/SystemContexts.html#//apple_ref/doc/uid/ 20002208-BCICFCJH)? – trojanfoe

回答

6

使用SCDynamicStoreCopyConsoleUser獲取控制檯用戶名。

CFStringRef consoleUserName = nil; 
uid_t  uid; 
gid_t  gid; 
consoleUserName = SCDynamicStoreCopyConsoleUser(NULL, &uid, &gid); 

在某些成員變量中存儲consoleUserName。 現在創建一個會話使用SCDynamicStoreCreate

 SCDynamicStoreRef store; 
    CFStringRef   key; 
    CFArrayRef   keys; 
    CFRunLoopSourceRef rls; 
    store = SCDynamicStoreCreate(
            NULL, 
            CFSTR("com.apple.dts.ConsoleUser"), 
            callBackFunction, 
            NULL 
            ); 

    // Set it up to notify us when the console user value changes. 

    key = SCDynamicStoreKeyCreateConsoleUser(NULL); 
    assert(key != NULL); 

    keys = CFArrayCreate(NULL, (const void **) &key, 1, &kCFTypeArrayCallBacks); 
    //assert(keys != NULL); 

    success = SCDynamicStoreSetNotificationKeys(store, keys, NULL); 
    //assert(success); 

    // Add it to the runloop. 

    rls = SCDynamicStoreCreateRunLoopSource(NULL, store, 0); 
    // assert(rls != NULL); 

    CFRunLoopAddSource(CFRunLoopGetCurrent(), rls, kCFRunLoopDefaultMode); 


    mConsoleUserName = CopyCurrentConsoleUsername(store); 
    CFRunLoopRun(); 

    CFRunLoopSourceInvalidate(rls); 
    CFRelease(rls); 
    CFRelease(keys); 
    CFRelease(key); 
    CFRelease(store); 

實施callBackFunction功能通過系統配置服務器維護的動態存儲交互。當控制檯用戶值更改時,您將獲得回調。

static void callBackFunction(
           SCDynamicStoreRef store, 
           CFArrayRef   changedKeys, 
           void *    info 
           ) 
{ 
    CFStringRef   currentConsoleUser; 
    Boolean    didChange; 

    // Get the current console user. 

    currentConsoleUser = CopyCurrentConsoleUsername(store); 

    if (currentConsoleUser == NULL) 
    { 
     return; 
    } 
    didChange = ! CFEqual(storedvalue, currentConsoleUser); 
    if (![currentConsoleUser isEqualToString:@"loginwindow"]) 
    { 
     // pass this value to some method 
    } 
} 
+0

登錄用戶不一定會更改。即使同一用戶註銷並重新登錄,我也希望收到通知 –

+0

您可以按照您的要求修改callBackFunction。用戶註銷並登錄後,您將收到回電。 –

+0

當用戶註銷時,您將收到控制檯用戶更改爲「loginWindow」的通知。對於登錄,您將收到控制檯用戶更改爲「loginwindow」到「某些用戶」的通知 –