Search code examples
dllshell-extensions

Most reasonable strategy for upgrading/uninstalling a shell extension?


I want to create an installer for a shell extension that is installed for current user only. I want both upgrade and uninstall to run as seamless as possible for the end user.

The problem is that a loaded shell extension DLL can be unregistered but not deleted because it is locked by Explorer. The installer will then get stuck when it tries to delete the DLL. As the shell extension is installed for current user only I cannot leverage any "delete DLL on reboot" option that require admin privileges. I also cannot use a hard restart of explorer.exe as it may leave the computer in an unusable state for the end user: Often times with restart explorer is shut down but not started again.

After looking into the DLLs of some other applications it seems some might be using rolling version numbers, for example shell_ext_v5.dll, shell_ext_v6.dll, etc. New versions get a new number so the old DLL files do not necessarily need to be deleted.

If I go with this strategy:

  • When reinstalling the current version I can leave DLL untouched, as it has not changed.
  • When upgrading, a new DLL will be installed, and registry will point to the new version. The old DLL file will remain in the system albeit unused.
  • When uninstalling the DLL file may be left undeleted if it is locked by Explorer.

So the bad thing is that there will be leftover DLL files in the system. But the good thing is install/uninstall would never get stuck if the DLL is locked. What do you think? Is there yet an alternative?


Solution

  • Write a small program to delete the outdated files(each release adds to the list) on the system.

    On application update, add a registry entry to HKCU\Software\Microsoft\Windows\RunOnce, that points to this program.

    The next time the user logs in, this program will be executed(the files will be unlocked and therefore deleted), and then the entry is removed by the system from the registry.

    Make sure the program's Main function returns a 0 as its exit code.

    This should be transparent to the user, with the possible flash of a console window(depends on the program settings).

    All of this is performed in the user context, so no Administrator privileges or UAC is required.