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);
}

  

  

  

### 创建、使用和调试Tcl DLLVisual Studio中的方法 #### 设置项目环境 为了成功创建、使用或调试Tcl相关的DLL,在Visual Studio环境中设置CMake项目是必要的。这涉及到配置项目的构建系统以便支持所需的库文件和头文件路径[^1]。 #### 编写Tcl扩展代码 当开发一个新的Tcl扩展作为动态链接库(DLL),开发者应当遵循特定的编码标准来确保兼容性和稳定性。通常情况下,这样的DLL会导出一组函数供解释器调用。下面是一个简单的例子展示如何定义一个可以被Tcl加载并使用的模块: ```c #include "tcl.h" int DLLEXPORT MyCmd(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) { // 实现命令逻辑... } extern "C" __declspec(dllexport) int DLLEXPORT Tcl_PkgInit(Tcl_Interp* interp){ if (Tcl_InitStubs(interp, TCL_VERSION, 0) == NULL) { return TCL_ERROR; } Tcl_CreateObjCommand(interp, "mycmd", MyCmd, nullptr, nullptr); Tcl_PkgProvide(interp, "MyPackage", "1.0"); return TCL_OK; } ``` 这段代码展示了怎样编写一个基本的Tcl命令`mycmd`以及初始化过程,其中包含了重要的宏定义用于Windows平台下的DLL导出声明[^2]。 #### 构建MSI安装包 对于希望分发自己编写的Tcl扩展的情况,可以通过构建MSI安装程序来进行打包发布。此操作需要用到位于Tools/msi目录下的build.bat脚本,并指定目标架构参数如-x86以适应不同硬件需求。 #### 调试技巧 针对可能出现的问题,比如找不到依赖项或其他运行时错误,建议采用以下几种方式解决问题: - 使用Dependency Walker工具检查是否存在缺失的导入; - 启动应用程序之前通过环境变量`PATH`添加额外的搜索路径; - 利用Visual Studio内置的调试功能附加到正在执行的过程上查看实时状态;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值