Search code examples
c++objective-capp-bundle

Check if C++ program is running as an app bundle or command-line on Mac


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?


Solution

  • 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.