获取文件版本信息

  • 主题发起人 主题发起人 import
  • 开始时间 开始时间
I

import

Unregistered / Unconfirmed
GUEST, unregistred user!
定一个版本信息结构: type
PFixedFileInfo = ^TFixedFileInfo;
TFixedFileInfo = record
dwSignature : DWORD;
dwStrucVersion : DWORD;
wFileVersionMS : WORD; // 次版本号
wFileVersionLS : WORD; // 主版本号
wProductVersionMS : WORD; // 建立次数(build)
wProductVersionLS : WORD; // 发行次数(release)
dwFileFlagsMask : DWORD;
dwFileFlags : DWORD;
dwFileOS : DWORD;
dwFileType : DWORD;
dwFileSubtype : DWORD;
dwFileDateMS : DWORD;
dwFileDateLS : DWORD;
end; // TFixedFileInfo
 
下面是取版本信息函数
function FileInfo( const FileName :String ) : TFixedFileInfo;
var
dwHandle, dwVersionSize : DWORD;
strSubBlock : String;
pTemp : Pointer;
pData : Pointer;
begin
strSubBlock := ';
// 取得文件版本信息的大小
dwVersionSize := GetFileVersionInfoSize( PChar( FileName ), dwHandle );
 
if dwVersionSize <> 0 then
begin
GetMem( pTemp, dwVersionSize );
try
//取文件版本信息
if GetFileVersionInfo( PChar( FileName ),dwHandle,
dwVersionSize,pTemp ) then
//查询文件版本信息
if VerQueryValue( pTemp,PChar( strSubBlock ),
pData,dwVersionSize ) then
Result := PFixedFileInfo( pData )^;
finally
FreeMem( pTemp );
end; // try
end; // if dwVersionSize
end;
调用例子:
var
f1:string;
x :TFixedFileInfo;
begin
f1 := Application.ExeName;
x := FileInfo( f1 );
ShowMessage( f1 +
#13#10'Version: ' + IntToStr( x.wFileVersionLS ) + '.' +
IntToStr( x.wFileVersionMS ) +
#13#10'Release: ' + IntToStr( x.wProductVersionLS) +
#13#10'Build: ' + IntToStr( x.wProductVersionMS ) );
end;
**********************************
获取文件版本信息
type
TFileInfo = packed record
CommpanyName: string;
FileDescription: string;
FileVersion: string;
InternalName: string;
LegalCopyright: string;
LegalTrademarks: string;
OriginalFileName: string;
ProductName: string;
ProductVersion: string;
Comments: string;
VsFixedFileInfo:VS_FIXEDFILEINFO;
UserDefineValue:string;
end;
function GetFileVersionInfomation(const FileName: string; var info: TFileInfo;UserDefine:string=''):
boolean;
const
SFInfo= ';
var
VersionInfo: Pointer;
InfoSize: DWORD;
InfoPointer: Pointer;
Translation: Pointer;
VersionValue: string;
unused: DWORD;
begin
unused := 0;
Result := False;
InfoSize := GetFileVersionInfoSize(pchar(FileName), unused);
if InfoSize > 0 then
begin
GetMem(VersionInfo, InfoSize);
Result := GetFileVersionInfo(pchar(FileName), 0, InfoSize, VersionInfo);
if Result then
begin
VerQueryValue(VersionInfo, '', Translation, InfoSize);
VersionValue := SFInfo + IntToHex(LoWord(Longint(Translation^)), 4) +
IntToHex(HiWord(Longint(Translation^)), 4) + ';
VerQueryValue(VersionInfo, pchar(VersionValue + 'CompanyName'), InfoPointer, InfoSize);
info.CommpanyName := string(pchar(InfoPointer));
VerQueryValue(VersionInfo, pchar(VersionValue + 'FileDescription'), InfoPointer, InfoSize);
info.FileDescription := string(pchar(InfoPointer));
VerQueryValue(VersionInfo, pchar(VersionValue + 'FileVersion'), InfoPointer, InfoSize);
info.FileVersion := string(pchar(InfoPointer));
VerQueryValue(VersionInfo, pchar(VersionValue + 'InternalName'), InfoPointer, InfoSize);
info.InternalName := string(pchar(InfoPointer));
VerQueryValue(VersionInfo, pchar(VersionValue + 'LegalCopyright'), InfoPointer, InfoSize);
info.LegalCopyright := string(pchar(InfoPointer));
VerQueryValue(VersionInfo, pchar(VersionValue + 'LegalTrademarks'), InfoPointer, InfoSize);
info.LegalTrademarks := string(pchar(InfoPointer));
VerQueryValue(VersionInfo, pchar(VersionValue + 'OriginalFileName'), InfoPointer, InfoSize);
info.OriginalFileName := string(pchar(InfoPointer));
VerQueryValue(VersionInfo, pchar(VersionValue + 'ProductName'), InfoPointer, InfoSize);
info.ProductName := string(pchar(InfoPointer));
VerQueryValue(VersionInfo, pchar(VersionValue + 'ProductVersion'), InfoPointer, InfoSize);
info.ProductVersion := string(pchar(InfoPointer));
VerQueryValue(VersionInfo, pchar(VersionValue + 'Comments'), InfoPointer, InfoSize);
info.Comments := string(pchar(InfoPointer));
if VerQueryValue(VersionInfo, ', InfoPointer, InfoSize) then
info.VsFixedFileInfo := TVSFixedFileInfo(InfoPointer^);
if UserDefine<>'' then
begin
if VerQueryValue(VersionInfo,pchar(VersionValue+UserDefine),InfoPointer,InfoSize) then
info.UserDefineValue:=string(pchar(InfoPointer));
end;
end;
FreeMem(VersionInfo);
end;
end;
调用演示:
procedure TForm1.Button1Click(Sender: TObject);
var
info: TFileInfo;
begin
if OpenDialog1.Execute then
begin
if GetFileVersionInfomation(opendialog1.FileName, info,'WOW Version') then
begin
Listbox1.Items.Add(OpenDialog1.FileName);
ListBox1.Items.Add('Comments:' + info.Comments);
ListBox1.Items.Add('CommpanyName:' + info.CommpanyName);
ListBox1.Items.Add('FileDescription:' + info.FileDescription);
ListBox1.Items.Add('FileVersion:' + info.FileVersion);
ListBox1.Items.Add('InternalName:' + info.InternalName);
ListBox1.Items.Add('LegalCopyright:' + info.LegalCopyright);
ListBox1.Items.Add('LegalTrademarks:' + info.LegalTrademarks);
ListBox1.Items.Add('OriginalFileName:' + info.OriginalFileName);
ListBox1.Items.Add('ProductName:' + info.ProductName);
ListBox1.Items.Add('ProductVersion:' + info.ProductVersion);
ListBox1.Items.Add('UserDefineValue:' + info.UserDefineValue);
if boolean(info.VsFixedFileInfo.dwFileFlags and vs_FF_Debug) then
listbox1.Items.Add('Debug:True')
else
ListBox1.Items.Add('Debug:False');
ListBox1.Items.Add('');
end;
end;
end;
*******************
GoodHope:
下面是我抽空写的一个读取全部版本信息的函数,由于工作紧张,没有写释放部分。
这个函数假定版本信息已经存到一个文件中,其实直接用GetFileVersionInfo取得的内容初始化TMemoryStream也是完全可以的。
type
TFileInfo = packed record
CommpanyName: string;
FileDescription: string;
FileVersion: string;
InternalName: string;
LegalCopyright: string;
LegalTrademarks: string;
OriginalFileName: string;
ProductName: string;
ProductVersion: string;
Comments: string;
VsFixedFileInfo:VS_FIXEDFILEINFO;
UserDefineValue:string;
end;
PAString = ^TAString;
TAString = packed record
wLength: WORD;
wValueLength: WORD;
wType: WORD;
szKey: PWCHAR;
Padding: PWCHAR;
Value: PWCHAR;
end;
PStringTable = ^TStringTable;
TStringTable = packed record
wLength: WORD;
wValueLength: WORD;
wType: WORD;
szKey: PWCHAR;
Padding: PWCHAR;
Children: array of PAString;
end;
PStringFileInfo = ^TStringFileInfo;
TStringFileInfo = packed record
wLength: WORD;
wValueLength: WORD;
wType: WORD;
szKey: PWCHAR;
Padding: PWCHAR;
Children: array of PStringTable;
end;
PAVar = ^TAVar;
TAVar = packed record
wLength: WORD;
wValueLength: WORD;
wType: WORD;
szKey: PWCHAR;
Padding: PWCHAR;
Value: PWCHAR;
end;
PVarFileInfo = ^TVarFileInfo;
TVarFileInfo = packed record
wLength: WORD;
wValueLength: WORD;
wType: WORD;
szKey: PWCHAR;
Padding: PWCHAR;
Children: array of PAVar;
end;
PVSVersionInfo = ^TVSVersionInfo;
TVSVersionInfo = packed record
wLength: WORD;
wValueLength: WORD;
wType: WORD;
szKey: PWCHAR;
Padding1: PWCHAR;
Value: TVSFixedFileInfo;
Padding2: PWCHAR;
StringFileInfo: PStringFileInfo;
VarFileInfo: PVarFileInfo;
end;
function LoadVersionInfo(const FileName: string): PVSVersionInfo;
var
Stream: TMemoryStream;
function ReadWideString: PWideChar;
var
iCount, iSize: Integer;
Buffer: PWideChar;
wcTerminal: WideChar;
begin
Result := nil;
Buffer := Pointer(Integer(Stream.Memory) + Stream.Position);
wcTerminal := #0;
for iCount := 0 to ((Stream.Size - Stream.Position) div 2) - 1 do
if Buffer[iCount] = wcTerminal then begin
iSize := Succ(iCount) * SizeOf(WideChar);
Result := AllocMem(iSize);
Stream.Read(Result^, iSize);
Exit;
end;
end;
function AlignToDWord: PWideChar;
var
iCount: Integer;
begin
iCount := Stream.Position mod 4;
if iCount = 0 then
Result := nil
else begin
Result := AllocMem(((iCount + 1) div 2) * SizeOf(WideChar));
Stream.Read(Result^, iCount);
end;
end;
 
function ReadString: PAString;
begin
New(Result);
Stream.Read(Result.wLength, SizeOf(WORD));
Stream.Read(Result.wValueLength, SizeOf(WORD));
Stream.Read(Result.wType, SizeOf(WORD));
Result.szKey := ReadWideString;
ResultPadding := AlignToDWord;
Result.Value := ReadWideString;
AlignToDWord;
end;
function ReadStringTable:PStringTable;
var
TerminalPos: Integer;
begin
TerminalPos := Stream.Position;
New(Result);
Stream.Read(Result.wLength, SizeOf(WORD));
Stream.Read(Result.wValueLength, SizeOf(WORD));
Stream.Read(Result.wType, SizeOf(WORD));
Result.szKey := ReadWideString;
ResultPadding := AlignToDWord;
Inc(TerminalPos, Result.wLength);
while Stream.Position < TerminalPos - 1 do begin
SetLength(Result.Children, Length(Result.Children) + 1);
Result.Children[High(Result.Children)] := ReadString;
end;
end;
function ReadStringFileInfo: PStringFileInfo;
var
TerminalPos: Integer;
begin
TerminalPos := Stream.Position;
New(Result);
Stream.Read(Result.wLength, SizeOf(WORD));
Stream.Read(Result.wValueLength, SizeOf(WORD));
Stream.Read(Result.wType, SizeOf(WORD));
Result.szKey := ReadWideString;
ResultPadding := AlignToDWord;
Inc(TerminalPos, Result.wLength);
while Stream.Position < TerminalPos - 1 do begin
SetLength(Result.Children, Length(Result.Children) + 1);
Result.Children[High(Result.Children)] := ReadStringTable;
end;
end;
function ReadAVar: PAVar;
begin
New(Result);
Stream.Read(Result.wLength, SizeOf(WORD));
Stream.Read(Result.wValueLength, SizeOf(WORD));
Stream.Read(Result.wType, SizeOf(WORD));
Result.szKey := ReadWideString;
ResultPadding := AlignToDWord;
Result.Value := ReadWideString;
AlignToDWord;
end;
function ReadVarFileInfo: PVarFileInfo;
var
TerminalPos: Integer;
begin
TerminalPos := Stream.Position;
New(Result);
Stream.Read(Result.wLength, SizeOf(WORD));
Stream.Read(Result.wValueLength, SizeOf(WORD));
Stream.Read(Result.wType, SizeOf(WORD));
Result.szKey := ReadWideString;
ResultPadding := AlignToDWord;
Inc(TerminalPos, Result.wLength);
while Stream.Position < TerminalPos - 1 do begin
SetLength(Result.Children, Length(Result.Children) + 1);
Result.Children[High(Result.Children)] := ReadAVar;
end;
end;
begin
New(Result);
Stream := TMemoryStream.Create;
Stream.LoadFromFile(FileName);
Stream.Read(Result.wLength, SizeOf(ResultwLength));
Stream.Read(Result.wValueLength, SizeOf(Result.wValueLength));
Stream.Read(Result.wType, SizeOf(Result.wType));
Result.szKey := ReadWideString;
Result.Padding1 := AlignToDWord;
Stream.Read(Result.Value, SizeOf(Result.Value));
Result.StringFileInfo := ReadStringFileInfo;
Result.VarFileInfo := ReadVarFileInfo;
Stream.Free;
end;
 
后退
顶部