Starting my application at user login

  • Hi everyone,

    I wish to start my application on "User Login", much like iChat. Any
    resources/links on how to do this?

    Thanks a lot.

    --
    "I never look back darling, it distracts from the now", Edna Mode (The
    Incredibles)
  • On 2008 Jan, 12, at 14:35, Devraj Mukherjee wrote:

    > I wish to start my application on "User Login", much like iChat. Any
    > resources/links on how to do this?

    You need to install it into Login Items.  Normally this is added/
    removed in response to a user preference.

    To install or remove an item from Login Items, the last time I
    researched this, maybe 15 months ago, the recommended method was to
    use Apple's LoginItemsAE sample code.  You can find this code by
    searching ADC.  This works 99.5% of the time, if you bump the timeout
    in there from 5 seconds up to 10 seconds.  I filed a bug and they made
    it better in Leopard.  The problem that it uses System Events, which
    is sometimes too busy to respond.  Funny, I'd never seen a failure in
    18a couple hours ago it failed on me when I ran my app.

    So I use the wrapper functions below to alert the user and retry.  I
    didn't include all my little utilities that are depended upon, but you
    can get the idea.

    If you find that a different way is now recommended, please let me
    know.  (If you search the list archives you will also find a
    supposedly evil, non-recommended, but much simpler method of writing
    directly to the Login Items plist.)

    Jerry

    #import "LoginItemsAE.h"

    // This function is invoked by the next function
    enum SSResult SSTryAddDeleteUserLoginItem(NSString* filePath, BOOL
    hide, BOOL doAdd, OSStatus* pErr)
    {
        enum SSResult result = SSResultNoAction ;

        NSMutableArray* loginItems = nil ;
        NSMutableArray** loginItemsPtr = &loginItems;
        //CFArrayRef* loginItemsPtr = (CFArrayRef*)&loginItems ;
        //NSLog(@"%x %x %x %x %x", *loginItems, loginItems, &loginItems,
    loginItemsPtr, *loginItemsPtr) ;

        int i;

        if (!pErr) {
            OSStatus err ;
            pErr = &err ;
        }

        *pErr = LIAECopyLoginItems((CFArrayRef*)loginItemsPtr) ;

        int iOurIndex = NSNotFound ;
        if (*pErr == noErr)
        {
            NSString* executableName = [filePath lastPathComponent] ;
            for (i = 0; i < [loginItems count]; i++)
            {
                NSDictionary* itemDict = [loginItems objectAtIndex:i];
                NSString* itemPath = (NSString*)[[itemDict
    objectForKey:@"URL"] absoluteString] ;
                if ([itemPath rangeOfString:executableName].location !=
    NSNotFound) {
                    iOurIndex = i ;
                }
            }
        }

        SSLog(5, "SSAddDeleteUserLoginItem: err=%i, iOurIndex=%i, doAdd=
    %i", *pErr, iOurIndex, doAdd) ;
        if ((*pErr==noErr) && (iOurIndex==NSNotFound) && doAdd)
        {
            // Target filePath is not currently a login item but caller
    wants it in
            // So we add it
            SSLog(5, "Adding login item") ;
            NSURL* fileURL = [NSURL fileURLWithPath:filePath] ;
            *pErr = LIAEAddURLAtEnd((CFURLRef)fileURL, YES) ;
            result = SSResultAdded ;
        }
        else if ((*pErr==noErr) && (iOurIndex!=NSNotFound) && !doAdd)
        {
            // Target filePath is currently a login item but caller wants
    it out
            // So we remove it
            SSLog(5, "Removing login item") ;
            *pErr = LIAERemove(iOurIndex) ;
            result = SSResultRemoved ;
        }

        if (*pErr != noErr)
        {
            result = SSResultFailed ;
            SSLog(0, "Login Items AE failed, err %i", *pErr) ;
        }

        [loginItems release];

        return result ;
    }

    enum SSResult SSAddDeleteUserLoginItem(NSString* filePath, BOOL hide,
    BOOL doAdd)
    {
        OSStatus err ;

        enum SSResult result = SSResultFailed;

        if (filePath) {
            result = SSTryAddDeleteUserLoginItem(filePath, hide, doAdd,
    &err) ;

            if (result == SSResultFailed) {
                // Try again with dialogs shown to user
                int unsigned oldPID =
    SSPIDOfRunningExecutableNamed(@"System Events") ;
                int alertReturn ;
                alertReturn = NSRunInformationalAlertPanel(
                        nil,
                        [NSString stringWithFormat:@"Your System Events
    process (pid=%i) returned error %i to our request for Login Items.
    Since it is not working, we'd like to kill and then restart your
    System Events process.  That usually fixes the problem.", oldPID, err],
                        nil,
                        NSLocalizedString(@"cancel", nil),
                        nil) ;
                if (alertReturn == NSAlertDefaultReturn) {
                    if (oldPID) {
                        SSKillProcess(oldPID, YES) ;
                        result = SSTryAddDeleteUserLoginItem(filePath,
    hide, doAdd, &err)    ;
                        if (result == SSResultFailed)
                        {
                            NSRunInformationalAlertPanel(
                                        NSLocalizedString(@"sorry", nil),
                                        [NSString
    stringWithFormat:@"Still didn't work.  err = %i.", err],
                                        nil,
                                        nil,
                                        nil) ;
                        } else {
                            alertReturn = NSRunInformationalAlertPanel(
                                        NSLocalizedString(@"itWorked",
    nil),
                                        @"That fixed it",
                                        nil,
                                        nil,
                                        nil) ;
                        }
                    }
                }
            }
        }

        return result ;
    }
  • On Jan 12, 2008, at 5:49 PM, Jerry Krinock wrote:

    >
    > On 2008 Jan, 12, at 14:35, Devraj Mukherjee wrote:
    >
    >> I wish to start my application on "User Login", much like iChat. Any
    >> resources/links on how to do this?
    >
    > You need to install it into Login Items.  Normally this is added/
    > removed in response to a user preference.

    For Tiger and beyond you should use launchd and not the old Login
    Items mechanism.

    See <http://developer.apple.com/technotes/tn2005/tn2083.html>

    Dave
  • On Jan 12, 2008 10:53 PM, Dave Camp <dave...> wrote:
    > For Tiger and beyond you should use launchd and not the old Login
    > Items mechanism.
    >
    > See <http://developer.apple.com/technotes/tn2005/tn2083.html>

    launchd agents are broken on 10.4, as per the warning on the technote
    you linked.

    --Kyle Sluder
  • On Jan 13, 2008 7:53 AM, Kyle Sluder <kyle.sluder+<cocoa-dev...> wrote:
    > On Jan 12, 2008 10:53 PM, Dave Camp <dave...> wrote:
    >> For Tiger and beyond you should use launchd and not the old Login
    >> Items mechanism.
    >>
    >> See <http://developer.apple.com/technotes/tn2005/tn2083.html>
    >
    > launchd agents are broken on 10.4, as per the warning on the technote
    > you linked.

    You shouldn't use Login Items for Agents, but if you do want to modify
    Login Items there is a new supported way of doing so in Leopard as
    well. See LSSharedFileList.h

    -- Finlay
previous month january 2008 next month
MTWTFSS
  1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31      
Go to today