Is there a way for a C++ or Objective-C program to tell whether is it being run as a command-line application (e.g. with ./myprog
in a shell) or as an app bundle (e.g. by double-clicking on a .app in Finder or running open myprog.app/
in Terminal)?
Currently I'm using the following.
CFBundleRef bundle = CFBundleGetMainBundle();
CFURLRef bundleUrl = CFBundleCopyBundleURL(bundle);
char bundleBuf[PATH_MAX];
CFURLGetFileSystemRepresentation(bundleUrl, TRUE, (UInt8*) bundleBuf, sizeof(bundleBuf));
At this point, bundleBuf
now holds the path to the .app bundle or the directory containing the command-line executable. I can check whether the string ends with ".app"
, but this is hacky. Is there a better way to do this?
You can query the Uniform Type Identifier (UTI) of the URL (using CFURLCopyResourcePropertyForKey()
with kCFURLTypeIdentifierKey
) and see if it conforms to kUTTypeApplicationBundle
(using UTTypeConformsTo()
).
CFStringRef uti;
if (CFURLCopyResourcePropertyForKey(bundleUrl, kCFURLTypeIdentifierKey, &uti, NULL) &&
uti &&
UTTypeConformsTo(uti, kUTTypeApplicationBundle))
{
// Is bundled application
}
Using Objective-C, you can use the NSWorkspace
methods -typeOfFile:error:
and -type:conformsToType:
for the same purpose.