扫一扫
分享文章到微信
扫一扫
关注官方公众号
至顶头条
作者:佚名 来源:论坛 2007年10月31日
关键字:
const InfoNum = 9; InfoStr: array[1..InfoNum] of string = ( 'ProductName', 'ProductVersion', 'FileDescription', 'LegalCopyright', 'FileVersion', 'CompanyName', 'LegalTradeMarks', 'InternalName', 'OriginalFileName' ); var S: string; BufSize, Len: DWORD; Buf: PChar; Value: PChar; begin S := Application.ExeName; BufSize := GetFileVersionInfoSize(PChar(S), BufSize); if BufSize > 0 then begin Buf := AllocMem(BufSize); GetFileVersionInfo(PChar(S), 0, BufSize, Buf); if VerQueryValue(Buf, PChar('StringFileInfo\080403A8\' + InfoStr[1]), Pointer(Value), Len) then ProductName.Caption := Value; if VerQueryValue(Buf, PChar('StringFileInfo\080403A8\' + InfoStr[2]), Pointer(Value), Len) then ProductVersion.Caption := '产品版本: ' + Value; if VerQueryValue(Buf, PChar('StringFileInfo\080403A8\' + InfoStr[3]), Pointer(Value), Len) then FileDescription.Caption := '文件说明: ' + Value; if VerQueryValue(Buf, PChar('StringFileInfo\080403A8\' + InfoStr[4]), Pointer(Value), Len) then LegalCopyright.Caption := '合法版权: ' + Value; if VerQueryValue(Buf, PChar('StringFileInfo\080403A8\' + InfoStr[5]), Pointer(Value), Len) then FileVersion.Caption := '文件版本: ' + Value; if VerQueryValue(Buf, PChar('StringFileInfo\080403A8\' + InfoStr[6]), Pointer(Value), Len) then CompanyName.Caption := '公司名称: ' + Value; if VerQueryValue(Buf, PChar('StringFileInfo\080403A8\' + InfoStr[7]), Pointer(Value), Len) then LegalTrademarks.Caption := '合法商标: ' + Value; if VerQueryValue(Buf, PChar('StringFileInfo\080403A8\' + InfoStr[8]), Pointer(Value), Len) then InternalName.Caption := '内部名称: ' + Value; if VerQueryValue(Buf, PChar('StringFileInfo\080403A8\' + InfoStr[9]), Pointer(Value), Len) then OriginalFilename.Caption := '原文件名: ' + Value; FreeMem(Buf, BufSize); // OperatingSystem.Caption := GetOSVerInfo; // SystemMemory.Caption := GetMemStat; end else begin Application.MessageBox('获取产品信息时遇到致命错误,请尝试重新启动软件。'+ #13 + '若仍未能解决问题,请联系产品服务人员。','错误',MB_OK + MB_ICONSTOP); Application.Terminate; end; |
在这段代码中,首先通过调用GetFileVersionInfoSize()函数获得在内存中存储版本信息资源所需要的最小内存空间大小。如果函数的返回值小于等于0,则函数调用失败,继而程序转入错误处理部分。在这部分的错误处理代码中,程序会提示用户程序运行实现错误,并要求用户重新启动软件。
如果函数调用成功,程序将通过AllocMem()函数向操作系统申请一块内容空间,用于保存从文件中获得的版本信息资源。
此后,利用GetFileVersionInfo()函数从文件中得到版本信息。但这些信息对我们来说是不可读的,因为它们都是一些二进制的编码。在随后的程序中,通过一连串对VerQueryValue()函数的调用,我们得到了文件的版本信息,并把它们显示在这个关于对话框窗体中正确的位置上。
在使用完这些信息后,我们一定要记住用FreeMem()函数释放前面用AllocMem()函数分配的内存,否则就会出现内存泄漏。
// OperatingSystem.Caption := GetOSVerInfo; |
和
// SystemMemory.Caption := GetMemStat; |
这两行代码调用的两个函数是我自己编制的,分别用于获取操作系统版本信息和内存信息。前面已经说过,由于篇幅的关系,我们在这里暂时跳过这两行代码,不去管它。反正程序已经可以正常的运行了。
三、总结
通过本文中对文件版本信息处理方法的简单介绍,相信读者已经对这种技术有了一个初步的认识。这种实用且非常重要的技术是不是很简单呢?答案当然是肯定的!正如上面所讲述的内容,其实就是对那六个函数的交替调用。在这里唯一要提醒读者的是,在使用这些函数的时候,一定要注意调用次序,不能搞错,否则很有可能怎么也不能正常访问这些函数(函数返回值始终是调用失败)。
在第二节中的哪个实例的源代码,我们在Windows 2000简体中文专业版和Delphi 6.0企业版的编程环境下调试通过,所有代码均能正常运行。
如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。
现场直击|2021世界人工智能大会
直击5G创新地带,就在2021MWC上海
5G已至 转型当时——服务提供商如何把握转型的绝佳时机
寻找自己的Flag
华为开发者大会2020(Cloud)- 科技行者