#include #include #include #include #include struct Var { WORD wLength; WORD wValueLength; WORD wType; WCHAR szKey[11]; WORD Padding[1]; DWORD Value[1]; }; void print_file_version(char *file_name) { LPSTR lpVersion; DWORD dwVerHnd=0; UINT uVersionLen; DWORD dwVerInfoSize = GetFileVersionInfoSize (file_name, &dwVerHnd); if (!dwVerInfoSize) // Cannot reach the DLL file exit(1); LPSTR lpstrVffInfo = (LPSTR) new char[dwVerInfoSize]; // Alloc memory for file inf if (!GetFileVersionInfo(file_name, dwVerHnd, dwVerInfoSize, lpstrVffInfo)) { delete [] lpstrVffInfo; exit(2); // Cannot read the file information - // wierd, since we could read the information size } /* The below 'hex' value looks a little confusing, but essentially what it is, is the hexidecimal representation of a couple different values that represent the language and character set that we are wanting string values for. 040904E4 is a very common one, because it means: US English, Windows MultiLingual characterset Or to pull it all apart: 04------ = SUBLANG_ENGLISH_USA --09---- = LANG_ENGLISH ----04E4 = 1252 = Codepage for Windows:Multilingual */ unsigned char *translation; UINT translation_len = sizeof(translation); if (!VerQueryValue(lpstrVffInfo, (LPSTR) (TEXT("\\VarFileInfo\\Translation")), (LPVOID *)&translation, (UINT *)&translation_len)) { delete [] lpstrVffInfo; exit(4); // Query was unsuccessful } TCHAR key_name[256]; sprintf(key_name, TEXT("\\StringFileInfo\\%02X%02X%02X%02X\\FileVersion"), int(translation[1]), int(translation[0]), int(translation[3]), int(translation[2])); if (!VerQueryValue(lpstrVffInfo, (LPSTR) key_name, (LPVOID *)&lpVersion, (UINT *)&uVersionLen)) { delete [] lpstrVffInfo; exit(5); // Query was unsuccessful } std::cout << lpVersion << std::endl; delete [] lpstrVffInfo; } int main(int argc, char *argv[]) { while (--argc > 0) print_file_version(*++argv); return 0; }