blog advertising is good for you


blog advertising is good for you
User login

Creating an Open Handler and Custom Icons for Hand-Rolled Packages

Christopher Williams asks:

Question

As a way to more easily play movies from ripped DVDs, I have started setting the “Movie” folder (the folder which contains the VIDEO_TS and AUDIO_TS folders which generally is the name of the movie) as a “Bundle Bit” via the Path Finder Get Info pane (I would imagine that it works the same in the Finder as well), giving the folder an extension of “.dvdmovie” (the extension could be just about anything so long as there are no conflicts with existing extensions), and informing the system that I would like all files with said extension to open via VLC so that all I need to do is double click the new bundle bit and watch the movie. This works extremely well (I really prefer not to use DVD Player as it doesn’t always play ripped movies correctly), but I have one problem. All of my new “.dvdmovie” bundles have the generic “Document” icon which is unsightly.

How do I make the system (via GUI, Applescript, command line, or hacking) apply a specific icon to all of my new “.dvdmovie” bundles, and to future ones as they are made? I would think that there is a way short of manually assigning them individually.

Answer

There are hackish ways and there are proper ways. Here I’ll describe some proper ways to do it.

Write a Small Program

  1. Install Xcode.
  2. Make a new Cocoa Document-Based Application project.
  3. In MyDocument.m, remove the two file read/write methods and replace them with the following:
    - (BOOL)readFromURL:(NSURL *)absoluteURL ofType:(NSString *)typeName error:(NSError **)outError
    {
    	[[NSWorkspace sharedWorkspace] openFile:[absoluteURL path] withApplication:@"VLC"];
    	return YES;
    }
    
  4. In the windowNibName method, munge “MyDocument” somehow. I just added a space to it, myself. This prevents it from opening a window (the very wrong, but very easy way).
  5. Add the icon for the file type to the project by dragging it in (it must be an ICNS file; Google for help) to the Resources folder. Check “copy” and accept the rest of the defaults.
  6. Press ⌘⌥-E to get the Project Settings window.
  7. Under Properties, change “Name” to “DVD movie”, “Extensions” to “dvdmovie”, “Role” to “Viewer”, and ensure “Package” is checked (if it’s checked, uncheck and re-check it; this is important).
  8. Enter the file name for the icon in the “Icon File” field for the document type.
  9. In the Project->Set Active Build Configuration menu pick Release.
  10. Build the project and run it.

You may need to logout and back in again for it to see all .dvdmovie files as packages owned by this program, but when they are then when you name something with that extension, it will become a package owned by this program, gain the icon, and tell this program to open it and it will, in turn, tell VLC to open it.

You can go further. Add more file types and icons to the project settings and change the above method to do something like this:

- (BOOL)readFromURL:(NSURL *)absoluteURL ofType:(NSString *)typeName error:(NSError **)outError
{
	if ([typeName isEqualToString:@"DVD movie"])
		[[NSWorkspace sharedWorkspace] openFile:[absoluteURL path] withApplication:@"VLC"];
	else if ([typeName isEqualToString:@"another file"])
		[[NSWorkspace sharedWorkspace] openFile:[absoluteURL path] withApplication:@"Another Program"];
	return YES;
}

Again, it’s very lightweight, hackish, and improper code, but it works fine for what you need. In the end, it’s the most versatile way to get what you want reliably, which is to not only to declare a folder a package, but to set the icon and which program to start it.

Hack VLC

Now, you could really have some fun and just edit the Info.plist for VLC, too. Right-click on the VLC program and show the contents. Open the Contents folder and then open Info.plist in a text editor. Find the array for CFBundleDocumentTypes and insert the following dictionary:

		<dict>
			<key>CFBundleTypeExtensions</key>
			<array>
				<string>dvdmovie</string>
			</array>
			<key>CFBundleTypeIconFile</key>
			<string>MyIcon.icns</string>
			<key>CFBundleTypeName</key>
			<string>DVD movie</string>
			<key>CFBundleTypeRole</key>
			<string>Viewer</string>
			<key>LSTypeIsPackage</key>
			<true/>
		</dict>

Now copy the ICNS file into the Resources folder, ensure the name matches the one you added in the plist, and then close out. Open VLC once, quit and logout, then log back in and it should have the same effect.

Of course, with this method you have to hack every program you want to do this for, and do it every time you update it. Or submit a feature request to the VLC team for similar functionality.

I think I’d just send in the feature request, myself.

Why Go Through All This?

The reason is that to tell the system the file is a package requires telling Launch Services this via one of its supported registration schemes. Sadly, those are not open. However, just creating a program that will open the file will cause LS to register the information in the Info.plist file and learn about the file type. So, we either hack the destination application or make a new one to do our bidding.

For files, you can just tell it to open in a certain program forever, but here we’ve got to also tell LS that a folder is a package, and that bit of registration comes through this method. Three cheers for semi-closed APIs!

Now, in theory, you could create the program without editing code, just making it declare the files and icons, and then change your open preferences to VLC, but you wouldn’t get the icon unless you also hacked VLC, so mixing the methods doesn’t win anything.

Average rating
(0 votes)
About Adam Knight
Adam Knight's picture

Author Biography

Adam Knight is one of the founders of Mac Geekery and is a geek at heart. Programmer by day, hacker by night, his daily life revolves around the Macintosh platform, which he has been a user and programmer for since the early days of System 7 when his LCII replaced his Apple //c.

In-between tech jobs, he’s managed to learn the basics of any web hacker: PHP, MySQL, Perl, Apache, Linux, *BSD, and the intricacies of ./configure —prefix=~/bombshelter/. Today, codepoet is concentrating on blogging again, writing some software for the Mac by himself (including Notae) and for his company (such as Switchblade) and has a few other toys coming out soon.

Bug him over AIM or email [link fixed].

the second hack you describe (hacking VLC’s preferences file) and adding the custom icon to the VLC app package. Now all I need to do is copy that version of the program to all of my systems. It works flawlessly.

Thanks,
Chris

http://www.macademic.net
where all things mac are academic

their Info.plist of OO.o refers to an icon file for .doc but it doesn’t have one for it. (maybe it was .rtf). I’ll get around to it. probably not if OO.o carbon comes out before then.

Post new comment
The content of this field is kept private and will not be shown publicly.
5 + 11 =
Solve this simple math problem and enter the result. E.g. for 1+3, enter 4.