Reputation: 8077
I've got a Cocoa command-line app which is built to target 10.5 SDK. In the app, I have
NSString *appPath = [[NSBundle mainBundle] bundlePath];
NSLog(@"%@", appPath);
On Mac OSX 10.5, when I run the app from the command line, I get the expected output of the path. However, if I set the app up to run as a LaunchDeamon, it only outputs a '/'
It works as expected on 10.6 and on 10.7 both as a Deamon and as an app. Anyone know why the difference would be? Is there a better way to get the application path that would work on 10.5+?
UPDATE
For me, the solution in the accepted answer did not work. However, the comment about adding the "WorkingDirectory" key to the LaunchDeamon's plist file worked out. Apparently this is needed for Mac OS X 10.5, but not 10.6+.
Upvotes: 0
Views: 192
Reputation: 89509
Thanks for answering my clarifying question.
NSBundle depends on a existing bundle, with it's associated Info.plists and bundle ID's (e.g. com.apple.textedit.app
), etc.
While a single binary is not a bundle, I'm guessing that Apple engineering fixed up [[NSBundle mainBundle] bundlePath]
to do "the right thing" in 10.6 & 10.7. But you still need a solution for 10.5.
Maybe the UNIX library function char * getcwd(char *buf, size_t size)
would get you to where you need to be.
For a proper solution, I'd recommend doing a run-time conditional check with code that looks something like this:
+ (NSString *) getAppPath
{
NSString * appPath = NULL;
SInt32 minorVersionNum;
OSErr err;
err = Gestalt(gestaltSystemVersionMinor,&minorVersionNum);
// do this only if we're running on anything *older* than 10.6
if((noErr == err) && (minorVersionNumber < 6))
{
// hopefully the below define is enough space for any returned path
#define kMaxPathLength 512
size_t bufferLength = kMaxPathLength;
char bufferToHoldPath[kMaxPathLength];
// initialize the buffer & guarantee null-terminated strings
bzero(&bufferToHoldPath,bufferLength);
if( getcwd(&bufferToHoldPath, bufferLength) != NULL)
{
appPath = [NSString stringWithUTF8String: bufferToHoldPath];
}
}
// this code runs for 10.6 and *newer*, and attempts it on
// 10.5 only if the above getcwd call failed
if(NULL == appPath)
{
appPath = [[NSBundle mainBundle] bundlePath];
}
return(appPath);
}
I did not test this code out so YMMV.
Upvotes: 1