Re: Starting my application at user login
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