VerQueryValue function
Applies to: desktop apps only
Retrieves specified version information from the specified version-information resource. To retrieve the appropriate resource, before you call VerQueryValue, you must first call the GetFileVersionInfoSize function, and then the GetFileVersionInfo function.
Syntax
BOOL WINAPI VerQueryValue( __in LPCVOID pBlock, __in LPCTSTR lpSubBlock, __out LPVOID *lplpBuffer, __out PUINT puLen );
Parameters
- pBlock [in]
-
Type: LPCVOID
The version-information resource returned by the GetFileVersionInfo function.
- lpSubBlock [in]
-
Type: LPCTSTR
The version-information value to be retrieved. The string must consist of names separated by backslashes (\) and it must have one of the following forms.
- \
-
The root block. The function retrieves a pointer to the VS_FIXEDFILEINFO structure for the version-information resource.
- \VarFileInfo\Translation
-
The translation array in a Var variable information structure—the Value member of this structure. The function retrieves a pointer to this array of language and code page identifiers. An application can use these identifiers to access a language-specific StringTable structure (using the szKey member) in the version-information resource.
- \StringFileInfo\lang-codepage\string-name
-
A value in a language-specific StringTable structure. The lang-codepage name is a concatenation of a language and code page identifier pair found as a DWORD in the translation array for the resource. Here the lang-codepage name must be specified as a hexadecimal string. The string-name name must be one of the predefined strings described in the following Remarks section. The function retrieves a string value specific to the language and code page indicated.
- lplpBuffer [out]
-
Type: LPVOID*
When this method returns, contains the address of a pointer to the requested version information in the buffer pointed to by pBlock. The memory pointed to by lplpBuffer is freed when the associated pBlock memory is freed.
- puLen [out]
-
Type: PUINT
When this method returns, contains a pointer to the size of the requested data pointed to by lplpBuffer: for version information values, the length in characters of the string stored at lplpBuffer; for translation array values, the size in bytes of the array stored at lplpBuffer; and for root block, the size in bytes of the structure.
Return value
Type: BOOL
If the specified version-information structure exists, and version information is available, the return value is nonzero. If the address of the length buffer is zero, no value is available for the specified version-information name.
If the specified name does not exist or the specified resource is not valid, the return value is zero.
Remarks
This function works on 16-, 32-, and 64-bit file images.
The following are predefined version information Unicode strings.
| Comments | InternalName | ProductName |
| CompanyName | LegalCopyright | ProductVersion |
| FileDescription | LegalTrademarks | PrivateBuild |
| FileVersion | OriginalFilename | SpecialBuild |
Examples
The following example shows how to enumerate the available version languages and retrieve the FileDescription string-value for each language.
Be sure to call the GetFileVersionInfoSize and GetFileVersionInfo functions before calling VerQueryValue to properly initialize the pBlock buffer.
// Structure used to store enumerated languages and code pages.
HRESULT hr;
struct LANGANDCODEPAGE {
WORD wLanguage;
WORD wCodePage;
} *lpTranslate;
// Read the list of languages and code pages.
VerQueryValue(pBlock,
TEXT("\\VarFileInfo\\Translation"),
(LPVOID*)&lpTranslate,
&cbTranslate);
// Read the file description for each language and code page.
for( i=0; i < (cbTranslate/sizeof(struct LANGANDCODEPAGE)); i++ )
{
hr = StringCchPrintf(SubBlock, 50,
TEXT("\\StringFileInfo\\%04x%04x\\FileDescription"),
lpTranslate[i].wLanguage,
lpTranslate[i].wCodePage);
if (FAILED(hr))
{
// TODO: write error handler.
}
// Retrieve file description for language and code page "i".
VerQueryValue(pBlock,
SubBlock,
&lpBuffer,
&dwBytes);
}
Requirements
|
Minimum supported client | Windows 2000 Professional |
|---|---|
|
Minimum supported server | Windows 2000 Server |
|
Header |
|
|
Library |
|
|
DLL |
|
|
Unicode and ANSI names | VerQueryValueW (Unicode) and VerQueryValueA (ANSI) |
See also
- Reference
- GetFileVersionInfo
- VarFileInfo
- Var
- StringFileInfo
- StringTable
- String
- GetFileVersionInfoSize
- VS_FIXEDFILEINFO
- VS_VERSIONINFO
- Conceptual
- Version Information
Send comments about this topic to Microsoft
Build date: 2/3/2012
The very important here (in the example), is that pBlock is a buffer already pre-allocated (of size by GetFileVersionInfoSize), hence can be freed. And lpBuffer is just a pointer to somewhere at the data inside pBlock, thus never try free(lpBuffer). The example didn't put GetFileVersionInfoSize, GetFileVersionInfo and VerQueryValue functions together. Let's see my example then:
CString GetVersionInfo(char* filename, char* request)
{
char strTmp[512];
DWORD handle; //didn't actually use (dummy var)
int infoSize = (int) GetFileVersionInfoSize(filename, &handle);
if(infoSize == 0){
AfxMessageBox("Function <GetFileVersionInfoSize> unsuccessful!");
return "ERROR";
}
LPVOID pBlock;
pBlock = new BYTE[infoSize];
int bResult = GetFileVersionInfo(filename, handle, infoSize, pBlock);
if(bResult == 0){
AfxMessageBox("Function <GetFileVersionInfo> unsuccessful!");
return "ERROR";
}
// Structure used to store enumerated languages and code pages.
struct LANGANDCODEPAGE {
WORD wLanguage;
WORD wCodePage;
}*lpTranslate;
LPVOID lpBuffer;
UINT dwBytes;
int i, langNumber;
CString strRet;
// Read the list of languages and code pages.
bResult = VerQueryValue(pBlock, TEXT("\\VarFileInfo\\Translation"), (LPVOID*)&lpTranslate, &dwBytes);
if(bResult == 0){
AfxMessageBox("Function <VerQueryValue> for Translation unsuccessful!");
return "ERROR";
}
langNumber = dwBytes/sizeof(struct LANGANDCODEPAGE); //langNumber always must be equal 1 (in my program)
if(langNumber != 1){
sprintf(strTmp, "Error! Languages number: %d.", langNumber);
AfxMessageBox(strTmp);
return "ERROR";
}
// Read the file description for each language and code page.
HRESULT hr;
for(i=0; i<langNumber; i++){
hr = StringCchPrintf(strTmp, 512, TEXT("\\StringFileInfo\\%04x%04x\\%s"),
lpTranslate[i].wLanguage, lpTranslate[i].wCodePage, request);
if (FAILED(hr)){
AfxMessageBox("Unable to get information in this language!");
return "ERROR";
}
// Retrieve file description for language and code page "i".
bResult = VerQueryValue(pBlock, strTmp, &lpBuffer, &dwBytes);
if(bResult == 0){
AfxMessageBox("Function <VerQueryValue> for StringFileInfo unsuccessful!");
return "ERROR";
}
}
strRet = (char*)lpBuffer;
delete [] pBlock;
strRet.Replace(", ", ".");
return strRet;
}
- 4/10/2012
- Dionathan Nakamura
PUINT is passed to the function (a pointer to UINT) and not PUINT*. Therefore just a UNIT is returned and not a pointer to UINT.
Therefore the text should be formulated as:
"When this method returns, contains the size of the requested data pointed to by lplpBuffer"
- 4/20/2011
- Simon4