守护进程知道用户何时登录到MAC [英] Daemon to know when a user logs into the MAC

查看:312
本文介绍了守护进程知道用户何时登录到MAC的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个守护进程(以Obj C编写)运行,我想在某些用户登录时执行一些操作。守护进程可以知道特定用户在OSX中登录或注销的时间。当发生登录时,是否有任何通知被抛出?我想避免使用登录项或启动代理。

解决方案

使用 SCDynamicStoreCopyConsoleUser 获取控制台用户名。

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

在某些成员变量中存储 consoleUserName
现在使用 SCDynamicStoreCreate



<$ p>创建一个与系统配置服务器维护的动态存储交互的会话$ p> SCDynamicStoreRef store;
CFStringRef key;
CFArrayRef keys;
CFRunLoopSourceRef rls;
store = SCDynamicStoreCreate(
NULL,
CFSTR(com.apple.dts.ConsoleUser),
callBackFunction,
NULL
);

//设置它以在控制台用户值更改时通知我们。

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

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

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

//将其添加到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;

//获取当前控制台用户。

currentConsoleUser = CopyCurrentConsoleUsername(store);

if(currentConsoleUser == NULL)
{
return;
}
didChange =! CFEqual(storedvalue,currentConsoleUser);
if(![currentConsoleUser isEqualToString:@loginwindow])
{
//将此值传递给某些方法
}
}


I have a daemon (written in Obj C) running, and I would like to perform some action when some user logs in. Is it possible for a Daemon to know when a particular user logs in or out in OSX? Are there any Notifications thrown when a log in occurs? I would like to avoid the use of Log in Item or Launch Agent. And also i would like to avoid polling on a timer to check the logged in user.

解决方案

Use SCDynamicStoreCopyConsoleUser to get the console user name.

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

Store consoleUserName in some member variable. Now creates a session to interact with the dynamic store maintained by the System Configuration server using 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);   

Implement callBackFunction function. You will get callback when the console user value changes.

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

这篇关于守护进程知道用户何时登录到MAC的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆