windows API获取PE文件的版本信息
PE文件的版本信息
版本信息在vc编程时,定义在rc资源文件里。见罗云彬的《Windows 32 位环境下汇编语言程序设计》p179
在Windows API中GetFileVersionInfoSize、GetFileVersionInfo、VerQueryValue
驻留在version.dll文件中,在汇编中使用,则加上include Version.inc和version.lib
首先用GetFileVersionInfoSize,返回值是版本信息的长度,如果返回0,则文件不是PE文件或者没有定义版本信息资源。
然后用GetFileVersionInfo将版本信息读取到一个缓冲区中。缓冲区的大小必须大于上一步获取的大小。
再用VerQueryValue去解码。
原文的案例是用汇编写的对话框。
本文是c++移植版。
GetVersionInfo.cpp
1 /* 2 *作者:范哥范小飞 3 * 4 *改编自 罗云彬 的《windows 32位环境下 汇编程序设计》 5 * 6 *提取PE文件中资源中的版本信息 7 * 8 */ 9 #include<stdio.h> 10 /* 11 * 获取文件中资源的版本信息 12 * 13 * 需要包含version.lib 14 * 15 * 入口参数:文件名,返回信息的缓冲区 16 * 17 * 返回参数:true = 成功 false = 失败 18 * 19 */ 20 21 22 #pragma comment(lib, "version.lib") 23 24 25 bool GetVersionInfo(char *szPath, char *szBuffer) { 26 char verInfoBuffer[4096]; 27 char szStringInfo[512]; 28 char szString[512]; 29 LPVOID lpData; 30 UINT dwLen=sizeof(VS_FIXEDFILEINFO); 31 VS_FIXEDFILEINFO *vfbuffer; 32 33 34 int retSize = GetFileVersionInfoSize(szPath, 0); 35 if (retSize==0) { 36 //文件可能不是PE文件,或者文件没有版本信息 37 wsprintf(szBuffer, "文件可能没有版本信息,或者不是有效PE文件\0"); 38 return false; 39 } 40 // 获取固定属性 41 GetFileVersionInfo(szPath, 0, sizeof(verInfoBuffer), verInfoBuffer); 42 VerQueryValue(verInfoBuffer, "\\", (void**)&vfbuffer, &dwLen); 43 // 计算版本号 44 wsprintf(szBuffer, "固定版本信息属性:\r\nFileVersion: %d.%d.%d.%d \r\nProductVersion: %d.%d.%d.%d\r\nFileOS: %08x\r\nFileType: %08x\r\n字符串版本属性:\r\n\0", 45 HIWORD(vfbuffer->dwFileVersionMS), 46 LOWORD(vfbuffer->dwFileVersionMS), 47 HIWORD(vfbuffer->dwFileVersionLS), 48 LOWORD(vfbuffer->dwFileVersionLS), 49 HIWORD(vfbuffer->dwProductVersionMS), 50 LOWORD(vfbuffer->dwProductVersionMS), 51 HIWORD(vfbuffer->dwProductVersionLS), 52 LOWORD(vfbuffer->dwProductVersionLS), 53 vfbuffer->dwFileOS, 54 vfbuffer->dwFileType); 55 printf("%s", szBuffer); 56 // 获取语言集 57 VerQueryValue(verInfoBuffer, "\\VarFileInfo\\Translation", (void**)&vfbuffer, &dwLen); 58 //DWORD * Translation = (DWORD*)vfbuffer; 59 //Translation[0] 60 DWORD strTranslation = MAKELONG(HIWORD(((DWORD*)vfbuffer)[0]), LOWORD(((DWORD*)vfbuffer)[0])); 61 wsprintf(szStringInfo, "Translation:%08X //080404B0为中文,040904E4为英文(大端序) \r\n\r\n", strTranslation); 62 lstrcat(szBuffer, szStringInfo); 63 printf("Translation:%08X \n\n", strTranslation);//080404b0为中文,040904E4为英文 64 // 获取字符串版本信息 65 66 dwLen = sizeof(szString); 67 wsprintf(szStringInfo, "\\StringFileInfo\\%08x\\Comments", strTranslation); 68 ZeroMemory(szString, sizeof(szString)); 69 VerQueryValue(verInfoBuffer, szStringInfo, (void**)&szString, &dwLen); 70 wsprintf(szStringInfo, "Comments -> %s\r\n", szString); 71 lstrcat(szBuffer, szStringInfo); 72 printf("%s", szStringInfo); 73 74 ZeroMemory(szStringInfo, sizeof(szStringInfo)); 75 wsprintf(szStringInfo, "\\StringFileInfo\\%08X\\CompanyName", strTranslation); 76 ZeroMemory(szString, sizeof(szString)); 77 VerQueryValue(verInfoBuffer, szStringInfo, &lpData, &dwLen); 78 //返回的是字符串指针 79 //printf("debug : %s\n", lpData); 80 wsprintf(szStringInfo, "CompanyName -> %s\r\n", lpData); 81 lstrcat(szBuffer, szStringInfo); 82 printf("%s", szStringInfo); 83 84 ZeroMemory(szStringInfo, sizeof(szStringInfo)); 85 wsprintf(szStringInfo, "\\StringFileInfo\\%08X\\FileDescription", strTranslation); 86 ZeroMemory(szString, sizeof(szString)); 87 VerQueryValue(verInfoBuffer, szStringInfo, &lpData, &dwLen); 88 //返回的是字符串指针 89 //printf("debug : %s\n", lpData); 90 wsprintf(szStringInfo, "FileDescription -> %s\r\n", lpData); 91 lstrcat(szBuffer, szStringInfo); 92 printf("%s", szStringInfo); 93 94 ZeroMemory(szStringInfo, sizeof(szStringInfo)); 95 wsprintf(szStringInfo, "\\StringFileInfo\\%08X\\FileVersion", strTranslation); 96 ZeroMemory(szString, sizeof(szString)); 97 VerQueryValue(verInfoBuffer, szStringInfo, &lpData, &dwLen); 98 //返回的是字符串指针 99 //printf("debug : %s\n", lpData); 100 wsprintf(szStringInfo, "FileVersion -> %s\r\n", lpData); 101 lstrcat(szBuffer, szStringInfo); 102 printf("%s", szStringInfo); 103 104 ZeroMemory(szStringInfo, sizeof(szStringInfo)); 105 wsprintf(szStringInfo, "\\StringFileInfo\\%08X\\InternalName", strTranslation); 106 ZeroMemory(szString, sizeof(szString)); 107 VerQueryValue(verInfoBuffer, szStringInfo, &lpData, &dwLen); 108 //返回的是字符串指针 109 //printf("debug : %s\n", lpData); 110 wsprintf(szStringInfo, "InternalName -> %s\r\n", lpData); 111 lstrcat(szBuffer, szStringInfo); 112 printf("%s", szStringInfo); 113 114 ZeroMemory(szStringInfo, sizeof(szStringInfo)); 115 wsprintf(szStringInfo, "\\StringFileInfo\\%08X\\LegalCopyright", strTranslation); 116 ZeroMemory(szString, sizeof(szString)); 117 VerQueryValue(verInfoBuffer, szStringInfo, &lpData, &dwLen); 118 //返回的是字符串指针 119 //printf("debug : %s\n", lpData); 120 wsprintf(szStringInfo, "LegalCopyright -> %s\r\n", lpData); 121 lstrcat(szBuffer, szStringInfo); 122 printf("%s", szStringInfo); 123 124 ZeroMemory(szStringInfo, sizeof(szStringInfo)); 125 wsprintf(szStringInfo, "\\StringFileInfo\\%08X\\LegalTrademarks", strTranslation); 126 ZeroMemory(szString, sizeof(szString)); 127 VerQueryValue(verInfoBuffer, szStringInfo, &lpData, &dwLen); 128 //返回的是字符串指针 129 //printf("debug : %s\n", lpData); 130 wsprintf(szStringInfo, "LegalTrademarks -> %s\r\n", lpData); 131 lstrcat(szBuffer, szStringInfo); 132 printf("%s", szStringInfo); 133 134 135 ZeroMemory(szStringInfo, sizeof(szStringInfo)); 136 wsprintf(szStringInfo, "\\StringFileInfo\\%08X\\OriginalFilename", strTranslation); 137 ZeroMemory(szString, sizeof(szString)); 138 VerQueryValue(verInfoBuffer, szStringInfo, &lpData, &dwLen); 139 //返回的是字符串指针 140 //printf("debug : %s\n", lpData); 141 wsprintf(szStringInfo, "OriginalFilename -> %s\r\n", lpData); 142 lstrcat(szBuffer, szStringInfo); 143 printf("%s", szStringInfo); 144 145 146 ZeroMemory(szStringInfo, sizeof(szStringInfo)); 147 wsprintf(szStringInfo, "\\StringFileInfo\\%08X\\PrivateBuild", strTranslation); 148 ZeroMemory(szString, sizeof(szString)); 149 VerQueryValue(verInfoBuffer, szStringInfo, &lpData, &dwLen); 150 //返回的是字符串指针 151 //printf("debug : %s\n", lpData); 152 wsprintf(szStringInfo, "PrivateBuild -> %s\r\n", lpData); 153 lstrcat(szBuffer, szStringInfo); 154 printf("%s", szStringInfo); 155 156 157 ZeroMemory(szStringInfo, sizeof(szStringInfo)); 158 wsprintf(szStringInfo, "\\StringFileInfo\\%08X\\ProductName", strTranslation); 159 ZeroMemory(szString, sizeof(szString)); 160 VerQueryValue(verInfoBuffer, szStringInfo, &lpData, &dwLen); 161 //返回的是字符串指针 162 //printf("debug : %s\n", lpData); 163 wsprintf(szStringInfo, "ProductName -> %s\r\n", lpData); 164 lstrcat(szBuffer, szStringInfo); 165 printf("%s", szStringInfo); 166 167 168 ZeroMemory(szStringInfo, sizeof(szStringInfo)); 169 wsprintf(szStringInfo, "\\StringFileInfo\\%08X\\ProductVersion", strTranslation); 170 ZeroMemory(szString, sizeof(szString)); 171 VerQueryValue(verInfoBuffer, szStringInfo, &lpData, &dwLen); 172 //返回的是字符串指针 173 //printf("debug : %s\n", lpData); 174 wsprintf(szStringInfo, "ProductVersion -> %s\r\n", lpData); 175 lstrcat(szBuffer, szStringInfo); 176 printf("%s", szStringInfo); 177 178 ZeroMemory(szStringInfo, sizeof(szStringInfo)); 179 wsprintf(szStringInfo, "\\StringFileInfo\\%08X\\SpecialBuild", strTranslation); 180 ZeroMemory(szString, sizeof(szString)); 181 VerQueryValue(verInfoBuffer, szStringInfo, &lpData, &dwLen); 182 //返回的是字符串指针 183 //printf("debug : %s\n", lpData); 184 wsprintf(szStringInfo, "SpecialBuild -> %s\r\n", lpData); 185 lstrcat(szBuffer, szStringInfo); 186 printf("%s", szStringInfo); 187 188 return true; 189 }
使用方法:
char szBuffer[4096];
char szPath[MAX_PATH]="";//你的文件路径
GetVersionInfo(szPath, szBuffer);
效果:
适用于对话框的文本控件。
踩坑日记:
1:用到对话框的文本控件里时,edit换行需要\r\n,且控件需要开启多行支持
2:VerQueryValue第三个参数返回的是一个字符串指针,自己不需要分配栈空间,printf操作时需要获取间接取值(RetStr = (char*)lpData;)
参考资料:
C++获取文件版本信息 https://blog.csdn.net/u012592062/article/details/78667485?utm_source=blogxgwz5
VerQueryValue获取文件-属性-详细信息 https://blog.csdn.net/liwen930723/article/details/49471459