Демон, чтобы знать, когда пользователь входит в MAC
У меня работает демон (написанный на Obj C), и я хотел бы выполнить какое-либо действие, когда какой-либо пользователь входит в систему. Возможно ли, чтобы демон знал, когда конкретный пользователь входит в систему или выходит из нее в OSX? При входе в систему появляются какие-либо уведомления? Я хотел бы избежать использования элемента входа в систему или агента запуска. А также я хотел бы избежать опроса таймера для проверки вошедшего в систему пользователя.
1 ответ
Использование 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
}
}