首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用TFileStream从文件中读取VersionInfo

使用TFileStream从文件中读取VersionInfo
EN

Stack Overflow用户
提问于 2013-05-08 01:15:28
回答 2查看 340关注 0票数 1

我需要使用TSream从文件(exe或dll)中读取VersionInfo。

我不能使用windows API GetFileVersionInfo,因为我的文件在内存中(TMemoryStream),而且我不想为了获取这些信息而将文件写到磁盘上,我有一些性能限制。

有人能帮我吗?

EN

回答 2

Stack Overflow用户

发布于 2013-05-08 02:53:58

如果原始文件数据在内存中,则Win32应用编程接口无法帮助您定位文件的版本资源。您必须手动读取和解释文件的PE标头,以定位文件的资源表,然后遍历该表以查找所需的版本资源。一旦找到它,您就可以使用Win32 API VerQueryValue()函数来访问资源内部的一些(但不是全部)值。我之所以这么说,是因为VerQueryValue()内部依赖于GetFileVersionInfo()在运行时建立的查找。但是,例如,在不先调用GetFileVersionInfo()的情况下,访问VS_FIXEDFILEINFO结构就可以正常工作。

票数 3
EN

Stack Overflow用户

发布于 2020-04-29 08:24:29

可以使用下面的技术对其进行归档。

使用已经加载到.EXE内存空间中的模块的HInstance值,通过TResourceStream获取RT_VERSION资源。

例如,要获取MainModule hInstace和相应的版本:

代码语言:javascript
复制
var module: HMODULE;
    version: String;
...
module := GetModuleHandle(nil);
version := FileVersion(base);

如果您不能像我下面那样从内存中加载资源,您可以使用PE HEADERS解析.EXE并使用TMemoryStream查找RT_VERSION资源。

代码语言:javascript
复制
unit Version;

interface

implementation

uses
  Winapi.Windows, System.SysUtils, System.Classes, Math;

function FileVersion(Module: HINST = 0): String;
var
  verblock:PVSFIXEDFILEINFO;
  versionMS,versionLS:cardinal;
  verlen:cardinal;
  rs:TResourceStream;
  m:TMemoryStream;
  p:pointer;
  s:cardinal;
begin
  m:=TMemoryStream.Create;
  try
    if Module = 0 then
      Module := HInstance;

    rs:=TResourceStream.CreateFromID(Module,1,RT_VERSION);
    try
      m.CopyFrom(rs,rs.Size);
    finally
      rs.Free;
    end;
    m.Position:=0;
    if VerQueryValue(m.Memory,'\',pointer(verblock),verlen) then
      begin
        VersionMS:=verblock.dwFileVersionMS;
        VersionLS:=verblock.dwFileVersionLS;
        Result:=
          IntToStr(versionMS shr 16)+'.'+
          IntToStr(versionMS and $FFFF)+'.'+
          IntToStr(VersionLS shr 16)+'.'+
          IntToStr(VersionLS and $FFFF);
      end;
    if VerQueryValue(m.Memory,PChar('\\StringFileInfo\\'+
      IntToHex(GetThreadLocale,4)+IntToHex(GetACP,4)+'\\FileDescription'),p,s) or
        VerQueryValue(m.Memory,'\\StringFileInfo\\040904E4\\FileDescription',p,s) then //en-us
          Result:=PChar(p)+' '+Result;
  finally
    m.Free;
  end;
end;

end.
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/16424872

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档