CFileVerHelper.h
#pragma once #include <wtypesbase.h> #include <string> #include <tchar.h> #ifdef_UNICODE using _tstring = std::wstring; #else using _tstring = std::string; #endif // //typedef struct tagVS_FIXEDFILEINFO { // DWORD dwSignature; // Contains the value 0xFEEF04BD. This is used in conjunction with the szKey member of the VS_VERSIONINFO structure when searching for the VS_FIXEDFILEINFO structure. // DWORD dwStrucVersion; // The high-order word of this member contains the major version number, and the low-order word contains the minor version number // DWORD dwFileVersionMS; // The file version number is 32 bits higher // DWORD dwFileVersionLS; // File version number lower 32 bits // DWORD dwProductVersionMS; // Higher 32 digits of the product version number // DWORD dwProductVersionLS; // Product version number lower 32 bits // DWORD dwFileFlagsMask; // Bitmask containing the valid bits in specified dwFileFlags. Defined bits are only valid when creating a file. // DWORD dwFileFlags; // bitmask containing boolean attributes for the specified file // DWORD dwFileOS; // bitmask containing boolean attributes for the specified file // DWORD dwFileType; // General type of file // DWORD dwFileSubtype; // The subtype of the file // DWORD dwFileDateMS; // file date timestamp high 32 bits // DWORD dwFileDateLS; // File date timestamp lower 32 bits //} VS_FIXEDFILEINFO; typedef struct _VS_VERSIONINFO { WORD wLength; //The length of the VS_VERSIONINFO structure (in bytes) WORD wValueLength; //The length of the Value member (in bytes) WORD wType; //The data type in the version resource. This member is 1 if the version resource contains text data; it is 0 if the version resource contains binary data. WCHAR szKey[16]; //Unicode string L"VS_VERSION_INFO". WORD Padding1; // Contains any zero WORDs needed to align the Value member on a 32-bit boundary. VS_FIXEDFILEINFO Value; //Any data associated with this VS_VERSIONINFO structure, the wValueLength member specifies the length of this member; if wValueLength is zero, this member does not exist. WORD Padding2; // Any zero word required to align the Children member on a 32-bit boundary WORD Children; // an array of zero or one StringFileInfo structures _VS_VERSIONINFO() { ZeroMemory(this, sizeof(_VS_VERSIONINFO)); } } VS_VERSIONINFO, * PVS_VERSIONINFO; typedef CONST PVS_VERSIONINFO PCVS_VERSIONINFO; class CFileVerHelper { struct LANGANDCODEPAGE { WORD wLanguage; WORD wCodePage; }; public: CFileVerHelper(); CFileVerHelper(const _tstring & strFile); ~CFileVerHelper(); CFileVerHelper operator = (const CFileVerHelper & r) = delete; static _tstring GetCurrentExeVersion(); public: bool LoadFile(const _tstring & amp; strFile); //load file information bool IsValid() const; void Close(); bool GetComments(_tstring & amp; strRes) const; //File comments bool GetInternalName(_tstring & amp; strRes) const; //internal name bool GetProductName(_tstring & amp; strRes) const; //product name bool GetCompanyName(_tstring & amp; strRes) const; //company name bool GetLegalCopyright(_tstring & amp; strRes) const; //legal copyright bool GetProductVersion(_tstring & amp; strRes) const; //Product version bool GetFileDescription(_tstring & amp; strRes) const; //file description bool GetLegalTrademarks(_tstring & amp; strRes) const; //Legal Trademarks bool GetPrivateBuild(_tstring & amp; strRes) const; //private version bool GetFileVersion(_tstring & amp; strRes) const; //file version bool GetOriginalFilename(_tstring & amp; strRes) const; //Original file name bool GetSpecialBuild(_tstring & amp; strRes) const; //special build PCVS_VERSIONINFO GetVersionInfo() const; private: bool QueryInfo(const _tstring strName, _tstring & amp; strRes) const; //query file information PVS_VERSIONINFO m_lpVerData = nullptr; //file information data pointer DWORD m_dwVerSize = 0; //file information data size LANGANDCODEPAGE *m_lpTranslate = nullptr; //language code page };
CFileVerHelper.cpp
#include "CFileVerHelper.h" #include <tchar.h> #include <strsafe.h> #pragma comment(lib, "Version. lib") CFileVerHelper::CFileVerHelper() { } CFileVerHelper::CFileVerHelper(const _tstring & strFile) { (void)this->LoadFile(strFile); } CFileVerHelper::~CFileVerHelper() { this->Close(); } _tstring CFileVerHelper::GetCurrentExeVersion() { TCHAR szBuf[MAX_PATH] = { 0 }; GetModuleFileName(NULL, szBuf, _countof(szBuf)); CFileVerHelper obj; obj.LoadFile(szBuf); _tstring strVer; obj. GetFileVersion(strVer); return strVer; } bool CFileVerHelper::LoadFile(const _tstring & strFile) { BOOL isDisableWow64Fs = FALSE; PVOID OldValue = NULL; BOOL isSuccess = FALSE; UINT cbTranslate = 0; if (strFile. empty()) { goto L_Cleanup; } this->Close(); isDisableWow64Fs = Wow64DisableWow64FsRedirection( & amp;OldValue); m_dwVerSize = GetFileVersionInfoSize(strFile.c_str(), 0); if (0 == m_dwVerSize) { goto L_Cleanup; } m_lpVerData = (PVS_VERSIONINFO)::HeapAlloc(::GetProcessHeap(), 0, m_dwVerSize); if (!m_lpVerData) { goto L_Cleanup; } if (!GetFileVersionInfo(strFile.c_str(), 0, m_dwVerSize, m_lpVerData)) { goto L_Cleanup; } if (!VerQueryValue(m_lpVerData, _T("\VarFileInfo\Translation"), (LPVOID*) & amp;m_lpTranslate, & amp;cbTranslate)) { goto L_Cleanup; } isSuccess = TRUE; L_Cleanup: if (!isSuccess) { this->Close(); } if (isDisableWow64Fs) { Wow64RevertWow64FsRedirection(OldValue); } return isSuccess; } bool CFileVerHelper::IsValid() const { return nullptr != m_lpVerData; } void CFileVerHelper::Close() { if (m_lpVerData) { ::HeapFree(::GetProcessHeap(), 0, m_lpVerData); m_lpVerData = nullptr; m_dwVerSize = 0; } } bool CFileVerHelper::QueryInfo(const _tstring strName, _tstring & amp; strRes) const { TCHAR strQuery[MAX_PATH] = { 0 }; HRESULT hr = S_OK; BOOL isSuccess = FALSE; LPCTSTR lpQueryRes = NULL; UINT uQueryCchSize; strRes. clear(); if (!m_lpVerData || !m_lpTranslate) { goto L_Cleanup; } hr = StringCchPrintf(strQuery, _countof(strQuery), _T("\StringFileInfo\ x x\%s"), m_lpTranslate[0].wLanguage, m_lpTranslate[0].wCodePage, strName.c_str()); if (FAILED(hr)) { goto L_Cleanup; } if (!VerQueryValue(m_lpVerData, strQuery, (LPVOID*) & amp;lpQueryRes, & amp;uQueryCchSize)) { goto L_Cleanup; } strRes = lpQueryRes; isSuccess = TRUE; L_Cleanup: return isSuccess; } bool CFileVerHelper::GetComments(_tstring & amp; strRes) const { return QueryInfo(_T("Comments"), strRes); } bool CFileVerHelper::GetInternalName(_tstring & amp; strRes) const { return QueryInfo(_T("InternalName"), strRes); } bool CFileVerHelper::GetProductName(_tstring & strRes) const { return QueryInfo(_T("ProductName"), strRes); } bool CFileVerHelper::GetCompanyName(_tstring & strRes) const { return QueryInfo(_T("CompanyName"), strRes); } bool CFileVerHelper::GetLegalCopyright(_tstring & strRes) const { return QueryInfo(_T("LegalCopyright"), strRes); } bool CFileVerHelper::GetProductVersion(_tstring & amp; strRes) const { return QueryInfo(_T("ProductVersion"), strRes); } bool CFileVerHelper::GetFileDescription(_tstring & amp; strRes) const { return QueryInfo(_T("FileDescription"), strRes); } bool CFileVerHelper::GetLegalTrademarks(_tstring & amp; strRes) const { return QueryInfo(_T("LegalTrademarks"), strRes); } bool CFileVerHelper::GetPrivateBuild(_tstring & strRes) const { return QueryInfo(_T("PrivateBuild"), strRes); } bool CFileVerHelper::GetFileVersion(_tstring & amp; strRes) const { return QueryInfo(_T("FileVersion"), strRes); } bool CFileVerHelper::GetOriginalFilename(_tstring & amp; strRes) const { return QueryInfo(_T("OriginalFilename"), strRes); } bool CFileVerHelper::GetSpecialBuild(_tstring & strRes) const { return QueryInfo(_T("SpecialBuild"), strRes); } PCVS_VERSIONINFO CFileVerHelper::GetVersionInfo() const { return m_lpVerData; }