Search code examples
winapiwindows-7windows-vistauninstallationdefault-programs

Windows Vista, Default Programs API, file format associations, and (un)installers - explosive mix!


My application is a rather well behaved Windows citizen, so when I ported it to Windows Vista/7 I replaced my custom file format association code with support for the Default Programs API. However I ran into a problem when trying to make uninstaller for my application - there seems to be no way to remove file format associations via Default Programs API.

I tried to call IApplicationAssociationRegistration::ClearUserAssociations but it actually removes all associations, including the ones for other applications - completely restoring default state of the OS (which is of course unacceptable).

I tried to call IApplicationAssociationRegistration::SetAppAsDefault to return file format associations to the previous "owner" - but it does not help, because my application handles many unique file formats which the OS does not support and there is no previous "owners". And Windows does not allow to pass empty strings to SetAppAsDefault...

So what do I do? Any good solutions?


Solution

  • Side note: All the considerations below apply even if you modify directly the file associations in the registry instead of using the Default Programs API.

    On first run, your application should collect the previous owners of all the file types for which one exists, through IApplicationAssociationRegistration::QueryCurrentDefault and store them in storage your app owns.

    On uninstall, your application should use IApplicationAssociationRegistration::SetAppAsDefault to attempt to restore any file association it still owns to the previous owner it has. For associations your app still owns, but don't know previous owners, go to the HKCR registry and delete the corresponding extension, protocol or MIME type entry. Don't touch any associations your app is not the current owner - you'll be overwriting the user's choice.

    I certainly wish that the batched backup on first run and cleanup on uninstall were provided as a single API call by the Default Programs API, but until they decide to generalize that behavior for all apps, you're on your own.

    Note that the cleanup your application executes on uninstall will be specific for the uninstalling user. Any other users that might have used the application and changed their defaults will not be cleaned up.

    You can automate the cleanup for each user by adding a simple per-user task that executes the steps above in the Task Scheduler. The task will be scheduled to execute once and then removes itself from the user task scheduler. The only potential problem with that approach is that since you don't know how many users there will be, it's impossible for you to know when to remove the dll for that task from the machine. Then again, if you leave that dll in the ProgramData folder, it's not a big deal.