• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Re: Starting my application at user login
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Starting my application at user login


  • Subject: Re: Starting my application at user login
  • From: Jerry Krinock <email@hidden>
  • Date: Sat, 12 Jan 2008 17:49:07 -0800


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 ;
}


_______________________________________________

Cocoa-dev mailing list (email@hidden)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden


  • Follow-Ups:
    • Re: Starting my application at user login
      • From: Dave Camp <email@hidden>
References: 
 >Starting my application at user login (From: "Devraj Mukherjee" <email@hidden>)

  • Prev by Date: Re: Trying to use NSStream
  • Next by Date: Re: Trying to use NSStream
  • Previous by thread: Starting my application at user login
  • Next by thread: Re: Starting my application at user login
  • Index(es):
    • Date
    • Thread