VerQueryValue()不适用于单个字符值?

时间:2013-06-27 10:31:43

标签: delphi winapi delphi-xe3

我使用VerQueryValue()获取“PrivateBuild”键的值,这样可以正常工作。

除非值只有一个字符:例如'b'对于beta版本来说并不罕见。在这种情况下,函数返回False

我还测试了第三方Delphi程序,可以读取文件版本(以确保我的文件读取逻辑不是问题):

http://www.delphidabbler.com/articles?article=20

这有同样的问题。

任何人都可以验证这是Windows函数VerQueryValue()的问题吗? 它也可能是Delphi XE3 IDE的问题 - 可能它有一个错误,并且不会将单个字符写入dll文件版本信息。

1 个答案:

答案 0 :(得分:0)

我可以确认这是XE3& 4.它似乎是W(Unicode)版本和A(ANSI)版本之间的问题,因为我用于测试XE3和版本的Delphi 2007中的代码相同。 4正确读取单个字符PrivateBuild值。正如@DavidHeffernan在评论中提到的,这可能是资源编译器的一个问题,尽管我不确定32位资源编译器是否在D2007和XE之间发生了变化。 (使用具有需要Unicode的语言ID的资源,然后Unicode值在D2007中工作,以便资源编译器版本支持Unicode以及Ansi。)

从我坐在一个旧单元中快速抓取的测试代码添加到新的VCL表单应用程序的implementation部分,其中包含TMemoTButton,以及使用普通的Delphi对话框快速设置测试版本信息:

type
  TVersionInfo=record
    // Name of company
    CompanyName: string;
    // Description of file
    FileDescription: string;
    // File version
    FileVersion: string;
    // Internal name
    InternalName: string;
    // Legal copyright information
    LegalCopyright: string;
    // Legal trademark information
    LegalTradeMarks: string;
    // Original filename
    OriginalFilename: string;
    // Product name
    ProductName : string;
    // Product version
    ProductVersion: string;
    // Private build
    PrivateBuild: string;
    // Comments
    Comments: string;
  end;

const
  ItemList: array [0..10] of string = ( 'CompanyName',
                                       'FileDescription',
                                       'FileVersion',
                                       'InternalName',
                                       'LegalCopyright',
                                       'LegalTradeMarks',
                                       'OriginalFilename',
                                       'ProductName',
                                       'ProductVersion',
                                       'PrivateBuild',
                                       'Comments' );

function GetVerInfo(const FileName: string; var VersionInfo: TVersionInfo): Boolean;
var
  i: Integer;
  dwLen: Word;
  lpdwHandle: Cardinal;
  pValue: PChar;
  lpData: Pointer;
  uiLen: UInt;
  LCID: string;
begin
  dwLen := GetFileVersionInfoSize(PChar(FileName), lpdwHandle);
  Result := (dwLen > 0);
  if not Result then
    Exit;
  GetMem(lpData, (dwLen + 1) * SizeOf(Char));
  try
    LCID := 'StringFileInfo\' + IntToHex(GetUserDefaultLCID, 4) + IntToHex(GetACP, 4) + '\';

    GetFileVersionInfo(PChar(FileName), 0, dwLen, lpData);
    for i := Low(ItemList) to High(ItemList) do
    begin
      if (VerQueryValue(lpData, PChar(LCID + ItemList[i]), Pointer(pValue), uiLen)) then
        case i of
          0: VersionInfo.CompanyName := pValue;
          1: VersionInfo.FileDescription := pValue;
          2: VersionInfo.FileVersion := pValue;
          3: VersionInfo.InternalName := pValue;
          4: VersionInfo.LegalCopyright := pValue;
          5: VersionInfo.LegalTradeMarks := pValue;
          6: VersionInfo.OriginalFilename := pValue;
          7: VersionInfo.ProductName := pValue;
          8: VersionInfo.ProductVersion := pValue;
          9: VersionInfo.PrivateBuild := pValue;
         10: VersionInfo.Comments := pValue;
        end;

    end;
  finally
    FreeMem(lpData);
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  VI: TVersionInfo;
begin
  Memo1.Clear;
  GetVerInfo(ParamStr(0), VI);
  Memo1.Lines.Add('Company name: ' + VI.CompanyName);
  Memo1.Lines.Add('File version: ' + VI.FileVersion);
  Memo1.Lines.Add('Private build: ' + VI.PrivateBuild);

end;
相关问题