题 我如何阅读文件的详细信息?


如何阅读文件版本,产品版本等exe文件的详细信息以及该文件的“属性”窗口中“详细信息”选项卡中存储的其他内容? 谢谢。


12
2018-04-04 13:38


起源




答案:


这已在关于:

基本上,你只需使用 GetFileVersionInfo 函数获取数据然后 VerQueryValue 阅读它的功能。

因为这些API函数有点“难”使用,所以我写了一个简单的例子:

type
  TEXEVersionData = record
    CompanyName,
    FileDescription,
    FileVersion,
    InternalName,
    LegalCopyright,
    LegalTrademarks,
    OriginalFileName,
    ProductName,
    ProductVersion,
    Comments,
    PrivateBuild,
    SpecialBuild: string;
  end;

function GetEXEVersionData(const FileName: string): TEXEVersionData;
type
  PLandCodepage = ^TLandCodepage;
  TLandCodepage = record
    wLanguage,
    wCodePage: word;
  end;
var
  dummy,
  len: cardinal;
  buf, pntr: pointer;
  lang: string;
begin
  len := GetFileVersionInfoSize(PChar(FileName), dummy);
  if len = 0 then
    RaiseLastOSError;
  GetMem(buf, len);
  try
    if not GetFileVersionInfo(PChar(FileName), 0, len, buf) then
      RaiseLastOSError;

    if not VerQueryValue(buf, '\VarFileInfo\Translation\', pntr, len) then
      RaiseLastOSError;

    lang := Format('%.4x%.4x', [PLandCodepage(pntr)^.wLanguage, PLandCodepage(pntr)^.wCodePage]);

    if VerQueryValue(buf, PChar('\StringFileInfo\' + lang + '\CompanyName'), pntr, len){ and (@len <> nil)} then
      result.CompanyName := PChar(pntr);
    if VerQueryValue(buf, PChar('\StringFileInfo\' + lang + '\FileDescription'), pntr, len){ and (@len <> nil)} then
      result.FileDescription := PChar(pntr);
    if VerQueryValue(buf, PChar('\StringFileInfo\' + lang + '\FileVersion'), pntr, len){ and (@len <> nil)} then
      result.FileVersion := PChar(pntr);
    if VerQueryValue(buf, PChar('\StringFileInfo\' + lang + '\InternalName'), pntr, len){ and (@len <> nil)} then
      result.InternalName := PChar(pntr);
    if VerQueryValue(buf, PChar('\StringFileInfo\' + lang + '\LegalCopyright'), pntr, len){ and (@len <> nil)} then
      result.LegalCopyright := PChar(pntr);
    if VerQueryValue(buf, PChar('\StringFileInfo\' + lang + '\LegalTrademarks'), pntr, len){ and (@len <> nil)} then
      result.LegalTrademarks := PChar(pntr);
    if VerQueryValue(buf, PChar('\StringFileInfo\' + lang + '\OriginalFileName'), pntr, len){ and (@len <> nil)} then
      result.OriginalFileName := PChar(pntr);
    if VerQueryValue(buf, PChar('\StringFileInfo\' + lang + '\ProductName'), pntr, len){ and (@len <> nil)} then
      result.ProductName := PChar(pntr);
    if VerQueryValue(buf, PChar('\StringFileInfo\' + lang + '\ProductVersion'), pntr, len){ and (@len <> nil)} then
      result.ProductVersion := PChar(pntr);
    if VerQueryValue(buf, PChar('\StringFileInfo\' + lang + '\Comments'), pntr, len){ and (@len <> nil)} then
      result.Comments := PChar(pntr);
    if VerQueryValue(buf, PChar('\StringFileInfo\' + lang + '\PrivateBuild'), pntr, len){ and (@len <> nil)} then
      result.PrivateBuild := PChar(pntr);
    if VerQueryValue(buf, PChar('\StringFileInfo\' + lang + '\SpecialBuild'), pntr, len){ and (@len <> nil)} then
      result.SpecialBuild := PChar(pntr);
  finally
    FreeMem(buf);
  end;
end;

尝试一下。但要注意 - 目前,这个 只要 适用于en-us EXE!例如,它对我瑞典机器上的大多数EXE都不起作用。现在已经很晚了;明天我会扩展它以使用任何EXE语言,如果我还剩下一些时间。 [About.com代码有同样的问题,但他们甚至不假装这是一个问题!]

更新: 该代码现在可以使用任何EXE语言。

Sample usage on Explorer.exe (Swedish)
(瑞典)


28
2018-04-04 13:46



很有用。我的第一个搜索源是关于,但我找不到它,我想知道为什么!!!真的很感谢你 - Armin
我在编译时遇到这个错误:“实际和正式var参数的类型必须相同”问题是什么?我没有对描述的功能做任何改变! - Armin
@Armin:如果你告诉我们错误发生在哪一行会有所帮助。 - Andreas Rejbrand
当然!行:“n:= GetFileVersionInfoSize(PChar(S),n);” | “VersionInformation Function”中的第6行。它在这一行有同样的问题:“... InfoStr [j]),指针(值),Len)然后......”| “版本信息功能”的第14行。此错误“不兼容的类型:'字符串'和'数组'”在此代码“...(StringPad(labelStr,'',20,True)+'='+ Value);” | “版本信息功能”第20行。我正在使用问号标签中显示的Delphi-7。 - Armin
@Armin:跳过about.com代码!我自己写了一个简单的例子。 - Andreas Rejbrand