Получить FileVersion с Build
DelphiXe.
Для получения версии файла я использую функцию:
function FileVersion(AFileName: string): string;
var
szName: array[0..255] of Char;
P: Pointer;
Value: Pointer;
Len: UINT;
GetTranslationString: string;
FFileName: PChar;
FValid: boolean;
FSize: DWORD;
FHandle: DWORD;
FBuffer: PChar;
begin
try
FFileName := StrPCopy(StrAlloc(Length(AFileName) + 1), AFileName);
FValid := False;
FSize := GetFileVersionInfoSize(FFileName, FHandle);
if FSize > 0 then
try
GetMem(FBuffer, FSize);
FValid := GetFileVersionInfo(FFileName, FHandle, FSize, FBuffer);
except
FValid := False;
raise;
end;
Result := '';
if FValid then
VerQueryValue(FBuffer, '\VarFileInfo\Translation', p, Len)
else
p := nil;
if P <> nil then
GetTranslationString := IntToHex(MakeLong(HiWord(Longint(P^)),
LoWord(Longint(P^))), 8);
if FValid then
begin
StrPCopy(szName, '\StringFileInfo\' + GetTranslationString +
'\FileVersion');
if VerQueryValue(FBuffer, szName, Value, Len) then
Result := StrPas(PChar(Value));
end;
finally
try
if FBuffer <> nil then
FreeMem(FBuffer, FSize);
except
end;
try
StrDispose(FFileName);
except
end;
end;
end;
Для большинства исполняемых файлов и библиотек возвращает правильное значение. Но у некоторых файлов версия обрезается и показывается без сборки. Вот например файл BASS.DLL (http://us.un4seen.com/files/bass24.zip) В проводнике Windows в свойствах файла я вижу версию 2.4.7.1, функция result='2.4.7':(
Я открываю файл через Resourcehacker.exe (http://angusj.com/resourcehacker/), смотрю структуру VersionInfo:
1 VERSIONINFO
FILEVERSION 2,4,7,1
PRODUCTVERSION 2,4,0,0
FILEOS 0x4
FILETYPE 0x2
{
BLOCK "StringFileInfo"
{
BLOCK "000004b0"
{
VALUE "CompanyName", "Un4seen Developments"
VALUE "FileDescription", "BASS"
VALUE "FileVersion", "2.4.7"
VALUE "LegalCopyright", "Copyright © 1999-2010"
}
}
BLOCK "VarFileInfo"
{
VALUE "Translation", 0x0000 0x04B0
}
}
Вопрос: как получить 2.4.7.1, т.е. полную версию?
2 ответа
Если вам нужна версия файла корневого блока, тогда забудьте о переводе на конкретный язык:
function FileVersion(const FileName: TFileName): String;
var
VerInfoSize: Cardinal;
VerValueSize: Cardinal;
Dummy: Cardinal;
PVerInfo: Pointer;
PVerValue: PVSFixedFileInfo;
begin
Result := '';
VerInfoSize := GetFileVersionInfoSize(PChar(FileName), Dummy);
GetMem(PVerInfo, VerInfoSize);
try
if GetFileVersionInfo(PChar(FileName), 0, VerInfoSize, PVerInfo) then
if VerQueryValue(PVerInfo, '\', Pointer(PVerValue), VerValueSize) then
with PVerValue^ do
Result := Format('v%d.%d.%d build %d', [
HiWord(dwFileVersionMS), //Major
LoWord(dwFileVersionMS), //Minor
HiWord(dwFileVersionLS), //Release
LoWord(dwFileVersionLS)]); //Build
finally
FreeMem(PVerInfo, VerInfoSize);
end;
end;
Если вы хотите редактировать аудио библиотеку BASS (чего вы не можете). Причина в том, что он сжат "Petite v1.4", который хочет Ян, чтобы люди не могли его легко редактировать.
Кроме того, для получения версии bass.dll есть экспорт, который при использовании вы можете получить абсолютную версию, как вы хотите без большого взлома, а что нет.