How can I read details of file?
This has been described at About:
Basically, you just use the GetFileVersionInfo
function to obtain the data and then VerQueryValue
function to read it.
Because these API functions are a bit 'hard' to use, I have written a simple example:
type
TEXEVersionData = record
CompanyName,
FileDescription,
FileVersion,
InternalName,
LegalCopyright,
LegalTrademarks,
OriginalFileName,
ProductName,
ProductVersion,
Comments,
PrivateBuild,
SpecialBuild: string;
end;
function GetEXEVersionData(const FileName: string): TEXEVersionData;
type
PLandCodepage = ^TLandCodepage;
TLandCodepage = record
wLanguage,
wCodePage: word;
end;
var
dummy,
len: cardinal;
buf, pntr: pointer;
lang: string;
begin
len := GetFileVersionInfoSize(PChar(FileName), dummy);
if len = 0 then
RaiseLastOSError;
GetMem(buf, len);
try
if not GetFileVersionInfo(PChar(FileName), 0, len, buf) then
RaiseLastOSError;
if not VerQueryValue(buf, '\VarFileInfo\Translation\', pntr, len) then
RaiseLastOSError;
lang := Format('%.4x%.4x', [PLandCodepage(pntr)^.wLanguage, PLandCodepage(pntr)^.wCodePage]);
if VerQueryValue(buf, PChar('\StringFileInfo\' + lang + '\CompanyName'), pntr, len){ and (@len <> nil)} then
result.CompanyName := PChar(pntr);
if VerQueryValue(buf, PChar('\StringFileInfo\' + lang + '\FileDescription'), pntr, len){ and (@len <> nil)} then
result.FileDescription := PChar(pntr);
if VerQueryValue(buf, PChar('\StringFileInfo\' + lang + '\FileVersion'), pntr, len){ and (@len <> nil)} then
result.FileVersion := PChar(pntr);
if VerQueryValue(buf, PChar('\StringFileInfo\' + lang + '\InternalName'), pntr, len){ and (@len <> nil)} then
result.InternalName := PChar(pntr);
if VerQueryValue(buf, PChar('\StringFileInfo\' + lang + '\LegalCopyright'), pntr, len){ and (@len <> nil)} then
result.LegalCopyright := PChar(pntr);
if VerQueryValue(buf, PChar('\StringFileInfo\' + lang + '\LegalTrademarks'), pntr, len){ and (@len <> nil)} then
result.LegalTrademarks := PChar(pntr);
if VerQueryValue(buf, PChar('\StringFileInfo\' + lang + '\OriginalFileName'), pntr, len){ and (@len <> nil)} then
result.OriginalFileName := PChar(pntr);
if VerQueryValue(buf, PChar('\StringFileInfo\' + lang + '\ProductName'), pntr, len){ and (@len <> nil)} then
result.ProductName := PChar(pntr);
if VerQueryValue(buf, PChar('\StringFileInfo\' + lang + '\ProductVersion'), pntr, len){ and (@len <> nil)} then
result.ProductVersion := PChar(pntr);
if VerQueryValue(buf, PChar('\StringFileInfo\' + lang + '\Comments'), pntr, len){ and (@len <> nil)} then
result.Comments := PChar(pntr);
if VerQueryValue(buf, PChar('\StringFileInfo\' + lang + '\PrivateBuild'), pntr, len){ and (@len <> nil)} then
result.PrivateBuild := PChar(pntr);
if VerQueryValue(buf, PChar('\StringFileInfo\' + lang + '\SpecialBuild'), pntr, len){ and (@len <> nil)} then
result.SpecialBuild := PChar(pntr);
finally
FreeMem(buf);
end;
end;
Try it. But beware -- currently, this only works for en-us EXEs! It doesn't work for most of the EXEs on my Swedish machine, for instance. It is late now; tomorrow I will extend this to work with any EXE language, if only I get some time left. [The About.com code has the same problem, but they don't even pretend it is a problem!]
Update: The code now works with any EXE language.
(Swedish)
Related videos on Youtube
Armin Taghavizad
Life is shorter than filling *About me*... [ LINKEDIN PROFILE ] [ INSTAGRAM PROFILE ]
Updated on December 16, 2020Comments
-
Armin Taghavizad over 3 years
How can I read details of an exe file like File Version, Product Version and anything else stored in Details tab in Properties window of that file? Thanks.
-
Armin Taghavizad about 13 yearsVery useful. my first search source was ABOUT, but i could not find it, i wonder why!!!. Really Thank you
-
Armin Taghavizad about 13 yearsI get this error while compiling: "Types of actual and formal var parameters must be identical" Wheres the problem? I did not make any change to described functions!
-
Andreas Rejbrand about 13 years@Armin: It would help if you told us what line the error occurrs at.
-
Armin Taghavizad about 13 yearsSure! The line: "n := GetFileVersionInfoSize(PChar(S),n) ;" | The 6th line in "VersionInformation Function". It has the same problem at this line: "...InfoStr[j]),Pointer(Value),Len) Then..." | The 14th line of "VersionInformation function". Also this error "Incompatible types: 'String' and 'Array'" in this code "...(StringPad(labelStr,' ',20,True)+' = '+Value) ;" | 20th line of "Version Information Function". im using Delphi-7 as shown in question tags.
-
Armin Taghavizad about 13 yearsi also checked these links, but didnt help, wrong and empty results!! 1)http://www.delphidabbler.com/articles?article=20 2)http://www.swissdelphicenter.ch/torry/showcode.php?id=1047
-
Andreas Rejbrand about 13 years@Armin: Skip the about.com code! I just wrote a simple example myself.
-
Armin Taghavizad about 13 yearsHey, it really worked! Your code worked perfect. Really thank you. i searched long time but i didnt find anything..
-
Andreas Rejbrand almost 13 years@Robrok: Project/Options.../'Version Info'.
-
Reversed Engineer almost 8 yearsExcellent thank you!! You overcame the long standing problem of which locale ID the resource information is stored in.
-
Uli Gerhardt over 5 yearsWhat's the thing with the commented out
@len <> nil
? -
T.S about 4 yearsVery helpful! - I just added a Trim() to the results though, as you get a lot of whitespace.