Зарегистрируйтесь как элемент входа с Cocoa?
Google дал мне: http://developer.apple.com/samplecode/LoginItemsAE/index.html
И я решил, что должен быть лучший способ, чем использование событий AppleScript.
Итак, я загрузил источники Growl. Они используют точные источники из этой статьи разработчика Apple.
Есть ли лучший способ?
(Я ссылаюсь на элементы входа в учетные записи в системных настройках, то есть, когда моя программа запускается, когда пользователь входит в систему, программно)
Ответы
Ответ 1
Там API, который новый в Leopard называется LSSharedFileList. Одна из вещей, которую он позволяет вам сделать, - просмотреть и отредактировать список элементов входа (называемых элементами входа в сеанс в этом API).
Кстати, я ведущий разработчик Growl. Мы еще не отказались от AE, потому что мы все еще требуем Tiger, но я думаю о том, чтобы отказаться от этого для 1.2 (еще не поговорили с другими разработчиками). Когда мы удаляем Tiger, мы также отменим LoginItemsAE и перейдем к API файлов общих файлов.
EDIT с 2012 года: с 2009 года, когда я изначально написал этот ответ, Growl переключился на LSSharedFileList, и я покинул проект.
Ответ 2
Я наткнулся на Бена Кларка-Робинсона LaunchAtLoginController. Очень элегантное решение очень распространенной проблемы.
Ответ 3
Это работает на xcode 5.
- (BOOL)isLaunchAtStartup {
// See if the app is currently in LoginItems.
LSSharedFileListItemRef itemRef = [self itemRefInLoginItems];
// Store away that boolean.
BOOL isInList = itemRef != nil;
// Release the reference if it exists.
if (itemRef != nil) CFRelease(itemRef);
return isInList;
}
- (void)toggleLaunchAtStartup {
// Toggle the state.
BOOL shouldBeToggled = ![self isLaunchAtStartup];
// Get the LoginItems list.
LSSharedFileListRef loginItemsRef = LSSharedFileListCreate(NULL, kLSSharedFileListSessionLoginItems, NULL);
if (loginItemsRef == nil) return;
if (shouldBeToggled) {
// Add the app to the LoginItems list.
CFURLRef appUrl = (__bridge CFURLRef)[NSURL fileURLWithPath:[[NSBundle mainBundle] bundlePath]];
LSSharedFileListItemRef itemRef = LSSharedFileListInsertItemURL(loginItemsRef, kLSSharedFileListItemLast, NULL, NULL, appUrl, NULL, NULL);
if (itemRef) CFRelease(itemRef);
}
else {
// Remove the app from the LoginItems list.
LSSharedFileListItemRef itemRef = [self itemRefInLoginItems];
LSSharedFileListItemRemove(loginItemsRef,itemRef);
if (itemRef != nil) CFRelease(itemRef);
}
CFRelease(loginItemsRef);
}
- (LSSharedFileListItemRef)itemRefInLoginItems {
LSSharedFileListItemRef res = nil;
// Get the app URL.
NSURL *bundleURL = [NSURL fileURLWithPath:[[NSBundle mainBundle] bundlePath]];
// Get the LoginItems list.
LSSharedFileListRef loginItemsRef = LSSharedFileListCreate(NULL, kLSSharedFileListSessionLoginItems, NULL);
if (loginItemsRef == nil) return nil;
// Iterate over the LoginItems.
NSArray *loginItems = (__bridge NSArray *)LSSharedFileListCopySnapshot(loginItemsRef, nil);
for (id item in loginItems) {
LSSharedFileListItemRef itemRef = (__bridge LSSharedFileListItemRef)(item);
CFURLRef itemURLRef;
if (LSSharedFileListItemResolve(itemRef, 0, &itemURLRef, NULL) == noErr) {
// Again, use toll-free bridging.
NSURL *itemURL = (__bridge NSURL *)itemURLRef;
if ([itemURL isEqual:bundleURL]) {
res = itemRef;
break;
}
}
}
// Retain the LoginItem reference.
if (res != nil) CFRetain(res);
CFRelease(loginItemsRef);
CFRelease((__bridge CFTypeRef)(loginItems));
return res;
}
Ответ 4
Я делаю это в приложении которое я пишу:
Откажитесь от UKLoginItemRegistry за простой способ сделать это прагматично. Afaik, в Tiger нет никакого способа сделать это без Apple Events; в Leopard есть лучший способ, но если вы используете UKLoginItemRegistry, это действительно не проблема. Здесь полный код для реализации пункта меню "Открыть при входе в систему"
+ (bool)isAppSetToRunAtLogon {
int ret = [UKLoginItemRegistry indexForLoginItemWithPath:[[NSBundle mainBundle] bundlePath]];
NSLog(@"login item index = %i", ret);
return (ret >= 0);
}
- (IBAction)toggleOpenAtLogon:(id)sender {
if ([PopupController isAppSetToRunAtLogon]) {
[UKLoginItemRegistry removeLoginItemWithPath:[[NSBundle mainBundle] bundlePath]];
} else {
[UKLoginItemRegistry addLoginItemWithPath:[[NSBundle mainBundle] bundlePath] hideIt: NO];
}
}
Ответ 5
Я реорганизовал некоторые ответы здесь, чтобы предоставить категорию на NSApplication
, которая предоставляет свойство launchAtLogin
.
https://gist.github.com/joerick/73670eba228c177bceb3
Ответ 6
Посмотрите здесь пример с открытым исходным кодом: https://github.com/invariant/rhpnotifier (LoginItem.m, LoginItem.h)