GetProcessBundleLocation() -- no good in background agents!
GetProcessBundleLocation() -- no good in background agents!
- Subject: GetProcessBundleLocation() -- no good in background agents!
- From: Jerry Krinock <email@hidden>
- Date: Wed, 25 Mar 2009 16:20:12 -0700
If you install a background agent into an application package, and
said tool invokes
[[NSBundle mainBundle] bundlePath] ;
it gives the expected path with no side effects. But if instead said
tool invokes the equivalent Carbon function,
GetProcessBundleLocation()
it also gives the path but the bundle's icon will start bouncing in
the dock and remain bouncing until the tool quits. It's like the
system is trying to launch the application. Also, if your tool tries
to launch the main app while this bouncing is going on, /usr/bin/open
or NSWorkspace methods will fail but report success.
Is it a bug? Does anyone know if this is part of a more general class
of API that should not be used in background agents? Is there
anywhere a concise list of all the API which should not be invoked in
background agents? I'm aware that a daemon run as root should not
link AppKit for security reasons, but here the subject is merely a
background agent, run as the current user to help with an application.
By the way, I learned this by including the Growl framework in a
background tool. Growl uses GetProcessBundleLocation(). The self-
installer is another reason not to use Growl in a background agent.
Probably there are more reasons I've not "discovered" yet.
If anyone would like to play with this, here's a demo...
/* Use this code to build a Cocoa Command-Line tool and place
the product in Contents/MacOS of any application. Then
doubleclick it. Watch the log in the Terminal window and
un-hide and watch your dock.
Warning: If you try installing it into an app's bundle with
Xcode and running from within Xcode, it won't work because
Xcode will place a symlink in your regular builds location
and run the symlink, and some bundle-finding methods
don't follow symlinks. Use a Custom Executable. */
#include <Carbon/Carbon.h>
int main(int argc, const char *argv[]) {
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init] ;
NSBundle* bundle = [NSBundle mainBundle] ;
NSString* bundlePath = [bundle bundlePath] ;
NSLog(@"Your Cocoa bundle path is: %@", bundlePath) ;
ProcessSerialNumber psn = { 0, kCurrentProcess };
FSRef fsref;
NSLog(@"[[NSBundle mainBundle] bundlePath] did not cause bounce") ;
usleep(5000000) ;
OSStatus err = GetProcessBundleLocation(&psn, &fsref);
NSLog(@"GetProcessBundleLocation() has just caused dock
bouncing") ;
usleep(5000000) ;
NSLog(@"GetProcessBundleLocation err = %li", err) ;
CFURLRef url = NULL ;
url = CFURLCreateFromFSRef(kCFAllocatorDefault, &fsref);
NSString* carbonBundlePath = [(NSURL*)url path] ;
/*DB?Line*/ NSLog(@"Your Carbon bundle path is %@",
carbonBundlePath) ;
[pool release] ;
NSLog(@"exitting") ;
return 0 ;
}
_______________________________________________
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