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