如何编写OS X Finder插件

50
我正在寻找编写Mac OS X Finder插件的指南或示例代码。需要知道如何执行以下简单操作:
  1. 向图标添加图像叠加
  2. 添加上下文菜单项
  3. 监听文件更改
我找到了以下两个资源: 我很想查看SCPlugin代码,但希望能找到一个更易理解的示例。

2
自从这篇文章发布以来已经有一段时间了,现在10.6已经可以使用。你是否已经实现了你想要的功能?你是否采用了Finder插件策略? - epologee
1
有关狮子的任何更新吗? - Tony
@LesNie 在下面链接中分享了他的 Finder Icon Overlay 项目。我将其分享出来,以便其他人也可以找到一个开源的 OS X Finder 插件示例(就像我一样)。 - pkamb
8个回答

28

Finder Icon Overlay示例项目是下面答案的一个很小、非常基础但实际可行的示例。

https://github.com/lesnie/Finder-Icon-Overlay

我知道这已经很老了,但仍有些人可能对此感兴趣。

在Leopard(10.6)下完成需要使用正确Finder的头文件。使用class-dump工具获取它们。然后编写代码作为SIMBL插件(参考文档如何操作),交换某些方法。例如,在ListView中覆盖图标的绘制,必须重写TIconAndTextCell方法的drawIconWithFrame:方法。

这是方法交换的代码:

+ (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);

}

我正在使用我的方法 "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];
    }
}
基本上,它会在文件名以字母“A”开头的每个文件图标上覆盖“myPrettyIconOverlayImage”。这个逻辑由你自己决定。 请注意这一行:[self FT_drawIconWithFrame:arg1];这是如何调用“super”以获取普通的图标和名称等信息。我知道,看起来很奇怪,像一个循环,但实际上不是。然后将其包装成SIMBL插件,安装SIMBL并运行。 由于Lion中的更改,有些工作必须从头开始(创建一个新的“Finder.h”文件,其中包含所有需要的声明,找到要重写的正确的类和方法),但这种技术仍然可以使用。 愉快的黑客活动!

4
是的,很可能。然而这是您在Finder中实现此类功能(图标覆盖)的唯一方法。这可能是Dropbox不在AppStore上的原因。 - Les Nie
1
刚刚找到了它。虽然它被称为FI_TIconAndTextCell而不是TIconAndTextCell,但我怀疑我们指的是同一个类。 - Tony
3
好的,由于众多请求,我编写了一个小而非常基本但实际上有效的示例。这里是链接。再次祝你愉快地进行编程! - Les Nie
@LesNie,你能在10.9上做到这个吗?另外,有没有一种简单的方法将class-dump的输出压缩成一个文件(finder.h)? - Ali
@Ali - 我现在忙于其他事情,没有足够的时间,但我保证很快会看一下 :) 不过,我不知道有什么简单的方法可以得到一个漂亮的Finder.h文件。只能通过艰苦的手工劳动来完成。 - Les Nie
显示剩余5条评论

27

针对Yosemite(MacOS 10.10及以上版本),您可以使用苹果的FinderSync框架,该框架允许Finder扩展:

  • 表达特定文件夹层次结构的兴趣;
  • 为这些层次结构中的项目提供“徽章”以指示其状态;
  • 在Finder上下文菜单中提供动态菜单项,当所选项目(或窗口目标)位于这些层次结构中时;
  • 提供一个工具栏项,显示具有动态项的菜单(即使选择与此无关)。

点赞这个信息! - Jiulong Zhao

18

不幸的是,编写Finder插件仍然需要使用COM方法。 如果您查看SCPlugin项目的SCFinderPlugin子项目,您会发现它遵循了第一个链接中概述的完全相同的技术,包括为COM设置vtable,编写AddRef / ReleaseRef函数等。编写插件时,您同时管理老式Carbon内存管理、COM风格的内存管理和Cocoa /新式Carbon内存管理,可能会非常痛苦,完全忽略了您将在三个或更多根本不同的API中进行交互,具有不同的命名约定和调用语义。形容这种情况为极其糟糕绝对是轻描淡写。

好消息是,Mac OS X 10.6 Snow Leopard中的Finder已经完全重写为Cocoa,并且随之而来的是极大改进的插件接口。如果您足够幸运,可以只针对Snow Leopard进行编码,那么您可能应该获取ADC Premier或更高级别的会员资格,下载预发布版本,并对其进行编码。此外,即使没有Cocoa重写,您的插件也可能无法在10.6上工作,因此,在发布之前查看Snow Leopard可能是明智的选择。


谢谢解释。我会等待Snow Leopard的公开发布。 - notnoop
1
你知道在哪里可以找到提到的Finder插件接口(适用于OS X Lion)的信息吗? - jsherk
很遗憾没有提到。我知道的插件(例如Dropbox)是通过Mach调用将自己注入Finder中的,这不完全是我当时认为苹果会采取的方向。 - Benjamin Pollack

15

Finder没有官方或支持的插件系统。从OS X 10.6开始,您需要向Finder进程中注入代码并覆盖Objective C方法。

我曾经为一个专有项目完成过这个任务。我可以告诉你,之所以没有示例或教程是因为这是一项相当困难和耗时的开发任务。因此,那些已经完成这个任务的个人或组织有充分的动力密切保护他们的具体过程。

如果您能够使用Services API实现目标,请尽可能这样做。编写Finder插件将需要1-2个月的细致开发和相当深入的C和Objective-C内部知识。

如果您仍然坚信要这样做,请获取 mach_star。祝你好运。


2
这是一种使用Les Nie所描述的技术,为Lion和Mountain Lion中Finder图标徽章和上下文菜单提供完整解决方案。 Liferay Nativity提供了一个脚本束,可以扭曲相关的Finder方法和一个Java客户端来设置图标和上下文菜单。它还包括Windows和Linux的等效项目。
该项目是基于LGPL的开源项目,因此欢迎贡献任何错误修复或改进!

2
据我所知,Finder 没有官方的插件架构。你可能可以通过外部应用程序向图标添加图像叠加,而无需钩入 Finder,尽管这不是即时的。我认为除了文件夹操作和 Automator 之外,并没有添加上下文菜单项的方法。您还可以研究编写一个外部应用程序来使用 FSEvents API 监视文件系统更改。

1

选择很少;我从来不确定Finder插件是否得到支持。然而,还有一些线索:

  • SampleCMPlugIn - 当然是基于Carbon的,因为Finder也是如此。请注意,几乎任何Finder插件都可能在10.6中停止工作。
  • Automator可以将东西保存为“Finder插件”。这是您讨论的更受支持的版本,但当然不够灵活。

0

如果您想以跨平台的方式从Java中添加Finder/文件浏览器图标叠加和上下文菜单,请查看Liferay Nativity库。

我还在另一个SO帖子中提到了这一点,其中还包含到苹果的“Finder Sync”文档和API的链接。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接