I am unable to fathom why there is no straightforward API to access version information from the running process. To retrieve any kind of version information, you need to call 3 APIs – GetFileVersionInfoSize, GetFileVersionInfo and VerQueryValue. Actually make that 4 APIs, since you also need to call GetModuleFileName to get the full path of the running process. In fact a simple process like retrieving the LegalCopyright version string involves the following process :-
- Call
GetModuleFileNameand retrieve the full executable path - Pass this path to
GetFileVersionInfoSizeto get the size of the version info buffer - Allocate this buffer (using
mallocas it’s supposed to be avoid*) - Call
VerQueryValuewith\\VarFileInfo\\Translationto get the list of language and code pages (though you can skip this one if you are sure of what lang/codepage you need) - Call
VerQueryValueagain specifying the\\StringFileInfo\\[LangCodeCode]you need along with the name of the version string you are after - Free the buffer allocated early on
Good heavens! How hard would it have been for the Win32 API team to have added some function like GetFileVersionString(LPCTSTR versionstring)? 😮
I agree. The API is powerful, but feels like hitting a fly with a truck most of the time.
Hi Nish,
First of all, congrats for your interesting blog !
GetFileVersion() is part of a personal lib of mine that I include in all my projects.
I suspect the problem with this version API is that some day, some guy decided to create a data format that could be extended to contain just about any hierarchical set of data. And they used it as the format for the VERSION resources. Of course, this format has never been used anywhere else but now we are stuck with it 😦
When I started to work on my product (appTranslator), I needed to be able to programmatically parse all standard resources, including VERSION resources. I can tell you that this one is the most difficult to parse.
It’s IMO even more difficult than dialogs ! All that for a couple of loose strings and locales. Moreover, it’s even functionally ambiguous: An app is theoritically free to have a VERSION resource for each supported language. But ‘thanks to’ the VERSION data format, it can as well enumerate supported languages in one single resource. So what should parsers support ?
Ok, ok, ok: end of rant 🙂
Additionally it is also important to add version.lib to the linker input settings.