PDA

View Full Version : Can i identify if application run from Login Items?




newformac
Jun 7, 2011, 06:34 AM
Hi all,

How can an application determine if it was launched as a Startup Item
on logging in to Mac OS or a usual way like (double)clicking it's
icon?

please provide me guidance for this.

i m check this sample code to detect the app launch from Login Items or Not.



+ (BOOL)wasLaunchedAsLoginItem
{
// If the launching process was 'loginwindow', we were launched as a
login item
return [self wasLaunchedByProcess:@"lgnw"];
}

+ (BOOL)wasLaunchedByProcess:(NSString*)creator
{
BOOL wasLaunchedByProcess = NO;

// Get our PSN
OSStatus err;
ProcessSerialNumber currPSN;
err = GetCurrentProcess (&currPSN);
if (!err) {
// Get information about our process
NSDictionary* currDict = (NSDictionary*)
ProcessInformationCopyDictionary (&currPSN,
kProcessDictionaryIncludeAllInformationMask);

// Get the PSN of the app that *launched* us. Its not really the
parent app, in the unix sense.
long long temp = [[currDict objectForKey:@"ParentPSN"] longLongValue];
[currDict release];
long long hi = (temp >> 32) & 0x00000000FFFFFFFFLL;
long long lo = (temp >> 0) & 0x00000000FFFFFFFFLL;
ProcessSerialNumber parentPSN = {(unsigned long)hi, (unsigned long)lo};

// Get info on the launching process
NSDictionary* parentDict = (NSDictionary*)
ProcessInformationCopyDictionary (&parentPSN,
kProcessDictionaryIncludeAllInformationMask);

// Test the creator code of the launching app
wasLaunchedByProcess = [[parentDict objectForKey:@"FileCreator"]
isEqualToString:creator];
[parentDict release];
}

return wasLaunchedByProcess;
}




but its not working.

thanks in advance.



kainjow
Jun 8, 2011, 12:12 PM
Have you stepped through that code to see why it's not working?

newformac
Jun 8, 2011, 11:52 PM
it's not working? means its not identify the app running from Startup Login Items or simply by clicking over the application.

jiminaus
Jun 9, 2011, 04:21 AM
it's not working? means its not identify the app running from Startup Login Items or simply by clicking over the application.

What I think kainjow was asking for was why was the code not working. These are all questions you should have asked yourself.

Am I getting the current process serial number?
Am I getting the parent's process serial number?
Am I getting the file creator of the parent's process?
What is the file creator of the parent's process?

Normally to answer these questions you should have set a breakpoint at the top of wasLaunchedByProcess: and then step through the code looking at the results of each statement.

I granted you would have been able to do this during start up. But you should have been able to add to code to open a file, log the results of the method as it goes along, and the close the file. After you've logged in, you should have been able to open the file and see what happened.

Now I can tell you that this code does work in both 32-bit and 64-bit Intel builds on Mac OS X 10.6.7.

newformac
Jun 9, 2011, 05:28 AM
i m getting these values when i debug this method


currPSN = 0x03e03e ("FileCreater")

currDict = 0x1029720 18 key/value pairs

parentPSN = 0x029029 ("Xcode")

parentDict= 0x109ca40 20 key/value pairs

jiminaus
Jun 9, 2011, 05:55 AM
i m getting these values when i debug this method


currPSN = 0x03e03e ("FileCreater")

currDict = 0x1029720 18 key/value pairs

parentPSN = 0x029029 ("Xcode")

parentDict= 0x109ca40 20 key/value pairs



These values are to be expected when you run your code under Xcode. When it's run as a login item, parentPSN will be the PSN of loginwindow (creator code lgnw).

newformac
Jun 9, 2011, 06:41 AM
if i check this for Xcode its still return no


+ (BOOL)wasLaunchedAsLoginItem
{
return [self wasLaunchedByProcess:@"Xcode"];
}



can u please tell me how can i get the string value for parent name like here it is Xcode from parentPSN or parentDict.

jiminaus
Jun 9, 2011, 06:59 AM
if i check this for Xcode its still return no


+ (BOOL)wasLaunchedAsLoginItem
{
return [self wasLaunchedByProcess:@"Xcode"];
}



can u please tell me how can i get the string value for parent name like here it is Xcode from parentPSN or parentDict.

XCode doesn't have a viable creator code. Creator codes are archaic. Migrate your code from using creator codes to using bundle identifiers.

You can a process's bundle identifier with code like this.

[processInformationDictionary objectForKey:(NSString *)kCFBundleIdentifierKey]


The bundle identifier of loginwindow is com.apple.loginwindow. The bundle identifier of Xcode is com.apple.dt.Xcode.

newformac
Jun 9, 2011, 07:12 AM
thanks now when i launch it from startup its return com.apple.loginwindow and when i launch it from simply click over my app its return com.apple.finder or if click from dock view return com.apple.dock



//this give the name of parent

NSString* parent_name_str=[parentDict objectForKey:(NSString *)kCFBundleNameKey];

return value like "Xcode","Finder","Dock","Loginwindow"


i want to ask its return com.apple.loginwindow or Loginwindow for all version of mac os.

so now i compare result with com.apple.loginwindow or Loginwindow to check app launch from login item or not.

jiminaus
Jun 9, 2011, 07:33 AM
According to the Process Manager Reference (http://developer.apple.com/library/mac/#documentation/Carbon/Reference/Process_Manager), the ProcessInformationCopyDictionary function was introduced in Mac OS X 10.2. But I don't know when bundle identifiers where introduced. You'd need to test on old versions of Mac OS X to see how far back it works. You'd need to test on old versions of Mac OS X anyway if your wanting to claim support of them.

EDIT: A quick Google search revealed posts dating back to at least 2002. Particularly the function CFBundleGetBundleWithIdentifier is available since 10.0, so it seems Mac OS X has always had bundle identifiers. Creator codes seem to be purely a legacy of classic Mac OS.

newformac
Jun 9, 2011, 07:37 AM
thanks for your information and guidance.

jiminaus
Jun 9, 2011, 07:47 AM
//this give the name of parent
NSString* parent_name_str=[parentDict objectForKey:(NSString *)kCFBundleNameKey];
return value like "Xcode","Finder","Dock","Loginwindow"



You're ill-advised to use bundle name. The correct way to uniquely identifier a bundle is, naturally enough, by it bundle identifier, not by it's name. Names are not unique or stable.

newformac
Jun 9, 2011, 11:36 PM
thanks for ur valuable suggestions.