-
file version
I added a version resource to my file (dll) and I want to read it in that same file. (the version info is ther in explorer so that works I think)
I'm using "VerQueryValue" but I don't know if this is the best way to do it. I think there must be a better way because its't the same file that contains the resource.
here's the code I'm using.
Code:
DWORD versioninfo_size;
DWORD buffer;
void *versioninfo;
void *data;
UINT uint;
versioninfo_size=GetFileVersionInfoSize ( "filename.dll", &buffer);
GetFileVersionInfo("filename.dll",NULL,versioninfo_size, &versioninfo);
VerQueryValue(versioninfo,"\\StringFileInfo\\081304b0\\FileVersion",&data,&uint);
edit: versioninfo_size gets it size as it should (I think)
VerQueryValue gives me a unhandled exception.
could this be that it is because the code is in the same file as the resource???
I got 081304b0 from the .rc (don't know if I'm allowed to do this)
What am I doing wrong?
compiler: MSVC++ 6
thx
maes
-
GetFileVersionInfoSize() is a funny api because it actually returns the size. The variable you pass in is simply a dummy that will contain zero on return.
Once you have the required size, you need to allocate memory to hold the version information resource. Here is something that may work. I haven't tested it, so let me know if it works.
Code:
void ShowFileVersion(void)
{
DWORD versioninfo_size;
void* versioninfo;
LPTSTR file_version;
UINT cchLength;
DWORD dwDummy;
TCHAR szModulePath[MAX_PATH];
CHAR szBuf[200];
/* Get the complete path to the module(DLL or EXE) we are executing in. */
if (0 == GetModuleFileName(NULL, szModulePath, MAX_PATH))
{
return FALSE;
}
/* Get the size of the version information resource in the file. */
versioninfo_size = GetFileVersionInfoSize(szModulePath, &dwDummy);
if (0 == versioninfo_size)
{
return FALSE;
}
/* Allocate memory for the version information resource. */
versioninfo = malloc(versioninfo_size);
if (NULL = versioninfo)
{
return FALSE;
}
/* Get the version information resource in our buffer. */
if (!GetFileVersionInfo(szModulePath, 0, versioninfo_size, versioninfo))
{
free(versioninfo);
return FALSE;
}
/* Get a pointer to the FileVersion string value in file_version. */
if (!VerQueryValue(versioninfo,"\\StringFileInfo\\081304b0\\FileVersion", (void **) &file_version, &cchLength) ||
0 == cchLength || NULL == file_version)
{
free(versioninfo);
return FALSE;
}
MessageBox(NULL, file_version, TEXT("File Version"), NULL, 0);
free(versioninfo);
return TRUE;
}
Search for "\\StringFileInfo\\040904b0\\FileVersion"(0409 is for English) for more examples.
P.S I didn't know that Dutch was a language used in Belgium, how many languages does Belgium use!?
-
I forgot to allocate memory Dooooh. I went to a concert last night and I'm probably not awake yet. the usual monday morning sickness I guess :D
but your code did the trick. Thx anonytmouse
I think I'm going to put the resource in english (to make it more bug proof) because as you asked, Belgium is a small country of many languages.
3 official: Dutch, Frenc, German (only small part but it's an official language)
and besides that, you need to know english if you want a job (most of the time)
So I think I'll put it in English to be sure no one changes it to french.
Thx for the help
-
If needed, you can support multiple languages in your version information:
Code:
// Sample version information...
VS_VERSION_INFO VERSIONINFO
FILEVERSION 1,0,0,0 // Use this binary version number instead of a localized string - see below
PRODUCTVERSION 1,0,0,0
FILEOS VOS_NT
FILETYPE VFT_APP
{
BLOCK "StringFileInfo"
{
BLOCK "040904B0"
{
VALUE "CompanyName", "Company name in English"
VALUE "FileDescription", "File description in English"
VALUE "FileVersion", "1.0.0.0"
// Other values
}
BLOCK "081304B0"
{
VALUE "CompanyName", "Company name in Belgian Dutch"
VALUE "FileDescription", "File description in Belgian Dutch"
VALUE "FileVersion", "1.0.0.0"
// Other values
}
}
}
Instead of using a string version, for internal purposes you are probably better off using the binary version number:
Code:
void ShowFileVersion(void)
{
DWORD versioninfo_size;
void* versioninfo;
VS_FIXEDFILEINFO * fixed_info;
UINT cbLength;
DWORD dwDummy;
TCHAR szModulePath[MAX_PATH];
CHAR szBuf[200];
/* Get the complete path to the module(DLL or EXE) we are executing in. */
if (0 == GetModuleFileName(NULL, szModulePath, MAX_PATH))
{
return FALSE;
}
/* Get the size of the version information resource in the file. */
versioninfo_size = GetFileVersionInfoSize(szModulePath, &dwDummy);
if (0 == versioninfo_size)
{
return FALSE;
}
/* Allocate memory for the version information resource. */
versioninfo = malloc(versioninfo_size);
if (NULL = versioninfo)
{
return FALSE;
}
/* Get the version information resource in our buffer. */
if (!GetFileVersionInfo(szModulePath, 0, versioninfo_size, versioninfo))
{
free(versioninfo);
return FALSE;
}
/* Get a pointer to the fixed file version info in fixed_info. */
if (!VerQueryValue(versioninfo,"\\", (void **) &fixed_info, &cbLength) ||
cbLength < sizeof(VS_FIXEDFILEINFO) || NULL == fixed_info)
{
free(versioninfo);
return FALSE;
}
/* Use the values in fixed_info. */
{
TCHAR buf[256];
wsprintf(buf, TEXT("The version of this file is %d.%d"),
fixed_info->dwFileVersionMS, fixed_info->dwFileVersionLS);
MessageBox(NULL, buf, TEXT("File Version"), NULL, 0);
}
free(versioninfo);
return TRUE;
}
This will also be easier to compare against.
-
A search has just got me here as I'm looking to piuck up the CompanyName in an application I'm working on, but I don't understand the highlighed bit in the following line of code:
VerQueryValue(versioninfo,"\\StringFileInfo\\081304b0\\FileVersion",&data,&uint);
What is that number and what is it used for? It looks as though it's something to do with Unicode, and if you want the result in English then that's the number you use.
Is that correct, or does it serve some other purpose?
-
Resurrecting very old threads is frowned upon at Cboard. Typically, you should start a new thread and link back to the old thread.
As outlined above, the version information may be provided in multiple languages in the one executable. The language number is then used in the query string to indicate which language information you want.
The first half of the number you have highlighted is the language code (0x0813 is the language code for "Dutch (Belgium)"). You can find a complete list of language codes at MSDN. The second half is the character encoding used to encode the version information (0x04b0 is the code page for "Unicode UCS-2 Little-Endian", which is the default encoding used for version information). You can find a complete list of code pages at MSDN (however, the code page numbers are given in decimal while the version string requires the code page in hexadecimal).
For US English, the language code is 0x0409. So to retrieve version information in US English (the default), you would use the query string:
Code:
\\StringFileInfo\\040904b0\\CompanyName