objective-c 如何编写 OS X Finder 插件
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1294335/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to Write OS X Finder plugin
提问by notnoop
I'm looking for a guide or sample code for writing Mac OS X Finder plugins? It would like to know how to do some simple actions:
我正在寻找编写 Mac OS X Finder 插件的指南或示例代码?它想知道如何做一些简单的动作:
- adding image overlayers to icons
- adding context menu items
- listen to file changes
- 将图像叠加层添加到图标
- 添加上下文菜单项
- 监听文件更改
I found the following two resources:
我找到了以下两个资源:
- Writing Contextual Menu Plugins for OS X: An outdated document from 2002 that uses the
COMAPI targeting Mac OS X 8/9. - SCPlugin: Open-source SVN Mac application that includes a Finder plug-in.
- 为 OS X 编写上下文菜单插件:2002 年的过时文档,它使用
COM面向 Mac OS X 8/9的API。 - SCPlugin:包含 Finder 插件的开源 SVN Mac 应用程序。
I am tempted to review the SCPlugincode, but was hoping to find an easier sample to digest.
我很想查看SCPlugin代码,但希望找到一个更容易消化的示例。
采纳答案by Benjamin Pollack
Sadly, programming a Finder plugin actually doesstill require getting your hands dirty with COM. If you look at the SCFinderPlugin subproject of the SCPlugin project, you will find that it follows exactly the same techniques outlined in your first link, including setting up a vtable for COM, writing AddRef/ReleaseRef functions, and so on. Writing a plugin, where you're simultaneously managing old-school Carbon memory management, COM-style memory management, and Cocoa/new-style Carbon memory management, can be an incredible pain—and that totally ignores the fact that you'll be interacting in three or more radically different APIs, with different naming conventions and calling semantics. Calling the situation hysterically poor would be a vast understatement.
可悲的是,编程搜索插件实际上确实仍然需要得到你的手脏与COM。如果您查看 SCPlugin 项目的 SCFinderPlugin 子项目,您会发现它遵循与您在第一个链接中概述的完全相同的技术,包括为 COM 设置 vtable、编写 AddRef/ReleaseRef 函数等。编写一个插件,同时管理老式的 Carbon 内存管理、COM 风格的内存管理和 Cocoa/新风格的 Carbon 内存管理,这可能是一种令人难以置信的痛苦——而这完全忽略了这样一个事实:你将在三个或更多完全不同的 API 中交互,具有不同的命名约定和调用语义。将情况称为歇斯底里地糟糕将是一种轻描淡写的说法。
On the bright side, the Finder in Mac OS X 10.6 Snow Leopard has been fully rewritten in Cocoa--and with that come vastly superior plugin interfaces. If you are lucky enough to be in a situation where you can actually only target Snow Leopard, you probably should grab an ADC Premier or higher membership, download the prerelease builds, and code against that. Besides, your plugin may not work on 10.6 anyway without a Cocoa rewrite, so it might make good sense to take a look at Snow Leopard before it gets released, regardless.
好的一面是,Mac OS X 10.6 Snow Leopard 中的 Finder 已经完全用 Cocoa 重写了——随之而来的是非常出色的插件界面。如果您有幸遇到实际上只能针对 Snow Leopard 的情况,您可能应该获得 ADC Premier 或更高级别的会员资格,下载预发布版本,并针对该情况编写代码。此外,如果没有 Cocoa 重写,您的插件无论如何都可能无法在 10.6 上运行,因此无论如何,在 Snow Leopard 发布之前查看它可能是有意义的。
回答by Les Nie
The Finder Icon Overlayexample project represents a small and very basic but actually working example of the answer below.
在Finder图标叠加例如项目代表了下面的答案的小,非常基本的,但实际工作的例子。
https://github.com/lesnie/Finder-Icon-Overlay
https://github.com/lesnie/Finder-Icon-Overlay
I know this is so old, but some may be still interested in topic (?)
我知道这已经很老了,但有些人可能仍然对主题感兴趣(?)
Here is what I have it done under Leopard (10.6). At first proper Finder's headers are needed. Use class-dump tool to get it. Then write your code as a SIMBL plugin (refer to documentation how to do it), swizzling some methods. For instance to draw something over icon in ListView, drawIconWithFrame: method of TIconAndTextCell method must be overriden.
这是我在 Leopard (10.6) 下所做的。首先需要适当的 Finder 头文件。使用类转储工具来获取它。然后将您的代码编写为 SIMBL 插件(请参阅文档如何操作),混用一些方法。例如,要在 ListView 中的图标上绘制某些内容,必须覆盖 TIconAndTextCell 方法的 drawIconWithFrame: 方法。
Here's the code for method swizzling:
这是方法调配的代码:
+ (void) Plugin_load
{
Method old, new;
Class self_class = [self class];
Class finder_class = [objc_getClass("TIconAndTextCell") class];
class_addMethod(finder_class, @selector(FT_drawIconWithFrame:),
class_getMethodImplementation(self_class, @selector(FT_drawIconWithFrame:)),"v@:{CGRect={CGPoint=dd}{CGSize=dd}}");
old = class_getInstanceMethod(finder_class, @selector(drawIconWithFrame:));
new = class_getInstanceMethod(finder_class, @selector(FT_drawIconWithFrame:));
method_exchangeImplementations(old, new);
}
I am overriding "drawIconWithFrame:" method with my method "FT_drawIconWithFrame:". Below is sample implementation for this method.
我用我的方法“FT_drawIconWithFrame:”覆盖了“drawIconWithFrame:”方法。下面是此方法的示例实现。
- (void) FT_drawIconWithFrame:(struct CGRect)arg1
{
[self FT_drawIconWithFrame:arg1];
if ([self respondsToSelector:@selector(node)]) {
if ([[[[NSClassFromString(@"FINode") nodeWithFENode:[(TNodeIconAndNameCell *)self node]] fullPath] lastPathComponent] hasPrefix:@"A"])
[myPrettyIconOverlayImage drawInRect:NSMakeRect(arg1.origin.x, arg1.origin.y, arg1.size.height, arg1.size.height) fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:1.0];
}
}
Essentially it draws "myPrettyIconOverlayImage" over every icon for file with filename starts with letter "A". This logic is up to you.
本质上,它在文件名以字母“A”开头的文件的每个图标上绘制“myPrettyIconOverlayImage”。这个逻辑取决于你。
Pay attention to this line: [self FT_drawIconWithFrame:arg1];this is how to call 'super' in order to get normal icon and name etc. I know, looks weird, like loop, but actually it isn't. Then wrap in into SIMBL plugin, install SIMBL and ...run.
注意这一行:[self FT_drawIconWithFrame:arg1];这是如何调用“超级”以获得正常的图标和名称等。我知道,看起来很奇怪,像循环,但实际上并非如此。然后包装到 SIMBL 插件中,安装 SIMBL 并...运行。
Due to changes in Lion some work have to be done from scratch (make new "Finder.h" file with all declarations needed in it, find proper classess and methods to override), but this technique still works.
由于 Lion 中的更改,一些工作必须从头开始(创建新的“Finder.h”文件,其中包含所有需要的声明,找到合适的类和方法来覆盖),但这种技术仍然有效。
Happy hacking!
快乐黑客!
回答by Michael Dautermann
For Yosemite (MacOS 10.10 & newer), you can use Apple's FinderSync framework, which allows Finder extensions to:
对于 Yosemite(MacOS 10.10 及更新版本),您可以使用 Apple 的FinderSync 框架,它允许 Finder 扩展:
- Express interest in specific folder hierarchies
- Provide "badges" to indicate the status of items inside those hierarchies
- Provide dynamic menu items in Finder contextual menus, when the selected items (or the window target) are in those hierarchies
- Provide a Toolbar Item that displays a menu with dynamic items (even if the selection is unrelated)
- 表达对特定文件夹层次结构的兴趣
- 提供“徽章”以指示这些层次结构中项目的状态
- 当所选项目(或窗口目标)在这些层次结构中时,在 Finder 上下文菜单中提供动态菜单项
- 提供一个工具栏项,显示一个带有动态项的菜单(即使选择无关)
回答by anthony
There is no official or supported plugin system for the Finder. Starting with OS X 10.6, you will need to inject code into the Finder process and override objective C methods in the Finder process.
Finder 没有官方或受支持的插件系统。从 OS X 10.6 开始,您需要将代码注入 Finder 进程并覆盖 Finder 进程中的目标 C 方法。
I've done this for a proprietary project. I can tell you that the reason that there are no examples or tutorials for this is because it is a significantly difficult and time consuming development task. For this reason, there's plenty of incentive for individuals or organizations who have accomplished this to guard the specifics of their process closely.
我已经为一个专有项目完成了这项工作。我可以告诉你,之所以没有这方面的示例或教程,是因为这是一项非常困难且耗时的开发任务。出于这个原因,已经完成这项工作的个人或组织有足够的动力来密切保护其流程的细节。
If there's any way at all that you can accomplish your goal using the Services API, do it. Writing a Finder plugin will take you 1-2 solidmonths of painstaking development and reasonably deep knowledge of C and Objective-C internals.
如果有任何方法可以使用服务 API 实现您的目标,那就去做吧。编写一个Finder插件会带你1-2个固体潜心发展和C和Objective-C内部的合理很深的造诣个月。
If you're still convinced that you want do to this, grab mach_star. Good luck.
如果您仍然确信您想要这样做,请抓住mach_star。祝你好运。
回答by Martin Gordon
As far as I know, there's no official plugin architecture for the Finder. You may be able to add image overlays to icons through an external application without having to hook into the Finder, although it wouldn't be on the fly. I don't think there is a way to add contextual menu items aside from Folder Actions and Automator. You can also look into writing an external application to monitor File System changes using the FSEvents API.
据我所知,Finder 没有官方的插件架构。您可以通过外部应用程序向图标添加图像叠加层,而无需连接到 Finder,尽管它不会即时运行。我认为除了文件夹操作和 Automator 之外,没有办法添加上下文菜单项。您还可以考虑使用FSEvents API编写外部应用程序来监视文件系统更改。
回答by dejuknow
Here's a completed solution for Finder icon badges and contextual menus in Lion and Mountain Lion using the techniques described by Les Nie.
这是使用 Les Nie 描述的技术为 Lion 和 Mountain Lion 中的 Finder 图标徽章和上下文菜单提供的完整解决方案。
Liferay Nativityprovides a scripting bundle that will swizzle the relevant Finder methods and a Java client for setting the icons and context menus. It also includes equivalent projects for Windows and Linux.
Liferay Nativity提供了一个脚本包,可以混合相关的 Finder 方法和一个用于设置图标和上下文菜单的 Java 客户端。它还包括适用于 Windows 和 Linux 的等效项目。
The project is open source under LGPL, so feel free to contribute any bug fixes or improvements!
该项目是 LGPL 下的开源项目,因此请随时贡献任何错误修复或改进!
回答by Rob Napier
The pickings are slim; it's never been really clear to me whether Finder Plugins are actually supported. A few more leads, though:
采摘量很小;我一直不清楚是否真正支持 Finder 插件。不过,还有一些线索:
- SampleCMPlugIn- Carbon-based of course, since so is Finder. Note that almost any Finder plugin is probably going to stop working with 10.6.
- Automator can save things as a "Finder plugin." It's a more supported version of what you're discussing, but of course less flexible.
- SampleCMPlugIn- 当然是基于碳的,因为 Finder 也是如此。请注意,几乎所有 Finder 插件都可能会停止使用 10.6。
- Automator 可以将内容保存为“Finder 插件”。它是您所讨论内容的更受支持的版本,但当然不那么灵活。
回答by Big Rich
To add Finder/File browser icon overlays and context menus, in a cross-platform manner, from Java, take a look at the Liferay Nativitylibrary.
要以跨平台方式从 Java 添加 Finder/File 浏览器图标覆盖和上下文菜单,请查看Liferay Nativity库。
I also make mention of this in another SO post, which also contains links to Apple's 'Finder Sync' docs and API.
我还在另一篇 SO post 中提到了这一点,其中还包含指向 Apple 的“Finder Sync”文档和 API 的链接。

