如何编写OS X Finder插件?

时间:2023-01-14 13:51:43

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查找器插件的指南或示例代码?它想知道如何做一些简单的行动:

  1. adding image overlayers to icons
  2. 向图标添加图像覆盖层
  3. adding context menu items
  4. 添加上下文菜单项
  5. listen to file changes
  6. 听文件更改

I found the following two resources:

我发现了以下两种资源:

  • Writing Contextual Menu Plugins for OS X: An outdated document from 2002 that uses the COM API targeting Mac OS X 8/9.
  • 为OS X编写上下文菜单插件:一个2002年的过时文档,使用面向Mac OS X 8/9的COM API。
  • SCPlugin: Open-source SVN Mac application that includes a Finder plug-in.
  • 开源SVN Mac应用程序,包括一个查找器插件。

I am tempted to review the SCPlugin code, but was hoping to find an easier sample to digest.

我很想回顾一下SCPlugin代码,但是希望找到一个更简单的示例来消化。

8 个解决方案

#1


16  

Sadly, programming a Finder plugin actually does still 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函数等等。编写一个插件,你同时管理老式的碳记忆管理,com风格的记忆管理,以及Cocoa/new风格的碳记忆管理,可能是一件难以置信的痛苦——这完全忽略了这样一个事实:你将在三个或更多完全不同的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雪豹中的Finder已经被完全重写在Cocoa中——而且它的插件界面也非常出色。如果您足够幸运地处于只针对Snow Leopard的情况,那么您可能应该获取ADC Premier或更高的会员资格,下载预发行版,并对此进行编码。此外,如果没有重新编写Cocoa,你的插件可能无法在10.6上运行,所以在Snow Leopard发布之前看看它可能是很有意义的。

#2


28  

The Finder Icon Overlay example project represents a small and very basic but actually working example of the answer below.

查找器图标叠加示例项目代表了一个很小的、非常基本但实际上可以工作的答案示例。

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 (?)

我知道这太老了,但是有些人可能仍然对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)下所做的。首先需要适当的查找程序的头文件。使用类转储工具获取它。然后将代码编写为SIMBL插件(请参阅如何实现它的文档),使用一些方法。例如,要在ListView中绘制图标,drawIconWithFrame: TIconAndTextCell方法的方法必须是overriden。

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.

我重写了“drawIconWithFrame:”方法,我的方法是“FT_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];这就是如何调用super来获取普通的图标和名字等等。我知道,看起来很奇怪,像loop,但实际上不是。然后封装到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的变化,一些工作必须从头开始(创建新的“查找器”)。h"文件中包含所有需要的声明,找到合适的无类和方法来重写),但是这种技术仍然有效。

Happy hacking!

黑客快乐!

#3


21  

For Yosemite (MacOS 10.10 & newer), you can use Apple's FinderSync framework, which allows Finder extensions to:

对于Yosemite (MacOS 10.10和更新版本),您可以使用苹果的FinderSync框架,它允许查找扩展到:

  • 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
  • 当选定项(或窗口目标)处于这些层次结构中时,提供Finder上下文菜单中的动态菜单项。
  • Provide a Toolbar Item that displays a menu with dynamic items (even if the selection is unrelated)
  • 提供一个工具栏项,该工具栏项显示一个包含动态项的菜单(即使选择是不相关的)

#4


14  

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.

查找程序没有官方的或支持的插件系统。从OS X 10.6开始,您将需要向查找程序注入代码,并在查找程序中重写objective 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 solid months of painstaking development and reasonably deep knowledge of C and Objective-C internals.

如果有任何方法可以使用服务API来实现您的目标,请执行它。编写一个查找器插件将花费你1-2个月的艰苦开发和对C和Objective-C内部的合理深入了解。

If you're still convinced that you want do to this, grab mach_star. Good luck.

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

#5


2  

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.

据我所知,查找程序没有正式的插件架构。您可以通过外部应用程序向图标添加图像覆盖,而无需挂入查找程序,尽管它不会动态运行。我认为除了文件夹操作和自动操作之外,没有其他方法可以添加上下文菜单项。您还可以考虑编写一个外部应用程序来监视使用FSEvents API的文件系统更改。

#6


2  

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。

Liferay Nativity provides 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提供了一个脚本包,它可以使用相关的查找器方法和Java客户端来设置图标和上下文菜单。它还包括Windows和Linux的等效项目。

The project is open source under LGPL, so feel free to contribute any bug fixes or improvements!

该项目是LGPL下的开源项目,所以请随意提供任何bug修复或改进!

#7


1  

The pickings are slim; it's never been really clear to me whether Finder Plugins are actually supported. A few more leads, though:

它们也苗条;我一直不太清楚查找程序插件是否被支持。不过还有一些线索:

  • SampleCMPlugIn - Carbon-based of course, since so is Finder. Note that almost any Finder plugin is probably going to stop working with 10.6.
  • SampleCMPlugIn -基于碳的,因为Finder也是如此。注意,几乎所有的查找器插件都可能停止使用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.
  • 自动程序可以作为“查找器插件”保存东西。它是您正在讨论的更受支持的版本,但当然不那么灵活。

#8


0  

To add Finder/File browser icon overlays and context menus, in a cross-platform manner, from Java, take a look at the Liferay Nativity library.

要从Java以跨平台的方式添加查找器/文件浏览器图标覆盖和上下文菜单,请查看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中也提到了这一点,它还包含了与苹果的“查找同步”文档和API的链接。

#1


16  

Sadly, programming a Finder plugin actually does still 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函数等等。编写一个插件,你同时管理老式的碳记忆管理,com风格的记忆管理,以及Cocoa/new风格的碳记忆管理,可能是一件难以置信的痛苦——这完全忽略了这样一个事实:你将在三个或更多完全不同的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雪豹中的Finder已经被完全重写在Cocoa中——而且它的插件界面也非常出色。如果您足够幸运地处于只针对Snow Leopard的情况,那么您可能应该获取ADC Premier或更高的会员资格,下载预发行版,并对此进行编码。此外,如果没有重新编写Cocoa,你的插件可能无法在10.6上运行,所以在Snow Leopard发布之前看看它可能是很有意义的。

#2


28  

The Finder Icon Overlay example project represents a small and very basic but actually working example of the answer below.

查找器图标叠加示例项目代表了一个很小的、非常基本但实际上可以工作的答案示例。

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 (?)

我知道这太老了,但是有些人可能仍然对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)下所做的。首先需要适当的查找程序的头文件。使用类转储工具获取它。然后将代码编写为SIMBL插件(请参阅如何实现它的文档),使用一些方法。例如,要在ListView中绘制图标,drawIconWithFrame: TIconAndTextCell方法的方法必须是overriden。

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.

我重写了“drawIconWithFrame:”方法,我的方法是“FT_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];这就是如何调用super来获取普通的图标和名字等等。我知道,看起来很奇怪,像loop,但实际上不是。然后封装到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的变化,一些工作必须从头开始(创建新的“查找器”)。h"文件中包含所有需要的声明,找到合适的无类和方法来重写),但是这种技术仍然有效。

Happy hacking!

黑客快乐!

#3


21  

For Yosemite (MacOS 10.10 & newer), you can use Apple's FinderSync framework, which allows Finder extensions to:

对于Yosemite (MacOS 10.10和更新版本),您可以使用苹果的FinderSync框架,它允许查找扩展到:

  • 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
  • 当选定项(或窗口目标)处于这些层次结构中时,提供Finder上下文菜单中的动态菜单项。
  • Provide a Toolbar Item that displays a menu with dynamic items (even if the selection is unrelated)
  • 提供一个工具栏项,该工具栏项显示一个包含动态项的菜单(即使选择是不相关的)

#4


14  

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.

查找程序没有官方的或支持的插件系统。从OS X 10.6开始,您将需要向查找程序注入代码,并在查找程序中重写objective 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 solid months of painstaking development and reasonably deep knowledge of C and Objective-C internals.

如果有任何方法可以使用服务API来实现您的目标,请执行它。编写一个查找器插件将花费你1-2个月的艰苦开发和对C和Objective-C内部的合理深入了解。

If you're still convinced that you want do to this, grab mach_star. Good luck.

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

#5


2  

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.

据我所知,查找程序没有正式的插件架构。您可以通过外部应用程序向图标添加图像覆盖,而无需挂入查找程序,尽管它不会动态运行。我认为除了文件夹操作和自动操作之外,没有其他方法可以添加上下文菜单项。您还可以考虑编写一个外部应用程序来监视使用FSEvents API的文件系统更改。

#6


2  

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。

Liferay Nativity provides 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提供了一个脚本包,它可以使用相关的查找器方法和Java客户端来设置图标和上下文菜单。它还包括Windows和Linux的等效项目。

The project is open source under LGPL, so feel free to contribute any bug fixes or improvements!

该项目是LGPL下的开源项目,所以请随意提供任何bug修复或改进!

#7


1  

The pickings are slim; it's never been really clear to me whether Finder Plugins are actually supported. A few more leads, though:

它们也苗条;我一直不太清楚查找程序插件是否被支持。不过还有一些线索:

  • SampleCMPlugIn - Carbon-based of course, since so is Finder. Note that almost any Finder plugin is probably going to stop working with 10.6.
  • SampleCMPlugIn -基于碳的,因为Finder也是如此。注意,几乎所有的查找器插件都可能停止使用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.
  • 自动程序可以作为“查找器插件”保存东西。它是您正在讨论的更受支持的版本,但当然不那么灵活。

#8


0  

To add Finder/File browser icon overlays and context menus, in a cross-platform manner, from Java, take a look at the Liferay Nativity library.

要从Java以跨平台的方式添加查找器/文件浏览器图标覆盖和上下文菜单,请查看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中也提到了这一点,它还包含了与苹果的“查找同步”文档和API的链接。