When does an icon handler shell extension get unloaded?

A customer had a question about the SHGet­File­Info function. They used the function to obtain the icon for a file, and they discovered that when they asked for the icon of a particular type of file, the shell extension for the associated application was loaded.

But unfortunately the third party shell extension is not getting unloaded, maybe because of a bug. Can we do anything in code to get this shell extension to unload?

Shell extensions are COM objects, and icon handlers are in-process local servers, and in-process local servers remain loaded until the apartment is torn down or the application calls Co­Free­Unused­Libraries (or a moral equivalent).

Therefore, their application can follow the standard COM pattern of calling Co­Free­Unused­Libraries every so often (say, after being idle for five minutes or when there is some indication that the user has stopped one task and started another). The shell extension will then be asked whether it is safe to unload, and if it responds in the affirmative, then COM will unload it.

@Medinoc: I'm guessing this depends on if you are using the LR_SHARED flag ("Do not use LR_SHARED for images that have non-standard sizes, that may change after loading, or that are loaded from a file."). For file extensions, the shell icon cache probably also comes into play…

The fact that the documentation calls out that you need to call DestroyIcon, then I would guess that LoadImage makes a copy of the Icon. There is also:

"The system automatically deletes these resources when the process that created them terminates; however, calling the appropriate function saves memory and decreases the size of the process's working set."

At the end of LoadImage, so I would guess that it makes a copy. But it is still questionable if it is a good idea to unload the DLL even then.

There's the possibility that the icon object that you need to destroy only contains pointers to the data, no?

It's probably not what happens, but even if it isn't, it isn't in the documentation (though it should be) so you can't rely on it. Or maybe loading an icon from a DLL could cause the reference count of the DLL to increase…

There are many possible implementations of that function, all of which have side effects which can be important to know.