现在编译的dll、exe大部分讲求版本管理,在Visual Studio中添加Version可以通过在项目的资源文件中添加“资源”,选择“Version”项,然后修改“VS_VERSION_INFO”中的“FILEVERSION”、“PRODUCTVERSION”等添加版本号及其它信息。
但是创建后,有时候还需要在代码中获取这个版本号,用在比如日志记录和校验。网上找了下相关方法,找到关于宏定义、“GetFileVersionInfo”、“FindResource”三种实现的方法。
宏定义
VS2013如何获取RC文件中的版本号
在公共文件中通过宏定义版本号的4个数字,在rc、cpp文件中使用,但这样就不能用vs的IDE打开资源文件(rc是自动记录文档),这里视使用环境参考。
GetFileVersionInfo
GetFileVersionInfo获取版本号
vc 得到软件的版本信息 资源文件中的…/Version/VS_VERSION_INFO/FILEVERSION的值
这里定义的GetVersionInfo需要输入待检测dll或exe的文件名,然后处理获得版本相关信息,需要注意的是,如果提示GetFileVersionInfoSize无法链接之类的问题,可能是没有引入"version.lib",在链接器中加上即可,详情见:
解决无法链接GetFileVersionInfoSize、GetFileVersionInfo或VerQueryValue
FindResource
FindResource()函数
VC中获取资源文件中FileVersion的方法
通过FindResource 、LoadResource获取dll或exe的version信息,需要输入当前模块的句柄。
示例
以上GetFileVersionInfo、FindResource都可以获取dll或exe的版本信息,但都需要获取dll本身的名字或者模块句柄,因此如果在dll内部使用,可以通过现在常用的封装函数GetSelfModuleHandle来获取自身的版本信息。
// 获取自身句柄
HMODULE GetSelfModuleHandle()
{
MEMORY_BASIC_INFORMATION mbi;
return ((::VirtualQuery(GetSelfModuleHandle, &mbi, sizeof(mbi)) != 0) ? (HMODULE)mbi.AllocationBase : NULL);
}
// 获取自身路径
const char* GetSelfPath()
{
char DllDir[512];
GetModuleFileNameA(GetSelfModuleHandle(), DllDir, 512);
std::string StrPath(DllDir);
size_t index = StrPath.find_last_of("/\\");
StrPath = StrPath.substr(0, index);
return StrPath.c_str();
}
示例1、通过GetFileVersionInfo获取自身版本信息
void GetVersionInfo(char* strVersion)
{
TCHAR szVersionBuffer[1000] = _T("");
DWORD dwVerSize;
DWORD dwHandle;
dwVerSize = GetFileVersionInfoSizeA(GetSelfPath(), &dwHandle);
if (dwVerSize == 0)
return;
if (GetFileVersionInfoA(GetSelfPath(), 0, dwVerSize, szVersionBuffer))
{
VS_FIXEDFILEINFO * pInfo;
unsigned int nInfoLen;
if (VerQueryValue(szVersionBuffer, _T("\\"), (void**)&pInfo, &nInfoLen))
{
sprintf(strVersion, "%d.%d.%d.%d",
HIWORD(pInfo->dwFileVersionMS), LOWORD(pInfo->dwFileVersionMS),
HIWORD(pInfo->dwFileVersionLS), LOWORD(pInfo->dwFileVersionLS));
return strVersion;
}
}
return;
}
示例2、通过FindResource获取自身版本信息
void GetVersionInfo(char* strVersion)
{
HRSRC hsrc = FindResource(GetSelfModuleHandle(), MAKEINTRESOURCE(VS_VERSION_INFO), RT_VERSION);
HGLOBAL hgbl = LoadResource(GetSelfModuleHandle(), hsrc);
BYTE *pBt = (BYTE *)LockResource(hgbl);
VS_FIXEDFILEINFO* pFinfo = (VS_FIXEDFILEINFO*)(pBt + 40);
sprintf(strVersion, "%d.%d.%d.%d",
(pFinfo->dwFileVersionMS >> 16) & 0xFF,
(pFinfo->dwFileVersionMS) & 0xFF,
(pFinfo->dwFileVersionLS >> 16) & 0xFF,
(pFinfo->dwFileVersionLS) & 0xFF);
}