设置文件信息,您可以将应用程序与特定文件类型相关联,以便在单击时启动应用程序。我的问题是应用程序如何发现导致它启动的文件的完整文件名。
1 回答
并非每次打开关联文件时都启动 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
}