Visual Studio获取dll自身Version信息

  现在编译的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);
}

  

  

  

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个简单的 MFC 茶壶代码,用于在 Visual Studio 中绘制一个简单的茶壶: 1. 创建一个 MFC 应用程序项目。 2. 打开 Class View 窗口,右键单击该项目,然后选择添加->类。 3. 在“添加类”对话框中,选择“MFC”类类别,然后选择“MFC ActiveX 控件”类模板。 4. 在“添加 MFC ActiveX 控件”对话框中,输入“CTeaPot”作为控件类名称,然后选择“框架支持 ActiveX 控件”复选框。 5. 单击“完成”按钮,创建一个新的 MFC ActiveX 控件类。 6. 在“CTeaPot.h”文件中添加以下代码: ```cpp class CTeaPot : public COleControl { DECLARE_DYNCREATE(CTeaPot) // Construction public: CTeaPot(); // Overrides // ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CTeaPot) public: virtual void OnDraw(CDC* pdc, const CRect& rcBounds, const CRect& rcInvalid); virtual BOOL PreCreateWindow(CREATESTRUCT& cs); protected: virtual void DoPropExchange(CPropExchange* pPX); virtual void OnResetState(); //}}AFX_VIRTUAL // Implementation protected: ~CTeaPot(); DECLARE_OLECREATE_EX(CTeaPot) // Class factory and guid DECLARE_OLETYPELIB(CTeaPot) // GetTypeInfo DECLARE_PROPPAGEIDS(CTeaPot) // Property page IDs DECLARE_OLECTLTYPE(CTeaPot) // Type name and misc status // Message maps //{{AFX_MSG(CTeaPot) //}}AFX_MSG DECLARE_MESSAGE_MAP() // Dispatch maps //{{AFX_DISPATCH(CTeaPot) afx_msg float GetHeight(); afx_msg void SetHeight(float newVal); afx_msg float GetWidth(); afx_msg void SetWidth(float newVal); //}}AFX_DISPATCH DECLARE_DISPATCH_MAP() // Event maps //{{AFX_EVENT(CTeaPot) //}}AFX_EVENT DECLARE_EVENT_MAP() // Properties public: float m_fHeight; float m_fWidth; }; ``` 7. 在“CTeaPot.cpp”文件中添加以下代码: ```cpp // TeaPot.cpp : Implementation of CTeaPotApp and DLL registration. #include "stdafx.h" #include "TeaPot.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif ///////////////////////////////////////////////////////////////////////////// // CTeaPotApp BEGIN_MESSAGE_MAP(CTeaPotApp, CWinApp) //{{AFX_MSG_MAP(CTeaPotApp) //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CTeaPotApp construction CTeaPotApp::CTeaPotApp() { // TODO: add construction code here, // Place all significant initialization in InitInstance } ///////////////////////////////////////////////////////////////////////////// // The one and only CTeaPotApp object CTeaPotApp theApp; ///////////////////////////////////////////////////////////////////////////// // CTeaPotApp initialization BOOL CTeaPotApp::InitInstance() { AfxEnableControlContainer(); // Standard initialization // If you are not using these features and wish to reduce the size // of your final executable, you should remove from the following // the specific initialization routines you do not need. #ifdef _AFXDLL Enable3dControls(); // Call this when using MFC in a shared DLL #else Enable3dControlsStatic(); // Call this when linking to MFC statically #endif return TRUE; } ``` 8. 在“CTeaPot.cpp”文件中,添加以下代码来实现绘制茶壶的功能: ```cpp // CTeaPot::OnDraw - Drawing function void CTeaPot::OnDraw(CDC* pdc, const CRect& rcBounds, const CRect& rcInvalid) { // TODO: Replace the following code with your own drawing code. CPen pen(PS_SOLID, 1, RGB(255, 0, 0)); CPen* pOldPen = pdc->SelectObject(&pen); pdc->MoveTo(rcBounds.left, rcBounds.top); pdc->LineTo(rcBounds.right, rcBounds.bottom); pdc->MoveTo(rcBounds.left, rcBounds.bottom); pdc->LineTo(rcBounds.right, rcBounds.top); pdc->SelectObject(pOldPen); } // CTeaPot::PreCreateWindow - Modify parameters for CreateWindowEx BOOL CTeaPot::PreCreateWindow(CREATESTRUCT& cs) { //cs.lpszClass = _T("STATIC"); cs.style |= WS_CLIPCHILDREN|WS_CLIPSIBLINGS; return COleControl::PreCreateWindow(cs); } ``` 9. 在“TeaPot.idl”文件中,添加以下代码: ```cpp import "oaidl.idl"; [ uuid(69B182FE-3142-4B7C-8AF7-99FB9E77E705), helpstring("TeaPot 1.0 Control"), control, threading(apartment), vi_progid("TeaPot.TeaPotCtrl.1"), progid("TeaPot.TeaPotCtrl"), version(1.0), helpfile("TeaPot.hlp"), event_source("com") ] interface ITeaPot : IDispatch { [id(1), helpstring("property Height")] float Height; [id(2), helpstring("property Width")] float Width; }; ``` 10. 在“TeaPot.rgs”文件中,添加以下代码: ```cpp HKCR { TeaPot.TeaPotCtrl.1 = s 'TeaPot ActiveX Control' { CLSID = s '{02D5B4F8-7177-4E7B-8B55-5E6D4C02E8D8}' Insertable = s '1' ProgID = s 'TeaPot.TeaPotCtrl.1' VersionIndependentProgID = s 'TeaPot.TeaPotCtrl' DefaultIcon = s '%MODULE%,0' } } HKCR\CLSID { {02D5B4F8-7177-4E7B-8B55-5E6D4C02E8D8} = s 'TeaPot ActiveX Control' { ProgID = s 'TeaPot.TeaPotCtrl.1' VersionIndependentProgID = s 'TeaPot.TeaPotCtrl' Description = s 'TeaPot ActiveX Control' Control = s '' } {F033EFE8-07B1-11D2-A4F8-0000F8756F7A} = s 'TeaPot ActiveX Control' { ProgID = s 'TeaPot.TeaPotCtrl.1' VersionIndependentProgID = s 'TeaPot.TeaPotCtrl' Description = s 'TeaPot ActiveX Control' OleObject = s 'TeaPot.TeaPotCtrl.1' } } HKLM { Software\Classes\TeaPot.TeaPotCtrl.1 = s 'TeaPot ActiveX Control' { CLSID = s '{02D5B4F8-7177-4E7B-8B55-5E6D4C02E8D8}' Insertable = s '1' ProgID = s 'TeaPot.TeaPotCtrl.1' VersionIndependentProgID = s 'TeaPot.TeaPotCtrl' DefaultIcon = s '%MODULE%,0' } } HKLM\Software\Classes\CLSID { {02D5B4F8-7177-4E7B-8B55-5E6D4C02E8D8} = s 'TeaPot ActiveX Control' { ProgID = s 'TeaPot.TeaPotCtrl.1' VersionIndependentProgID = s 'TeaPot.TeaPotCtrl' Description = s 'TeaPot ActiveX Control' Control = s '' } } ``` 11. 编译并运行项目,在窗体设计器中将控件拖放到窗体上,然后在属性窗口中设置控件的高度和宽度属性,即可在窗体上看到绘制的茶壶。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值