C++文件操作——获取可执行文件或DLL版本信息

有时我们需要获取可执行文件或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);
}



你可能感兴趣的:(C++,文件操作)