Obtaining File Version Information (VerQueryValue) Queries

  • Thread starter Thread starter jpshortstuff
  • Start date Start date
J

jpshortstuff

Hi, not sure if this is the right place for this but it was definitely the
closest I could find.

I am having trouble with the GetFileVersionInformation/VerQueryValue
functions and was wondering if anyone could help.

All I am trying to do is obtain a string representation of a Version Info
value for a given file. Currently, I am only getting strange unicode
characters, so not sure if my problem is in the understanding of the
functions or of the syntax surrounding char sequences/pointers. I am not
totally at ease with the information in the Win32 API about VerQueryValue to
be honest with you.

Here is the code I am currently using:

LPDWORD temp; //dummy value for GetFileVersionInfoSize function
DWORD size = GetFileVersionInfoSize((char*)name.c_str(), temp); //Store size
of version info
delete temp; //delete dummy value

char* fvBuf = new char[size]; //buffer to hold version info
GetFileVersionInfo((char*)name.c_str(), 0, size, fvBuf); //get version info

UINT bufLen; //buffer to hold length of version info string
char* tempBuf = new char[size];//buffer to hold version info string
VerQueryValue(fvBuf, TEXT("\\StringFileInfo\\040904E4\\FileDescription"),
(LPVOID*)(&tempBuf), &bufLen); //supposedly get version info string and store
in tempBuf

out << tempBuf << "\n"; //output version info string to my output stream.

Thanks in advance for any info/assistance with this little issue, sorry if I
am way off course here.

Cheers.
 
jpshortstuff said:
Hi, not sure if this is the right place for this but it was definitely the
closest I could find.

Well, maybe microsoft.public.vc.language is a better place.
I am having trouble with the GetFileVersionInformation/VerQueryValue
functions and was wondering if anyone could help.

All I am trying to do is obtain a string representation of a Version Info
value for a given file. Currently, I am only getting strange unicode
characters, so not sure if my problem is in the understanding of the
functions or of the syntax surrounding char sequences/pointers. I am not
totally at ease with the information in the Win32 API about VerQueryValue to
be honest with you.

Here is the code I am currently using:

LPDWORD temp; //dummy value for GetFileVersionInfoSize function
DWORD size = GetFileVersionInfoSize((char*)name.c_str(), temp); //Store size
of version info
delete temp; //delete dummy value

"temp" mustn't be a pointer. Change the above code to:

DWORD temp;
DWORD size = GetFileVersionInfoSize((char*)name.c_str(), &temp);
char* fvBuf = new char[size]; //buffer to hold version info
GetFileVersionInfo((char*)name.c_str(), 0, size, fvBuf); //get version info

UINT bufLen; //buffer to hold length of version info string
char* tempBuf = new char[size];//buffer to hold version info string
VerQueryValue(fvBuf, TEXT("\\StringFileInfo\\040904E4\\FileDescription"),
(LPVOID*)(&tempBuf), &bufLen); //supposedly get version info string and store
in tempBuf

Suggestion: Don't hardcode the code page, 040904E4 is not the same for all
programs. Use VerQueryValue with "\\VarFileInfo\\Translation" to get the code
page needed to build the others strings.
out << tempBuf << "\n"; //output version info string to my output stream.

Thanks in advance for any info/assistance with this little issue, sorry if I
am way off course here.

Cheers.

Regards
 
Hi,

Thanks, that really helped, I have got it working now.

I do have a question though, if you have time.

When using the translation table, you get a pointer to an array of
Language/Codepage values. I am currently solely using the first, but is there
a difference? If so, is there a way of telling which one to use?

My new code is this:

DWORD temp;
DWORD size = GetFileVersionInfoSize((char*)name.c_str(), &temp);

char* fvBuf = new char[size];
GetFileVersionInfo((char*)name.c_str(), 0, size, fvBuf);

DWORD* langCodeArray;
UINT aLen;
VerQueryValue(fvBuf, TEXT("\\VarFileInfo\\Translation"),
(LPVOID*)&langCodeArray, &aLen);

TCHAR subBlock[25];
sprintf(subBlock, TEXT("\\StringFileInfo\\%04x%04x\\CompanyName"),
LOWORD(langCodeArray[0]), HIWORD(langCodeArray[0]));

UINT bufLen;
char* tempBuf = new char[size];
VerQueryValue(fvBuf, subBlock, (LPVOID*)(&tempBuf), &bufLen);

out << tempBuf << "\n";

Notice I am using [0].

Thanks a lot for all your help, it's greatly appreciated.
 
jpshortstuff said:
Hi,

Thanks, that really helped, I have got it working now.

I do have a question though, if you have time.

When using the translation table, you get a pointer to an array of
Language/Codepage values. I am currently solely using the first, but
is there a difference? If so, is there a way of telling which one to
use?

The idea is to choose a code page similar to OS code page. AFAIK nobody include
more than one code page per file, so, from my point of view, it's correct to
choose the first array position.

My new code is this:

DWORD temp;
DWORD size = GetFileVersionInfoSize((char*)name.c_str(), &temp);

char* fvBuf = new char[size];
GetFileVersionInfo((char*)name.c_str(), 0, size, fvBuf);

DWORD* langCodeArray;
UINT aLen;
VerQueryValue(fvBuf, TEXT("\\VarFileInfo\\Translation"),
(LPVOID*)&langCodeArray, &aLen);

TCHAR subBlock[25];
sprintf(subBlock, TEXT("\\StringFileInfo\\%04x%04x\\CompanyName"),
LOWORD(langCodeArray[0]), HIWORD(langCodeArray[0]));

UINT bufLen;
char* tempBuf = new char[size];
VerQueryValue(fvBuf, subBlock, (LPVOID*)(&tempBuf), &bufLen);

out << tempBuf << "\n";

Notice I am using [0].

Thanks a lot for all your help, it's greatly appreciated.

Regards
 
Back
Top