在 Mac OS El Capitan 安装后自动启动应用程序
Automatically start app after install in Mac OS El Capitan
我正在开发一个 OSX 应用程序,它将在应用程序商店之外分发。我已经存档并创建了 pkg 文件,但是当我安装应用程序时它不会自动启动。我必须从启动板手动启动它。下面是我在我的 appdelegate 中添加的代码,用于在启动时显示它。
- (void)installAppIntoLoginItems {
if (![self appIsInLoginItems]) {
// Get the LoginItems list.
LSSharedFileListRef loginItemsRef = LSSharedFileListCreate(NULL, kLSSharedFileListSessionLoginItems, NULL);
if (loginItemsRef == nil) return;
// Add the app to the LoginItems list.
LSSharedFileListItemRef itemRef = LSSharedFileListInsertItemURL(loginItemsRef, kLSSharedFileListItemLast, NULL, NULL, (__bridge CFURLRef)helperAppURL, NULL, NULL);
if (itemRef) {
CFRelease(itemRef);
}
CFRelease(loginItemsRef);
}
else {
// App is in the LoginItems List
NSLog(@"App is already in LoginItems List");
}
}
- (BOOL) appIsInLoginItems {
// 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;
}
- (LSSharedFileListItemRef)itemRefInLoginItems {
LSSharedFileListItemRef itemRef = nil;
CFURLRef itemUrl = NULL;
// 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 (int currentIndex = 0; currentIndex < [loginItems count]; currentIndex++) {
// Get the current LoginItem and resolve its URL.
LSSharedFileListItemRef currentItemRef = (__bridge LSSharedFileListItemRef)[loginItems objectAtIndex:currentIndex];
// if (LSSharedFileListItemResolve(currentItemRef, 0, (CFURLRef *) &itemUrl, NULL) == noErr) { //Replacing deprecated method
if( LSSharedFileListItemCopyResolvedURL(currentItemRef, 0, NULL) == noErr) {
// Compare the URLs for the current LoginItem and the app.
if ([(__bridge NSURL*)itemUrl isEqual:helperAppURL]) {
// Save the LoginItem reference.
itemRef = currentItemRef;
}
}
}
// Retain the LoginItem reference.
if (itemRef != nil) CFRetain(itemRef);
// Release the LoginItems lists.
CFRelease(loginItemsRef);
return itemRef;
}
我必须使用其他替代方法吗?有什么样品可以参考吗?
您可以使用启动代理:
我想将它作为登录项的好处是用户可能会自己弄清楚如何将其删除。如果您使用 LaunchAgent,您可能必须在您的应用中构建一个 "startup at login" 首选项。
我能够使用 SMLoginItemSetEnabled 方法解决登录时自动启动应用程序的问题,并且能够使用安装后脚本实现安装后自动启动
if (!SMLoginItemSetEnabled ((__bridge CFStringRef)helperAppBundleIdentifier, YES))
{
NSAlert *alert = [NSAlert alertWithMessageText:@"An error ocurred" defaultButton:@"OK" alternateButton:nil otherButton:nil informativeTextWithFormat:@"Couldn't add Helper App to launch at login item list."];
[alert runModal];
}
我正在开发一个 OSX 应用程序,它将在应用程序商店之外分发。我已经存档并创建了 pkg 文件,但是当我安装应用程序时它不会自动启动。我必须从启动板手动启动它。下面是我在我的 appdelegate 中添加的代码,用于在启动时显示它。
- (void)installAppIntoLoginItems {
if (![self appIsInLoginItems]) {
// Get the LoginItems list.
LSSharedFileListRef loginItemsRef = LSSharedFileListCreate(NULL, kLSSharedFileListSessionLoginItems, NULL);
if (loginItemsRef == nil) return;
// Add the app to the LoginItems list.
LSSharedFileListItemRef itemRef = LSSharedFileListInsertItemURL(loginItemsRef, kLSSharedFileListItemLast, NULL, NULL, (__bridge CFURLRef)helperAppURL, NULL, NULL);
if (itemRef) {
CFRelease(itemRef);
}
CFRelease(loginItemsRef);
}
else {
// App is in the LoginItems List
NSLog(@"App is already in LoginItems List");
}
}
- (BOOL) appIsInLoginItems {
// 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;
}
- (LSSharedFileListItemRef)itemRefInLoginItems {
LSSharedFileListItemRef itemRef = nil;
CFURLRef itemUrl = NULL;
// 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 (int currentIndex = 0; currentIndex < [loginItems count]; currentIndex++) {
// Get the current LoginItem and resolve its URL.
LSSharedFileListItemRef currentItemRef = (__bridge LSSharedFileListItemRef)[loginItems objectAtIndex:currentIndex];
// if (LSSharedFileListItemResolve(currentItemRef, 0, (CFURLRef *) &itemUrl, NULL) == noErr) { //Replacing deprecated method
if( LSSharedFileListItemCopyResolvedURL(currentItemRef, 0, NULL) == noErr) {
// Compare the URLs for the current LoginItem and the app.
if ([(__bridge NSURL*)itemUrl isEqual:helperAppURL]) {
// Save the LoginItem reference.
itemRef = currentItemRef;
}
}
}
// Retain the LoginItem reference.
if (itemRef != nil) CFRetain(itemRef);
// Release the LoginItems lists.
CFRelease(loginItemsRef);
return itemRef;
}
我必须使用其他替代方法吗?有什么样品可以参考吗?
您可以使用启动代理:
我想将它作为登录项的好处是用户可能会自己弄清楚如何将其删除。如果您使用 LaunchAgent,您可能必须在您的应用中构建一个 "startup at login" 首选项。
我能够使用 SMLoginItemSetEnabled 方法解决登录时自动启动应用程序的问题,并且能够使用安装后脚本实现安装后自动启动
if (!SMLoginItemSetEnabled ((__bridge CFStringRef)helperAppBundleIdentifier, YES))
{
NSAlert *alert = [NSAlert alertWithMessageText:@"An error ocurred" defaultButton:@"OK" alternateButton:nil otherButton:nil informativeTextWithFormat:@"Couldn't add Helper App to launch at login item list."];
[alert runModal];
}