1

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

4

1 回答 1

3

并非每次打开关联文件时都启动 Mac 应用程序。它们可能已启动,但如果它们已经在运行,那么它们只会被要求打开另一个文件。所以路径不会通过命令行到达应用程序。它作为消息发送给应用程序,应用程序需要处理一个运行循环(NSRunLoop)来接收它。

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

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

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

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

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

odoc通过自己实现 Apple 事件并响应(open document; { kCoreEventClass, kAEOpenDocuments }) 消息,可以在没有 NSApplication 或任何 Objective-C 的情况下响应这些打开请求。要攻击它,请参阅Apple 事件编程指南

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

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

然后您将实际处理以下消息OpenDocumentsAE(取自“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
}
于 2018-12-17T14:02:10.783 回答