有时我们需要获取可执行文件或DLL文件的版本信息,用于比对工具版本是否需要更新,那么如何获取文件的版本信息呢?

如下是一种版本信息的获取方法,可供参考

#pragma comment(lib,"version.lib")

#include

#include

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);

}