请问如何读取EXE文件的版本信息呢???

lenovoboy 2008-02-27 10:16:55
调用了下面这段代码,但没有任何返回值啊~~~~~~


Function TFrmMain.GetExeComments( const FileName, Value : String ): String;
var
dwHandle, dwVersionSize : DWORD;
strLangCharSetInfoString : String;
pcBuffer : PChar;
pTemp : Pointer;
begin
strLangCharSetInfoString := '\StringFileInfo\040904E4\' + Value; // get version information values

dwVersionSize := GetFileVersionInfoSize( PChar( FileName ), // pointer to filename string
dwHandle ); // pointer to variable to receive zero

// if GetFileVersionInfoSize is successful
if dwVersionSize <> 0 then
begin
GetMem( pcBuffer, dwVersionSize );
try
if GetFileVersionInfo( PChar( FileName ), // pointer to filename string
dwHandle, // ignored
dwVersionSize, // size of buffer
pcBuffer ) then // pointer to buffer to receive file-version info.

if VerQueryValue( pcBuffer, // pBlock - address of buffer for version resource
PChar( strLangCharSetInfoString ), // lpSubBlock - address of value to retrieve
pTemp, // lplpBuffer - address of buffer for version pointer
dwVersionSize ) then // puLen - address of version-value length buffer

Result := PChar( pTemp );
finally
FreeMem( pcBuffer );
end; // try
end;// if dwVersionSize
end; // GetFileInformation
...全文
853 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
lenovoboy 2008-02-28
  • 打赏
  • 举报
回复
VerQueryValue(VerBuf,'\VarFileInfo\Translation',Value,Len);
请问这个语句的功能是什么呢?
lenovoboy 2008-02-28
  • 打赏
  • 举报
回复
万分感谢楼上二位的赐教!!!!!!
刚从火星来,能告诉我啥叫“结分”么?
lqwxfdwj 2008-02-27
  • 打赏
  • 举报
回复
用Delphi实现动态获取版本信息

  1.1. GetFileVersionInfo函数

  GetFileVersionInfo函数被用来获取包含在指定文件中的版本信息。其Delphi函数声明如下:
function GetFileVersionInfo(
lptstrFilename: PChar; // 文件名
dwHandle: DWORD; // 忽略
dwLen: DWORD; // 缓冲区大小
lpData: Pointer // 版本信息缓冲区
): BOOL; stdcall;
  参数说明:
  lptstrFilename,一个以NULL结束字符串,它指定了期望从中获取版本详细的文件名。如果文件名不包含完整路径,函数将使用LoadLibrary函数的默认搜索次序进行搜索。在Windows 95/98/Me操作系统中路径名不能超过126个字符。

  dwHandle,这个参数没有使用,将被忽略。

  dwLen,请先调用GetFileVersionInfoSize函数确定文件版本信息的字节数大小。dwLen必须等于或大于这个值。如果lpDate指向的缓冲区空间不够,函数将根据实际大小裁减出文件的版本信息。

  lpData,指向一个用于保存函数调用后返回的文件版本信息的缓冲区。

  如果函数调用成功,它将返回True;否则返回False。可通过GetLastError函数得到扩展的错误信息。

  在调用GetFileVersionInfo函数前必须先调用GetFileVersionFileSize。为了从文件版本信息中获取有用信息,必须使用VerQueryValue函数。

  1.2. GetFileVersionInfoSize函数

  GetFileVersionInfoSize函数被用来判断操作系统是否能够从指定文件中获取版本信息。如果存在版本信息,便返回以字节为单位的这些信息所占用空间的大小。其Delphi函数声明如下:
function GetFileVersionInfoSize(
lptstrFilename: PChar; // 文件名
var lpdwHandle: DWORD // set to zero
): DWORD; stdcall;
  参数说明:

  lptstrFilename,一个以NULL结束字符串,它指明期望从哪个文件中获取版本信息的文件名。

  lpdwHandle,一个指向将被函数设置为0的变量的指针。

  如果函数调用成功,它将返回文件版本信息的字节大小;否则返回0,可通过GetLastError函数得到扩展的错误信息。

  在调用GetFileVersionInfo函数前应先调用GetFileVersionInfoSize函数。GetFileVersionInfoSize函数的返回值确定了GetFileVersionInfo函数所使用的版本信息缓冲区的大小。

  1.3. VerLanguageName函数

  VerLanguagename函数被用来获取与指定的二进制微软语言标示相关联的语言描述字符串。其Delphi函数声明如下:function VerLanguageName(
wLang: DWORD; // 微软语言标识符
szLang: PChar; // 语言描述缓冲区
nSize: DWORD // 缓冲区大小
): DWORD; stdcall;


  参数说明:

  wLang,语言标识符,是一个二进制数字。指定二进制语言标识符。如果向得到完整的语言标识符列表,请参见语言标识符部分的内容。举个例子,与语言标识符0x040A相关联的描述字符串就是“卡斯蒂利亚西班牙语”。如果是一个未知的标识符,那么szLang参数就会指向一个缺省字符串--“Language Neutral”。

  szLang,这个参数指向一个缓冲区。这个缓冲区用于存储由wLang参数所确定的、用来描述语言的、以NULL结尾的字符串。

  nSize 指定缓冲区的大小,单位是字符数量。


  1.4. VerQueryValue函数

  VerQueryValue函数被用来从指定的版本信息资源中获取指定版本信息。最常用的获取版本信息的逻辑流程是:先调用GetFileVersionInfoSize函数,紧接着再调用GetFileVersionInfo函数,最后再调用VerQueryValue函数。其Delphi函数声明如下:
function VerQueryValue(
pBlock: Pointer; // 存放版本资源的缓冲区
lpSubBlock: PChar; // 期望获取的值
var lplpBuffer: Pointer; // 指向存放版本值缓冲区的指针
var puLen: UINT // 版本信息长度
): BOOL; stdcall;
  参数说明:

  pBlock,一个指向用于存储版本信息资源的缓冲区的指针,这个版本信息资源是从GetFileVersionInfo函数返回的。

  lpSubBlock,指向一个零结尾的字符串,指定到底获得哪个版本信息值。这个字符串必须由被反斜线符号(\)分开的名字组成如下格式之一:

  →“\”,指定根区域。函数将返回一个指向VS_FIXEDFIELDFILEINFO结构的版本信息资源。

  →“\VarFileInfo\Translation”,指定一个保存在可变类型变量信息的结构中的转换阵列。函数返回一个指向语言和代码页标识符数组的指针。应用程序可以使用这些标识符来访问存储在版本信息资源中的特定语言字符串表结构。

  →“\StringFileInfo\lang-codepage\string-name”,指定存储在特定语言字符串表中结构的值。其中,lang-codepage的书写格式是:用双字(DWORD)表示的、保存在资源中的转换阵列的语言与代码页标识符对,并且需要书写成十六进制形式的字符串;string-name必须是在后面注释中预定义的字符串之一。函数根据指定的语言与代码页,返回一个与之相关的字符串。

  lplpBuffer,一个指向用于保存指向被请求的版本信息缓冲区的变量的指针。简单的说,就是一个指向指针的指针。

  puLen,指向一个保存版本信息长度的缓冲区。

  如果指定的版本信息结构存在并且有效,函数将返回一个非0值。如果长度缓冲区的地址等于0,指定的版本信息名称将无效。

  并且,在指定的名称不存在或指定的资源无效时,函数的返回值将等于0。

  以下列表是预定义的版本信息统一字符编码标准字符串:

Comments、InternalName、ProductName、CompanyName、LegalCopyright、ProductVersion、FileDescription、LegalTrademarks、PrivateBuild、FileVersion、OriginalFilename、SpecialBuild

  二、一个关于版本信息函数使用的实例

  下面开始,我们给出一个实例。通过这个实例,大家可以学习到在我们自己编写的应用程序中怎么使用这些函数来达到获取文件版本信息的目的。

  2.2. 填写应用程序的运行文件版本信息

  在Delphi的集成编辑器中按下Shift+Ctrl+F11键,在弹出的对话框中按照下表的内容,在相应键值的未知输入内容:
键值 内容
CompanyName 小珍工作室
FileDescription 演示“关于对话框”编程的应用程序
FileVersion 1.0.0.11
InternalName AboutBox Application
LegalCopyright 版权所有(C)1989-2003,小珍工作室
LegalTrademarks 关于对话框应用程序
OriginalFilename AboutBoxApp.exe
ProductName 关于对话框应用程序
ProductVersion 1.0.0
  2.3. 实现获取版本信息功能的代码

  下面的代码是这个关于对话框创建时的事件响应代码片断。大家把它们拷贝+粘贴到窗体的OnCreate事件中就可以了。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;

// OperatingSystem.Caption := GetOSVerInfo;
和 // SystemMemory.Caption := GetMemStat;

  
jiaxianglei 2008-02-27
  • 打赏
  • 举报
回复
这个我试过了,肯定能用,结分。
jiaxianglei 2008-02-27
  • 打赏
  • 举报
回复
delphi中获得文件版本号
function GetVersion(FileName:string):string; //获得文件版本号
var
InfoSize, Wnd: DWORD;
VerBuf: Pointer;
szName: array[0..255] of Char;
Value: Pointer;
Len: UINT;
TransString:string;
begin
Result := '';
InfoSize := GetFileVersionInfoSize(PChar(FileName),Wnd);
if InfoSize<>0 then
begin
GetMem(VerBuf,InfoSize);
try
if GetFileVersionInfo(PChar(FileName),Wnd,InfoSize,VerBuf) then
begin
Value:=nil;
VerQueryValue(VerBuf,'\VarFileInfo\Translation',Value,Len);
if Value<>nil then
TransString:=IntToHex(MakeLong(HiWord(Longint(Value^)),LoWord(Longint(Value^))),8); Result:='';
// StrPCopy(szName,'\StringFileInfo\'+Transstring+'\ProductVersion');
StrPCopy(szName,'\StringFileInfo\'+Transstring+'\FileVersion');
if VerQueryValue(VerBuf,szName,Value,Len) then
Result:=StrPas(PChar(Value));
end;
finally
FreeMem(VerBuf);
end;
end;
end;

1,183

社区成员

发帖
与我相关
我的任务
社区描述
Delphi Windows SDK/API
社区管理员
  • Windows SDK/API社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧