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

posted @ 2020-12-12 23:30  范哥范小飞  阅读(567)  评论(0编辑  收藏  举报