我正在尝试使用简体中文操作系统中的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。但它没有任何区别。
指导将不胜感激。
提前致谢
答案 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代码页时,才会发生这种情况。