I was building a little app that would take a jpeg file and set it as the user’s wallpaper. I could use the SystemParametersInfo API but I wanted something a bit more flexible (e.g. SPI only supports BMP images). So I set out to do what most people have already tried (and failed) and attempted to use the undocumented verb “setdesktopwallpaper”. And then my app crashes.
Looking at what was going on, something was definitely weird. At the point of the crash, my instruction pointer was pointing to garbage. It turns out there is a bug in the class that handles this verb. When that class receives the request to execute your “set desktop background” request, it will dispatch a new thread that will do that in the background. The main thread doesn’t wait for the background thread to complete, and happily continues execution. The worker thread starts executing. At some point, the main thread calls Release() on the last object that lives in the DLL that implements the handler, and that Release causes DllRelease to be called. Once the count of references to this dll gets to zero, we will unload that DLL. That’s how we get our instruction pointer to point at garbage.
This is usually not a problem when you’re setting the desktop wallpaper through explorer because that dll is always loaded in explorer for other reasons so it’s not at risk of getting unloaded prematurely.
So the workaround in the meantime is to LoadLibrary() stobject.dll which is the guy that implements this functionality.