如何编写OS X Finder插件

时间:2009-08-18 14:40:36

标签: objective-c cocoa macos plugins finder

我正在寻找编写Mac OS X Finder插件的指南或示例代码?它想知道如何做一些简单的行动:

  1. 将图像叠加层添加到图标
  2. 添加上下文菜单项
  3. 听取文件更改
  4. 我找到了以下两个资源:

    我很想查看SCPlugin代码,但我希望找到一个更容易消化的样本。

8 个答案:

答案 0 :(得分:28)

Finder Icon Overlay示例项目代表了以下答案的一个小而非常基本但实际可行的示例。

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

我知道这已经太老了,但有些人可能仍然对主题感兴趣(?)

以下是我在Leopard(10.6)下所做的事情。首先需要适当的Finder标头。使用类转储工具来获取它。然后将您的代码编写为SIMBL插件(请参阅文档如何操作),调整一些方法。例如,要在ListView中的图标上绘制一些东西,必须覆盖drawconMith方法的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];
    }
}

基本上,它会在文件的每个图标上绘制“myPrettyIconOverlayImage”,文件名以字母“A”开头。这个逻辑取决于你。

注意这一行:[self FT_drawIconWithFrame:arg1];这是如何调用'超级'以获得正常的图标和名称等。我知道,看起来很奇怪,像循环,但实际上并非如此。然后换入SIMBL插件,安装SIMBL并运行。

由于Lion的变化,一些工作必须从头开始(制作新的“Finder.h”文件及其中所需的所有声明,找到适当的classess和方法来覆盖),但这种技术仍然有效。

快乐的黑客攻击!

答案 1 :(得分:22)

对于Yosemite(MacOS 10.10及更新版),您可以使用Apple的FinderSync framework,它允许Finder扩展程序:

  • 表达对特定文件夹层次结构的兴趣
  • 提供“徽章” 表示这些层次结构中的项目状态
  • 提供动态 Finder上下文菜单中的菜单项,当选定的项目(或 窗口目标)在这些层次结构中
  • 提供工具栏项 显示带有动态项目的菜单(即使选择是 无关)

答案 2 :(得分:17)

可悲的是,编程Finder插件实际上确实仍需要弄脏COM。如果你查看SCPlugin项目的SCFinderPlugin子项目,你会发现它遵循第一个链接中概述的完全相同的技术,包括为COM设置vtable,编写AddRef / ReleaseRef函数等等。编写插件,同时管理老式碳内存管理,COM式内存管理和Cocoa /新式碳内存管理,可能是一种令人难以置信的痛苦 - 而且完全忽略了这样一个事实,即你将成为在三个或更多完全不同的API中进行交互,具有不同的命名约定和调用语义。把这种情况称为歇斯底里的穷人将是一个巨大的轻描淡写。

从好的方面来看,Mac OS X 10.6 Snow Leopard中的Finder已经在Cocoa中完全重写 - 并且随之而来的是更优秀的插件接口。如果你很幸运能够实际上只能实现Snow Leopard的目标,那么你可能应该获得ADC Premier或更高级别的会员资格,下载预发布版本以及代码。此外,如果没有Cocoa重写,你的插件可能无法在10.6上运行,所以在它被释放之前看看Snow Leopard可能是有道理的。无论如何。

答案 3 :(得分:14)

Finder没有正式或受支持的插件系统。从OS X 10.6开始,您需要将代码注入Finder流程并在Finder流程中覆盖目标C方法。

我为一个专有项目做了这个。我可以告诉你,没有示例或教程的原因是因为这是一项非常困难且耗时的开发任务。出于这个原因,对于完成此任务的个人或组织来说,有足够的动力来密切关注其过程的具体细节。

如果有任何方法可以使用Services API完成目标,那就去做吧。编写Finder插件将带您完成1-2个月的艰苦发展和对C和Objective-C内部的深入了解。

如果您仍然确信要这样做,请抓住mach_star。祝你好运。

答案 4 :(得分:2)

据我所知,Finder没有正式的插件架构。您可以通过外部应用程序将图像叠加添加到图标,而无需挂钩到Finder,尽管它不会在运行中。除了Folder Actions和Automator之外,我认为没有办法添加上下文菜单项。您还可以使用FSEvents API来编写外部应用程序以监视文件系统更改。

答案 5 :(得分:2)

这是使用Les Nie描述的技术在Lion和Mountain Lion中完成Finder图标徽章和上下文菜单的解决方案。

Liferay Nativity提供了一个脚本捆绑包,它将调配相关的Finder方法,以及一个用于设置图标和上下文菜单的Java客户端。它还包括Windows和Linux的等效项目。

该项目是LGPL下的开源项目,因此请随时提供任何错误修复或改进!

答案 6 :(得分:1)

采摘很苗条;我从来没有真正清楚Finder插件是否真正受到支持。不过还有一些线索:

  • SampleCMPlugIn - 碳基当然,因为Finder也是如此。请注意,几乎任何Finder插件都可能会停止使用10.6。
  • Automator可以将内容保存为“Finder插件”。它是您正在讨论的更受支持的版本,但当然不太灵活。

答案 7 :(得分:0)

要以跨平台的方式从Java添加Finder / File浏览器图标叠加层和上下文菜单,请查看Liferay Nativity库。

我在another SO post中也提到了这一点,其中还包含了Apple' Finder Sync'的链接。 docs和API。