Getting file version information

by Bret Knigge

Under the Project Options dialog box in the C++Builder IDE, you will find the Version Info page. This is where you specify the file version information, including the product name, product version number, and file description to name just a few. This information is then displayed when a user right clicks on the application in Windows Explorer and chooses Properties from the context menu. This is all well and good, but C++Builder does not come with a component to actually retrieve this version information from within your program. This article will explain how to extract that information. The resulting information can then be displayed in an About dialog box.

There are three API functions that need to be called to obtain the version information for a file. The GetFileVersionInfoSize() and GetFileVersionInfo() function are used to extract version information about a specified file (application or DLL). The VerQueryValue() function returns specific data related to the version information. The first step is to get the size of the version information block within the file. That is accomplished with this code:

 

DWORD dwSize;

DWORD dwReserved;

AnsiString FileName =

Application->ExeName;

dwSize = GetFileVersionInfoSize(

FileName.c_str(), &dwReserved);

 

The second parameter in the function call is required by Windows and is used to set the value to zero. It has no meaningful purpose beyond that.

Now that you have the size of the version information block, you can get version information itself using GetFileVersionInfo(). Here’s the code that does that:

LPVOID lpBuffer = new(dwSize);

GetFileVersionInfo(

FileName.c_str(), 0, dwSize, lpBuffer);

 

lpBuffer is an untyped block of memory (a void*) and will contain the version information when GetFileVersionInfo() returns. In this case I used operator new to allocate memory for lpBuffer. I could also have used the Windows API, function HeapAlloc(), to allocate the memory but that is a bit old fashioned in C++.

lpBuffer now holds the file’s version information. However you still need to use VerQueryValue() to extract the individual data related to that information. The following code shows how this is done:

 

LPVOID lpStr;

UINT wLength;

VerQueryValue(lpBuffer,

"\\StringFileInfo\\040904E4\\”

“ProductName", &lpStr, &dwLength);

AnsiString Info =

reinterpret_cast<char *>(lpStr);

 

Using the VerQueryValue() function is fairly straightforward, with the result being written to the third argument (lpStr), which in then cast to a more meaningful type (an AnsiString).

When you've finished accessing the version information, you must free the memory allocated for lpBuffer. If the memory was allocated using the Windows API function HeapAlloc(), then you must call HeapFree() to free the memory. If, on the other hand you used operator new to allocate the memory, you would need to use operator delete to free the memory. Here’s how that code looks:

 

if (lpBuffer)

delete(lpBuffer);

 

Adding version information to an About dialog box in an application can aid in giving your program a professional touch. For those that are interested, the second argument in the VerQueryValue() call can be obtained by examining the resource file of the application using a resource editor such as that found in Borland C++ 5.02.