[Code Sample] Retrieve C++ Application Version from VS_VERSION Resource
Sometimes you may need to retrieve the application version from its own resources. While sounding trivial, this task is not so easy to solve. While you can easily access string resources or dialog resources using the dedicated WinAPI functions, the version resource retrieval is not so easy. That's because the corresponding function VerQueryValue is intended for retrieving versions from another loaded module, not from own executable. So, how would you retrieve the application version from your own executable then?
Should you load the entire executable into memory for the second time and waste process memory for such an easy task? Fortunately, there is much less memory-consumptive way, load just the version info, query the version, and then free the memory.
The provided code loads the resources to memory, makes a modifiable copy of them, and makes a query.
Here is the code sample:
// version info will be appended here
TCHAR szAppName[128] = _T("MyApp ");
void GetVersionFromResource()
{
HRSRC hResInfo;
DWORD dwSize;
HGLOBAL hResData;
LPVOID pRes, pResCopy;
UINT uLen = 0;
VS_FIXEDFILEINFO* lpFfi = NULL;
HINSTANCE hInst = ::GetModuleHandle(NULL);
hResInfo = FindResource(hInst, MAKEINTRESOURCE(1), RT_VERSION);
if (hResInfo)
{
dwSize = SizeofResource(hInst, hResInfo);
hResData = LoadResource(hInst, hResInfo);
if (hResData)
{
pRes = LockResource(hResData);
if (pRes)
{
pResCopy = LocalAlloc(LMEM_FIXED, dwSize);
if (pResCopy)
{
CopyMemory(pResCopy, pRes, dwSize);
if (VerQueryValue(pResCopy, _T("\\"), (LPVOID*)&lpFfi, &uLen))
{
if (lpFfi != NULL)
{
DWORD dwFileVersionMS = lpFfi->dwFileVersionMS;
DWORD dwFileVersionLS = lpFfi->dwFileVersionLS;
DWORD dwLeftMost = HIWORD(dwFileVersionMS);
DWORD dwSecondLeft = LOWORD(dwFileVersionMS);
DWORD dwSecondRight = HIWORD(dwFileVersionLS);
DWORD dwRightMost = LOWORD(dwFileVersionLS);
_stprintf(szAppName + _tcslen(szAppName), _T(" %d.%d.%d.%d"), dwLeftMost, dwSecondLeft, dwSecondRight, dwRightMost);
}
}
LocalFree(pResCopy);
}
}
}
}
}