Вы отредактировали свой вопрос с полным образцом компиляции. Хорошо!
Вероятно, проще всего было бы использовать для этого JCL (ссылка ниже).
Тогда вы можете использовать TJclFileVersionInfo, который делает все, что вы хотите, и учитывает некоторые эзотерические вещи, которые может содержать VersionInfo.
Тогда ваша бизнес-логика станет примерно такой:
function GetStringFileInfo(
const Buffer: Pointer; const SubBlock: PChar;
const LangCharSetString: string; const Kind: string): string;
var
QueryString: string;
Data: Pointer;
DataCharacters: PChar absolute Data;
DataLen: LongWord;
begin
Result := '';
QueryString := Format('%s\StringFileInfo\%s\%s', [SubBlock, LangCharSetString, Kind]);
if VerQueryValue(Buffer, PChar(QueryString), Data, DataLen) then
Result := StrPas(DataCharacters);
end;
procedure GetVersionInfoStrings(var Comments: string; var ProductName: string;
var Caption: string; var Version: string; var Copyright: string);
type
PLangCharSetInfo = ^TLangCharSetInfo;
TLangCharSetInfo = record
Lang: Word;
CharSet: Word;
end;
var
FileName: array [0 .. 260] of Char;
SubBlock: array [0 .. 255] of Char;
VerHandle: Cardinal;
Size: Word;
Buffer: Pointer;
Data: Pointer;
DataCharacters: PChar absolute Data;
DataLen: LongWord;
LangCharSetInfo: PLangCharSetInfo;
LangCharSetString: string;
begin
Comments := 'No version information for this program is available!';
{ Get size and allocate buffer for VerInfo }
if GetModuleFileName(hInstance, FileName, SizeOf(FileName)) > 0 then
begin
Size := GetFileVersionInfoSize(FileName, VerHandle);
if Size > 0 then
begin
GetMem(Buffer, Size);
try
if GetFileVersionInfo(FileName, VerHandle, Size, Buffer) then
begin
{ Query first language and that language blocks version info }
if VerQueryValue(Buffer, '\VarFileInfo\Translation', Pointer
(LangCharSetInfo), DataLen) then
begin
LangCharSetString :=
IntToHex(LangCharSetInfo^.Lang, 4) +
IntToHex(LangCharSetInfo^.CharSet, 4);
ProductName := GetStringFileInfo(Buffer, SubBlock, LangCharSetString, 'ProductName');
Version := GetStringFileInfo(Buffer, SubBlock, LangCharSetString, 'FileVersion');
Copyright := GetStringFileInfo(Buffer, SubBlock, LangCharSetString, 'LegalCopyright');
Comments := GetStringFileInfo(Buffer, SubBlock, LangCharSetString, 'Comments');
Caption := ProductName;
end;
end;
finally
FreeMem(Buffer, Size);
end;
end
end;
end;
А в пользовательском интерфейсе вам нужно будет вызвать свою бизнес-логику и поместить результаты в различные элементы управления.
- Йерун
Ответ перед редактированием:
Ваш код не компилируется как есть, поэтому без контекста сложно ответить на ваш квест.
Какие существуют типы данных Buffer, SubBlock, LongCharSetString и DataLen? Как вы получили Buffer?
Действительно ли Data - это указатель на символы (Ansi или Unicode)? Не должно ли в конечном итоге указывать на PVSFixedFileInfo?
(Дополнительный вопрос: почему ваша бизнес-логика находится внутри пользовательского интерфейса? Если бы вы где-то разбили свою логику на отдельную функцию, у вас, вероятно, была бы подпрограмма компиляции, которая могла бы послужить основой для вашего вопроса. ответили на вопрос в первую очередь).
Для вопросов, подобных вашему, я обычно заглядываю единицы измерения в JCL или JVCL . Они приложили немало усилий, чтобы быть совместимыми с Юникодом.
Их код, который использует VerQueryValue, это код в модуле JclFileUtils, метод VersionFixedFileInfo:
// Fixed Version Info routines
function VersionFixedFileInfo(const FileName: string; var FixedInfo: TVSFixedFileInfo): Boolean;
var
Size, FixInfoLen: DWORD;
Handle: THandle;
Buffer: string;
FixInfoBuf: PVSFixedFileInfo;
begin
Result := False;
Size := GetFileVersionInfoSize(PChar(FileName), Handle);
if Size > 0 then
begin
SetLength(Buffer, Size);
if GetFileVersionInfo(PChar(FileName), Handle, Size, Pointer(Buffer)) and
VerQueryValue(Pointer(Buffer), DirDelimiter, Pointer(FixInfoBuf), FixInfoLen) and
(FixInfoLen = SizeOf(TVSFixedFileInfo)) then
begin
Result := True;
FixedInfo := FixInfoBuf^;
end;
end;
end;
Надеюсь, это поможет вам найти решение.
- Йерун