VS_VERSION_INFO信息的读取

最近在整理东西,打算把一些小东西分类整理下,与大家分享一下:

很早以前用MFC开始在做工业软件时,经常会遇到版本备份啊什么之类的问题,那时候,不太懂,后来研究了一下API,发现了如何读取VS_VERSION_INFO。

我们知道,MFC生成的exe的所有信息都是在RC\Version\VS_VERSION_INFO里设置的,我们只要在CAboutDlg里,把PRODUCTVERSION的信息读出来,在CAboutDlg里显示出来,这样只需要每次在VVI里修改相关信息,而不用再去考虑相关信息的一致性了,因为信息源只有这一个。


新建一个CMiyaVersion类,

MiyaVersion.h文件:

接口函数为GetFileVersionInfo以及GetValue,使用时,要先调用GetFileVersionInfo获取exe的所有版本信息即:m_pVersionInfo,当然这里提供一个常用的返回信息版本号:lpszVersion,若想获得其它信息,可使用GetValue去获取

  1. CompanyName:获取公:司名称
  2. FileDescription:
  3. FileVersion:
  4. InternalName:
  5. LegalCopyright:
  6. OriginalFilename:
  7. ProductName:
  8. ProductVersion:

#pragma once
  
namespace MiyaVersion
{
#include <shlwapi.h>
#pragma comment(linker, "/defaultlib:version.lib")
 
class CMiyaVersion : public VS_FIXEDFILEINFO
{
public:
	CMiyaVersion();
	virtual ~CMiyaVersion();
 
public:
 	bool     GetFileVersionInfo(LPCTSTR lpszModuleName, LPCTSTR lpszVersion);
 	CString  GetValue(LPCTSTR lpKeyName);
 
protected:
 
	static bool DllGetVersion(LPCTSTR lpszModuleName, DLLVERSIONINFO& dvi);
 
protected:
 
	BYTE* m_pVersionInfo;   // all version info
	
	typedef struct tag_TRANSLATION
	{
		WORD langID;         // language ID
		WORD charset;        // character set (code page)
 
	} TRANSLATION, *LPTRANSLATION;
	
	TRANSLATION m_translation;
}; 
}

MiyaVersion.cpp文件

#include "stdafx.h"
#include "MiyaVersion.h"
  
using namespace MiyaVersion;
 
//
// Construction/Destruction
//
 
CMiyaVersion::CMiyaVersion()
{
    m_pVersionInfo = NULL;
}
 
CMiyaVersion::~CMiyaVersion()
{
	if (m_pVersionInfo != NULL)
	{
		delete []m_pVersionInfo;
		m_pVersionInfo = NULL;
	}
}
 
bool CMiyaVersion::GetFileVersionInfo(LPCTSTR lpszModuleName, LPCTSTR lpszVersion)
{ 
	// default = ANSI code page
	m_translation.charset = 1252;
	memset((VS_FIXEDFILEINFO*)this, 0, sizeof(VS_FIXEDFILEINFO));
	
	// get module handle
	TCHAR chFileName[_MAX_PATH] = {0};
	HMODULE hModule = ::GetModuleHandle(lpszModuleName);
	if (hModule==NULL && lpszModuleName!=NULL)
	{
		return false;
	}
 
	// get module file name
	DWORD dwLen = GetModuleFileName(hModule, chFileName, sizeof(chFileName)/sizeof(chFileName[0]));
	if (dwLen <= 0)
	{
		return false;
	}
 
	// read file version info
	DWORD dwDummyHandle = 0; // will always be set to zero
	dwLen = GetFileVersionInfoSize(chFileName, &dwDummyHandle);
	if (dwLen <= 0)
	{
		return false;
	}
 
	if (m_pVersionInfo != NULL)
	{
		delete []m_pVersionInfo;
		m_pVersionInfo = NULL;
	}
	m_pVersionInfo = new BYTE[dwLen]; // allocate version info
	if (!::GetFileVersionInfo(chFileName, 0, dwLen, m_pVersionInfo))
	{
		if (m_pVersionInfo != NULL)
		{
			delete []m_pVersionInfo;
			m_pVersionInfo = NULL;
		}
 
		return false;
	}
 
	LPVOID lpvi = NULL;
	UINT nLen = 0;
	if (!VerQueryValue(m_pVersionInfo, _T("\\"), &lpvi, &nLen))
	{
		if (m_pVersionInfo != NULL)
		{
			delete []m_pVersionInfo;
			m_pVersionInfo = NULL;
		}
 
		return false;
	}
 
	// copy fixed info to myself, which am derived from VS_FIXEDFILEINFO
	*(VS_FIXEDFILEINFO*)this = *(VS_FIXEDFILEINFO*)lpvi;
	
	// Get translation info
	if (VerQueryValue(m_pVersionInfo, _T("\\VarFileInfo\\Translation"), &lpvi, &nLen) && nLen >= 4)
	{
		m_translation = *(TRANSLATION*)lpvi;
	}
 
	CString strVersion(_T(""));
	strVersion.Format(_T("%d.%d.%d.%d"), \
		HIWORD(this->dwFileVersionMS), LOWORD(this->dwFileVersionMS), \
		HIWORD(this->dwFileVersionLS), LOWORD(this->dwFileVersionLS));
	UINT nTemp = wcslen(strVersion)+1;
 
	lstrcpyn((LPTSTR)lpszVersion, strVersion, nTemp);
  
	return (dwSignature == VS_FFI_SIGNATURE);
}
 
CString CMiyaVersion::GetValue(LPCTSTR lpKeyName)
{
	CString strVal(_T(""));
 
	if (m_pVersionInfo != NULL)
	{      
	   CString strQuery;
	   strQuery.Format(_T("\\StringFileInfo\\%04x%04x\\%s"), m_translation.langID, m_translation.charset, lpKeyName);
		
		LPCTSTR pVal = NULL;
		UINT nLenVal = 0;
		if (VerQueryValue(m_pVersionInfo, (LPTSTR)(LPCTSTR)strQuery, (LPVOID*)&pVal, &nLenVal)) 
		{
			strVal = pVal;
		}
	}
 
	return strVal;
}
 
typedef HRESULT (CALLBACK* DLLGETVERSIONPROC)(DLLVERSIONINFO *);
 
bool CMiyaVersion::DllGetVersion(LPCTSTR lpszModuleName, DLLVERSIONINFO& dvi)
{
	HINSTANCE hInst = LoadLibrary(lpszModuleName);
	if (hInst == NULL)
	{
		return false;
	}
 
	DLLGETVERSIONPROC pDllGetVersion = (DLLGETVERSIONPROC)GetProcAddress(hInst, ("DllGetVersion"));
	
	if (pDllGetVersion == NULL)
	{
		return false;
	}
 
	memset(&dvi, 0, sizeof(dvi));        // clear
	dvi.cbSize = sizeof(dvi);            // set size for Windows
	
	return SUCCEEDED((*pDllGetVersion)(&dvi));
}


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值