如何在登录时打开您的应用程序?

时间:2009-05-02 15:41:08

标签: cocoa login

只是想知道如何在登录时自动打开我的应用程序,但是可以使用首选项窗口中的复选框打开和关闭它。

4 个答案:

答案 0 :(得分:39)

这是我使用的一些代码,它基于Growl源代码。

+ (BOOL) willStartAtLogin:(NSURL *)itemURL
{
    Boolean foundIt=false;
    LSSharedFileListRef loginItems = LSSharedFileListCreate(NULL, kLSSharedFileListSessionLoginItems, NULL);
    if (loginItems) {
        UInt32 seed = 0U;
        NSArray *currentLoginItems = [NSMakeCollectable(LSSharedFileListCopySnapshot(loginItems, &seed)) autorelease];
        for (id itemObject in currentLoginItems) {
            LSSharedFileListItemRef item = (LSSharedFileListItemRef)itemObject;

            UInt32 resolutionFlags = kLSSharedFileListNoUserInteraction | kLSSharedFileListDoNotMountVolumes;
            CFURLRef URL = NULL;
            OSStatus err = LSSharedFileListItemResolve(item, resolutionFlags, &URL, /*outRef*/ NULL);
            if (err == noErr) {
                foundIt = CFEqual(URL, itemURL);
                CFRelease(URL);

                if (foundIt)
                    break;
            }
        }
        CFRelease(loginItems);
    }
    return (BOOL)foundIt;
}

+ (void) setStartAtLogin:(NSURL *)itemURL enabled:(BOOL)enabled
{
    OSStatus status;
    LSSharedFileListItemRef existingItem = NULL;

    LSSharedFileListRef loginItems = LSSharedFileListCreate(NULL, kLSSharedFileListSessionLoginItems, NULL);
    if (loginItems) {
        UInt32 seed = 0U;
        NSArray *currentLoginItems = [NSMakeCollectable(LSSharedFileListCopySnapshot(loginItems, &seed)) autorelease];
        for (id itemObject in currentLoginItems) {
            LSSharedFileListItemRef item = (LSSharedFileListItemRef)itemObject;

            UInt32 resolutionFlags = kLSSharedFileListNoUserInteraction | kLSSharedFileListDoNotMountVolumes;
            CFURLRef URL = NULL;
            OSStatus err = LSSharedFileListItemResolve(item, resolutionFlags, &URL, /*outRef*/ NULL);
            if (err == noErr) {
                Boolean foundIt = CFEqual(URL, itemURL);
                CFRelease(URL);

                if (foundIt) {
                    existingItem = item;
                    break;
                }
            }
        }

        if (enabled && (existingItem == NULL)) {
            LSSharedFileListInsertItemURL(loginItems, kLSSharedFileListItemBeforeFirst,
                                          NULL, NULL, (CFURLRef)itemURL, NULL, NULL);

        } else if (!enabled && (existingItem != NULL))
            LSSharedFileListItemRemove(loginItems, existingItem);

        CFRelease(loginItems);
    }       
}

如果您想要一个易于实现的复选框,请在其中一个类中创建@property BOOL startAtLogin;并按如下方式实现它。只需将复选框值绑定到属性,它就可以无缝地工作。

- (NSURL *)appURL
{
    return [NSURL fileURLWithPath:[[NSBundle mainBundle] bundlePath]];
}

- (BOOL)startAtLogin
{
    return [LoginItem willStartAtLogin:[self appURL]];
}

- (void)setStartAtLogin:(BOOL)enabled
{
    [self willChangeValueForKey:@"startAtLogin"];
    [LoginItem setStartAtLogin:[self appURL] enabled:enabled];
    [self didChangeValueForKey:@"startAtLogin"];
}

答案 1 :(得分:19)

CocoaDev处有一个很好的描述。

基本上,如果您可以定位Mac OS X 10.5或更高版本,则需要在LaunchServices / LSSharedFileList.h中使用API​​。 10.5之前没有干净的API,因此您必须手动操作登录项(Sample code at the Developer Connectiong)。

这是我在评论中提到的Leopard的sample code (死)。通过this blog post找到。在登录时启用或禁用启动所需的代码位于Controller.m。

答案 2 :(得分:12)

使用指向应用程序的文件URL调用下面粘贴的方法,将其添加到当前用户的登录项目中。

要再次禁用,您需要获取相同的loginListRef,将其转换为数组,然后遍历它,直到找到包含要禁用的url的项目。最后,使用适当的参数调用LSSharedFileListItemRemove。

祝你好运:)

- (void)enableLoginItemWithURL:(NSURL *)itemURL
{
    LSSharedFileListRef loginListRef = LSSharedFileListCreate(NULL, kLSSharedFileListSessionLoginItems, NULL);

    if (loginListRef) {
        // Insert the item at the bottom of Login Items list.
        LSSharedFileListItemRef loginItemRef = LSSharedFileListInsertItemURL(loginListRef, 
                                             kLSSharedFileListItemLast, 
                                             NULL, 
                                             NULL,
                                             (CFURLRef)itemURL, 
                                             NULL, 
                                             NULL);     
        if (loginItemRef) {
            CFRelease(loginItemRef);
        }
        CFRelease(loginListRef);
    }
}

答案 3 :(得分:3)