NULL hInstance Considered Harmful

Michael Geary | Wed, 2004-08-11 16:10
category

On a couple of occasions, I've converted large Windows applications from EXEs to DLLs which are loaded by stub EXEs. There are several reasons you might want to do this, and for the most part it's surprisingly easy. Most Windows code doesn't know or care if it's running in a DLL or EXE, as long as it has the right instance handle for any functions that load resources or the like.

There were a few Windows functions that gave us grief, though. These are the functions that accept a NULL hInstance to mean the current process. I used to think this was a nice convenience, but all the code that used a NULL hInstance had to be converted to take an explicit hInstance.

I searched for the functions that came to mind and fixed them:

GetModuleBaseName
GetModuleFileName
GetModuleHandle

But I forgot about an entire group of functions and had to find them the hard way, through some tedious debugging:

EnumResourceLanguages
EnumResourceNames
EnumResourceTypes
FindResource
FindResourceEx
FindResourceWrapW
LoadResource

Are there more functions like this?

Submitted by Mike Sax (not verified) on Wed, 2004-08-11 23:15.

I’m curious why you’d want to do the conversion… The only reason that comes to mind would be to implement a “check for updates” feature in the EXE that can replace the core of the app on the fly without file-in-use issues. Well, as I’m typing this, also maybe loading a version of your app compiled for a specific OS (like a Unicode-only version). Are there any other good reasons?

Submitted by Michael Geary (not verified) on Thu, 2004-08-12 07:33.

It could be any of the reasons that you might have structured the code as a large DLL and stub EXE in the first place. For example, you may want to make some of your code available to other apps with an in-process COM server or DLL interface.

Or it may be a case like the Python interpreter, where python.exe is a console app and pythonw.exe is a GUI app. Each of these is a small stub that loads Python23.dll, the Python interpreter itself.

Basically anything like that, where you might want to have a couple of different versions of the .exe itself but have most of the code shared between them. It could even be something as trivial as needing to run two instances of your app for different purposes but wanting them to show up with different names in Task Manager.