有时我们需要获取可执行文件或DLL文件的版本信息,用于比对工具版本是否需要更新,那么如何获取文件的版本信息呢?
如下是一种版本信息的获取方法,可供参考
#pragma comment(lib,"version.lib")
#include <windows.h>
#include <stdio.h>
int GetVersionInfo(unsigned int* major_ver, unsigned int* minor_ver, unsigned int* build_num, unsigned int* revision_num)
{
int status = 0;
static unsigned int s_major_ver = 0;
static unsigned int s_minor_ver = 0;
static unsigned int s_build_num = 0;
static unsigned int s_revision_num = 0;
char VersionFilePath[MAX_PATH];
char* buf = NULL;
if( 0 == s_major_ver && 0 == s_minor_ver && 0 == s_build_num && 0 == s_revision_num )
{
char temp[1024];
// get loading path
//GetModuleHandle功能是获取一个应用程序或动态链接库的模块句柄。只有在当前进程的场景中,这个句柄才会有效。
HMODULE h = GetModuleHandle("Test.dll");
if( GetModuleFileName(h,
VersionFilePath,
MAX_PATH) == 0)
{
status = -1;
goto _ERROR;
}
// get file version indo
//如果需要获取外部exe版本信息,可以直接将路径赋值给VersionFilePath
DWORD dwHnd;
DWORD dwVerInfoSize;
if( 0 >= (dwVerInfoSize = GetFileVersionInfoSize(VersionFilePath,
&dwHnd)) )
{
status = -2;
goto _ERROR;
}
buf = new char[dwVerInfoSize];
if( NULL == buf )
{
status = -3;
goto _ERROR;
}
// get file version info
if(!GetFileVersionInfo(VersionFilePath,
dwHnd,
dwVerInfoSize,
buf))
{
status = -4;
goto _ERROR;
}
// Read the list of languages and code pages.
struct LANGANDCODEPAGE
{
WORD wLanguage;
WORD wCodePage;
}*lpTranslate;
unsigned int cbTranslate;
if(!VerQueryValue(buf, "\\VarFileInfo\\Translation", (void**)&lpTranslate, &cbTranslate))
{
status = -5;
goto _ERROR;
}
// get FileVersion string from resource
VS_FIXEDFILEINFO* p_version;
unsigned int version_len = 0;
if(!VerQueryValue(buf, "\\", (void**)&p_version, &version_len))
{
status = -6;
goto _ERROR;
}
s_major_ver = (p_version->dwFileVersionMS >> 16) & 0x0000FFFF;
s_minor_ver = p_version->dwFileVersionMS & 0x0000FFFF;
s_build_num = (p_version->dwFileVersionLS >> 16) & 0x0000FFFF;
s_revision_num = p_version->dwFileVersionLS & 0x0000FFFF;
/* get File Comments
const char* p_comments;
unsigned int comments_len = 0;
sprintf_s(temp, sizeof(temp), "\\StringFileInfo\\%04x%04x\\Comments", lpTranslate[0].wLanguage, lpTranslate[0].wCodePage);
if(!VerQueryValue(buf, temp, (void**)&p_comments, &comments_len))
{
status = -7;
goto _ERROR;
}
*/
}
// return version number
if( NULL != major_ver )
{
*major_ver = s_major_ver;
}
if( NULL != minor_ver )
{
*minor_ver = s_minor_ver;
}
if( NULL != build_num )
{
*build_num = s_build_num;
}
if( NULL != revision_num )
{
*revision_num = s_revision_num;
}
_ERROR:
delete [] buf;
return status;
}
unsigned int MajorVersion;
unsigned int MinorVersion;
unsigned int BuildNumber;
unsigned int RevisionNumber;
static char VersionString[MAX_PATH];
GetVersionInfo(&MajorVersion,
&MinorVersion,
&BuildNumber,
&RevisionNumber);
if( 0 == RevisionNumber )
{
sprintf_s(VersionString, sizeof(VersionString), "VersionInfo: v%u.%u.%02u",
MajorVersion,
MinorVersion,
BuildNumber);
}
else
{
sprintf_s(VersionString, sizeof(VersionString), "VersionInfo: v%u.%u.%02u.%02u",
MajorVersion,
MinorVersion,
BuildNumber,
RevisionNumber);
}