How to Write OS X Finder plugin

28,842

Solution 1

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.

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.

Solution 2

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

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.

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.

- (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.

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.

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.

Happy hacking!

Solution 3

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

  • 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)

Solution 4

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.

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.

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

Solution 5

Here's a completed solution for Finder icon badges and contextual menus in Lion and Mountain Lion using the techniques described by 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.

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

Share:
28,842
notnoop
Author by

notnoop

Working mainly with Java technologies.

Updated on March 31, 2020

Comments

  • notnoop
    notnoop over 4 years

    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:

    1. adding image overlayers to icons
    2. adding context menu items
    3. listen to file changes

    I found the following two resources:

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

  • notnoop
    notnoop almost 15 years
    thanks for the explanation. I will just wait for the Snow Leopard public release.
  • Parag Bafna
    Parag Bafna over 12 years
    After using this code , you can not sell your product on apple app store.
  • ping localhost
    ping localhost over 12 years
    Yes , I too agree with @jennifer .. what you're doing does'nt seem totally legal
  • Les Nie
    Les Nie over 12 years
    Yep, probably. Nevertheless this is the only method you can reach such functionality (icon overlays) in Finder. It may be the reason Dropbox isn't avail in AppStore.
  • Tony
    Tony over 12 years
    Finder plugins are definitely not officially apple sanctioned, but then again mac app store is not that big of a deal compare to iOS app store, people are so used to downloading desktop apps from internet anyways. Btw Les Nie, where do you get the header for TIconAndTextCell? It doesn't seem to be in AppKit.
  • Tony
    Tony over 12 years
    just found it. though it's called FI_TIconAndTextCell rather than just TIconAndTextCell, though I suspect we are referring to the same class.
  • jsherk
    jsherk about 12 years
    Any idea where I can find info on the Finder plugin interfaces mentioned (for OS X Lion)?
  • Benjamin Pollack
    Benjamin Pollack about 12 years
    It's unfortunately not mentioned. The plugins I know of (e.g., Dropbox's) work by injecting themselves into the Finder via Mach calls—not exactly the direction I thought Apple was going at the time.
  • Tarandeep Gill
    Tarandeep Gill about 12 years
    @LesNie Do you know which functions to override for overlaying icons, when Finder in in "Icon View"? The method you suggested, only overrides the functionality if the finder is in "List View" or "Column View".
  • Les Nie
    Les Nie about 12 years
    OK, due to numerous requests I wrote small and very basic but actually working example. Here's a link. Once again: hapy hacking!
  • Ali
    Ali over 10 years
    @LesNie have you been able to do this on 10.9 ? Also, is there an easy way to flatten the output of class-dump into one file (finder.h) ?
  • Les Nie
    Les Nie over 10 years
    @Ali - I am knee deep in other things and haven't got enought time for that but I promise to take a look soon :) And no, I don't know about any easy way to get one nice Finder.h. Just hard handwork.
  • Ali
    Ali over 10 years
    @LesNie haha Thanks, I appreciate that.
  • Jiulong Zhao
    Jiulong Zhao about 7 years
    thumb up for this info!