VerQueryValue在中文操作系统中没有返回版权符号?

时间:2013-09-12 12:31:32

标签: delphi character-encoding delphi-7

我正在尝试使用简体中文操作系统中的VerQueryValue显示EXE信息。所有文本都正确显示,但版权符号显示为“?” 。这是我正在使用的代码。

   const
     CInfoStr : array[1..13] of string =
('FileVersion',
 'CompanyName',
 'FileDescription',
 'InternalName',
 'LegalCopyright',
 'LegalTradeMarks',
 'OriginalFileName',
 'ProductName',
 'ProductVersion',
 'Comments',
 'CurrentProgramVersion',
 'CurrentDatabaseVersion',
 'VersionDetails');

type

  PTransBuffer = ^TTransBuffer;
  TTransBuffer = array[1..13] of smallint;


Function CheckFileVerForAppReplaceAlert(Path : String): Boolean;
var
  InfoSize,
  VerSize, Wnd : DWORD;
  Value        : PChar;
  ValWide      : PWideCHar;
  NewValWide   : WideString;
  VerBuf       : pointer;
  pTrans       : PTransBuffer;
  TypeStr,
  TransStr     : string;
  j            : Integer;

  KeyPath      : String;
  NewFileVer   : String;
  OldFileVer   : String;

  ResVer : Integer;
begin
  Result := False;
  If Path = '' then
    exit;
 try
   // Get Version of File
    InfoSize := GetFileVersioninfoSize(PChar(Path), Wnd);
   if (InfoSize <> 0) then
   begin
     try
       GetMem(VerBuf, InfoSize);
       if GetFileVersionInfo(PChar(Path), Wnd, InfoSize, VerBuf) then
       begin
         if VerQueryValue(VerBuf, PChar('\VarFileInfo\Translation'),Pointer(pTrans), VerSize) then
        begin
        TransStr := IntToHex(pTrans^[1], 4) + IntToHex(pTrans^[2], 4);
        TypeStr := 'StringFileInfo\' + TransStr + '\' + CInfoStr[5];   //Get The Copyright
        //if VerQueryvalue(VerBuf, PChar(TypeStr),Pointer(Value), VerSize) then
        if VerQueryvalue(VerBuf, PChar(TypeStr),Pointer(Value), VerSize) then
        begin
          NewFileVer := Value;
          //NewValWide :=Value;
          Updatelog('NewFileVer ' + NewValWide);
         // ShowMessage('Copyright ' + NewFileVer);
          //MessageBoxW(Application.Handle, PWideCHar(NewFileVer) , PWideChar('Err'),MB_OKCANCEL);
        end;

      end;
    end
  finally
    Try
      FreeMem(VerBuf, InfoSize);
    Except
    End;
  end;
end  //end Of taking version
 except
 end;
end;

这是为宽字符串编写的代码:

 Function AddWidePathToAppList_Reg(AppPath : WideString): Boolean ;
 Var
   j : Integer;
   PathWS : WideString;
   InfoSize,VerSize, Wnd: DWORD;
   pTrans: PTransBuffer;
   VerBuf: pointer;
   VerFlag: Boolean;
   Value: PWChar;
   TypeStr,
   TransStr: WideString;
 Begin
   Result := False;
   PathWS := (AppPath);
      InfoSize := GetFileVersioninfoSizeW(PWChar(AppPath), Wnd);
      if (InfoSize <> 0) then
      begin
          GetMem(VerBuf, InfoSize);
          try
              if GetFileVersionInfoW(PWChar(AppPath), Wnd, InfoSize, VerBuf) then
              begin
                  if VerQueryValueW(VerBuf, '\VarFileInfo\Translation',Pointer(pTrans), VerSize) then
                  begin
                      VerFlag:=False;
                      TransStr := IntToHex(pTrans^[1], 4) + IntToHex(pTrans^[2], 4);
                      for j := Low(CInfoStr) to High(CInfoStr) do
                      begin
                          TypeStr := 'StringFileInfo\' + TransStr + '\' + CInfoStr[j];
                          if VerQueryvalueW(VerBuf, PWChar(TypeStr),Pointer(Value), VerSize) then
                          begin
                             UpdateLog('Vlaue ' + Value);
                             Result := True;
                          end;
                      end;
                  end;
              end;
          finally
              FreeMem(VerBuf, InfoSize);
          end;
      end;

 end;

我不明白我做错了什么。我尝试使用WideString代替String。但它没有任何区别。

指导将不胜感激。

提前致谢

1 个答案:

答案 0 :(得分:4)

返回?表示系统从UTF-16转换为ANSI,并且由于ANSI代码页中不存在该字符而失败。您正在使用ANSI版本的Delphi,因此这是预期的行为。

为了读出UTF-16,您将不得不调用API函数的Unicode变体。这些是以W为后缀的函数。因此,不要调用映射到VarQueryValue(8位ANSI变体)的VarQueryValueA,而是调用VarQueryValueW

您需要将指针传递给WideChar数组。最简单的方法是使用WideString,然后转换为PWideChar

一旦你在WideChar中拥有它,你不清楚这个符号会做什么。系统无法将其转换为您的ANSI代码页,这是不可能的,并且您没有更好的成功希望。因此,您需要使用Unicode控件来显示文本。

您声称已尝试过我上面描述的内容,但仍然会看到?字符。只有当您的调试机制也仅限于ANSI代码页时,才会发生这种情况。