File extension madness, Windows Vista / 7 style

Last time I wrote about the old way of associating file types and file extensions with a program. I've since tried Default Programs, the new way of handling file associations starting with Windows Vista. You still have to register the file types in HKEY_CLASSES_ROOT in order to set the defaults (or more specifically HKLM\Software\Classes or HKCU\Software\Classes as required), but afterward you use the Default Programs mechanism to select the user mapping. This has the following advantages:

You get a UI for free to do this: Use CoCreateInstance() and invoke IApplicationAssociationRegistrationUI::LaunchAdvancedAssociationUI(). Not bad.

Adding default programs only requires writing to the registry. This means that you can dump an entire folder of portable apps into a directory and then apply one registry patch to set up Default Programs entries for them, even if the programs don't support it themselves.

There is a programmatic interface to apply defaults per-extension, and better yet, an easy way to query if the app is the current default. Doing this check the old way can actually be a bit hairy.

And... that's about it. Now for the bad parts:

The Default Programs mechanism sets user-local defaults only, but for some reason, it requires you to set up your application mapping in HKEY_LOCAL_MACHINE. This means that any programs that install per-user in order to allow installation without requiring administrator access are SOL.

There is no way in the UI or API to remove an association. This means that if a program offers an association for the generic .bin extension and you click it, you're stuck with that association and all the default APIs and UIs allow you to do is periodically select another program to accidentally open binary files with.

There is an API to remove user associations for all file types (IApplicationAssociationRegistration::ClearUserAssocations). As far as I can tell, the purpose of this is to nominate your program to appear on The Daily WTF, since for any other scenario it would be like swatting a fly with a nuclear bomb.

You can only associate one predefined programmatic identifier (ProgID) with each extension. You can't, for instance, have an option to switch ProgIDs to choose whether a file type opens in a new window or not or to multiplex one extension across multiple file types.

You must statically predefine the set of extensions for your program in the Registry. This is inadequate if your program accepts different file types based on dynamically loaded plugins or filters. I don't even know how this would work for programs that use DirectShow for playback, which has its own extension registry.

MSDN tells you how to get an instance of IApplicationAssociationRegistration via SHCreateAssociationRegistration(), but it doesn't seem to tell you how to get an object that implements IApplicationAssociationRegistrationUI. CoCreateInstance() with CLSID_ApplicationAssociationRegistrationUI works.

If there is no program currently associated with an extension, there is no way for the user to opt out of associating it in the UI: the checkboxes are grayed out enabled and the user is forced to associate your program with it. This is not great if some of the extensions are rarely used and not recommended for general use.

Guidance and support for uninstallation is lacking. The documentation for File Types recommends that you should delete the programmatic identifiers (ProgIDs) but leave the extension mappings to the ProgIDs in place, which is the best you can do anyway with Explorer locking down the UserChoice keys. Explorer does indeed handle this and display the Open With dialog if the file is launched. What the docs don't tell you is that Explorer displays the missing ProgID as the file type name, so the file that used to appear as "HLSL Shader File" now shows up as "FooEditor.hlslfx.5", which just makes it look like your program didn't uninstall properly.

As such, I'd say the new Default Programs system is not an improvement over the old way of doing file type associations. Sadly, the way things are, there isn't much choice unless you're willing to start hacking the Explorer registry keys, which I couldn't recommend as a good choice.