現在編譯的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);
}