Find the filename that launched your OS X app

若如初见. 提交于 2019-12-11 06:19:59

问题


Setting the info of a file you can associate an app with a particular file type so that when clicked the application is launched. My question is how the app can discover the full filename of the file that caused it to be launched.


回答1:


Mac apps are not launched every time an associated file is opened. They may be launched, but if they're already running, then they're just asked to open another file. So the path doesn't come to the app via the commandline. It's sent as a message to the application, which needs to process a run loop (NSRunLoop) to receive it.

In a regular Cocoa program, you implement an NSApplicationDelegate, and implement the method (in ObjC naming):

- (BOOL)application:(NSApplication *)sender openFile:(NSString *)filename;

If you only support 10.13+, the preferred method has changed to:

- (void)application:(NSApplication *)application openURLs:(NSArray<NSURL *> *)urls;

The OS will call this when your application needs to open a file if there's an NSApplication object running to accept it. Typically you create an NSApplication object by calling NSApplicationMain(), but you can implement your own version of NSApplicationMain() if you need to (see the NSApplication docs for details).

It is possible to respond to these open requests without an NSApplication, or any Objective-C, by implementing Apple Events yourself and responding to the odoc (open document; { kCoreEventClass, kAEOpenDocuments }) message. To attack that, see The Apple Events Programming Guide.

You should expect to write some piece of code that installs an event handler like:

err     = AEInstallEventHandler(kCoreEventClass, kAEOpenDocuments,
            NewAEEventHandlerUPP(OpenDocumentsAE), 0, false);
require_noerr(err, CantInstallAppleEventHandler);

And then you would actually handle the message in OpenDocumentsAE (taken from "A Handler for the Open Documents Apple Event"):

static pascal OSErr OpenDocumentsAE(const AppleEvent *theAppleEvent, AppleEvent *reply, long handlerRefcon)
{
    AEDescList  docList;
    FSRef       theFSRef;
    long        index;
    long        count = 0;
    OSErr       err = AEGetParamDesc(theAppleEvent,
                            keyDirectObject, typeAEList, &docList);// 1
    require_noerr(err, CantGetDocList);// 2

    err = AECountItems(&docList, &count);// 3
    require_noerr(err, CantGetCount);

    for(index = 1; index <= count; index++)// 4
    {
        err = AEGetNthPtr(&docList, index, typeFSRef,
                        NULL, NULL, &theFSRef, sizeof(FSRef), NULL);// 5
        require_noerr(err, CantGetDocDescPtr);

        err = OpenDocument(&theFSRef);// 6
    }
    AEDisposeDesc(&docList);// 7

CantGetDocList:
CantGetCount:
CantGetDocDescPtr:
    if (err != noErr)// 8
    {
        // For handlers that expect a reply, add error information here.
    }
    return(err);// 9
}


来源:https://stackoverflow.com/questions/53803912/find-the-filename-that-launched-your-os-x-app

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!