查找启动OS X应用的文件名

时间:2018-12-16 15:59:49

标签: macos launch-services

设置文件信息,您可以将应用程序与特定文件类型相关联,以便在单击该应用程序时启动。 我的问题是,应用程序如何发现导致其启动的文件的完整文件名。

1 个答案:

答案 0 :(得分:3)

每次打开关联文件时,不会启动Mac应用程序。它们可能已启动,但是如果它们已经在运行,则只要求它们打开另一个文件。因此,路径不会通过命令行到达应用程序。它作为消息发送到应用程序,该应用程序需要处理一个运行循环(NSRunLoop)才能接收它。

在常规的Cocoa程序中,您实现一个NSApplicationDelegate并实现该方法(以ObjC命名):

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

如果您仅支持10.13+,则首选方法已更改为:

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

如果正在运行一个NSApplication对象来接受文件,则当您的应用程序需要打开文件时,操作系统将调用此命令。通常,您可以通过调用NSApplicationMain()创建一个NSApplication对象,但是如果需要,您可以实现自己的NSApplicationMain()版本(有关详细信息,请参见NSApplication文档)。

可以通过自己实现Apple Events并响应odoc(打开文档; { kCoreEventClass, kAEOpenDocuments })消息来在没有NSApplication或任何Objective-C的情况下响应这些打开的请求。要对此进行攻击,请参见The Apple Events Programming Guide

您应该期望编写一些代码来安装事件处理程序,例如:

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

然后您将实际处理OpenDocumentsAE中的消息(摘自“ Open Document 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
}