Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / lazarus / 2013-11

Program version

15 messages · 5 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Antonio Fortuny

Hi Folks.

Currently I can extract any Windows program version as far as it has been compilerd on a Win platform using either Delphi or Lazarus. I can do the same on a Linux program on a Linux platform as fas as far as the version has been embedde somewhere in the elf. So fa, so good.
But do you now any method for a program running on a Linux platform to extract the version of a Window compiled program ? And vice-versa ? Al I know about this is that the version is embedded somwhere into a resource into the executable
Is it right if I assume that executable program signatures are Windows: first two bytes of the file are "MZ".
Linux: first 4 bytes of the file are $7F'ELF'

Antonio

Reply by email

Sven Barth
to Antonio Fortuny
Antonio Fortuny wrote 9 lines
Hi Folks. Currently I can extract any Windows program version as far as it has been compilerd on a Win platform using either Delphi or Lazarus. I can do the same on a Linux program on a Linux platform as fas as far as the version has been embedde somewhere in the elf. So fa, so good. But do you now any method for a program running on a Linux platform to extract the version of a Window compiled program ? And vice-versa ?

For reading the version of a Windows executable on a Linux one you'd need to copy what the resource API on Windows does plus parsing the executable image.
For reading the version of a Linux executable on Windows you'd need to check how FPC implements this version information and parse the executable image accordingly.

Show quoted text 5 lines
Al I know about this is that the version is embedded somwhere into a resource into the executable Is it right if I assume that executable program signatures are Windows: first two bytes of the file are "MZ". Linux: first 4 bytes of the file are $7F'ELF'

For Windows definitely correct, for Linux I don't know, but seems legit...

Regards,
Sven

Reply by email

Anton Kavalenka
to Antonio Fortuny: Hi Folks. Currently I can extract any Windows program version as far as it has been…
Antonio Fortuny wrote 24 lines
Hi Folks. Currently I can extract any Windows program version as far as it has been compilerd on a Win platform using either Delphi or Lazarus. I can do the same on a Linux program on a Linux platform as fas as far as the version has been embedde somewhere in the elf. So fa, so good. But do you now any method for a program running on a Linux platform to extract the version of a Window compiled program ? And vice-versa ? Al I know about this is that the version is embedded somwhere into a resource into the executable Is it right if I assume that executable program signatures are Windows: first two bytes of the file are "MZ". Linux: first 4 bytes of the file are $7F'ELF' Antonio -- _______________________________________________ Lazarus mailing list http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus

The unit versionresource is part of package fcl-res

Unit allow x-platform version resource extraction and parsing.
rsrc:=TVersionResource.Create;
Stream := TResourceStream.CreateFromID(hMod, 1, PChar(RT_VERSION));
rsrc.SetCustomRawDataStream(Stream);
  with res do
       case it of
       vsFileVersion:
Result:=format('%d.%d.%d.%d',[FileVersion[0],FileVersion[1],FileVersion[2],FileVersion[3]]);
       vsProductVersion:
Result:=format('%d.%d.%d.%d',[ProductVersion[0],ProductVersion[1],ProductVersion[2],ProductVersion[3]]);
       end;

regards,
Anton
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.lazarus.freepascal.org/pipermail/lazarus/attachments/20131106/115c4dae/attachment.html>

Reply by email

Antonio Fortuny
to Anton Kavalenka

Le 06/11/2013 14:41, Anton Kavalenka a ?crit :

The unit versionresource is part of package fcl-res

I already use it for Linux with a Linux executable file

Unit allow x-platform version resource extraction and parsing. rsrc:=TVersionResource.Create; Stream := TResourceStream.CreateFromID(*hMod*, 1, PChar(RT_VERSION));

What's *hMod *stands for ? Looks like a pointer of so (PtrUint)

Show quoted text 18 lines
rsrc.SetCustomRawDataStream(Stream); with res do case it of vsFileVersion: Result:=format('%d.%d.%d.%d',[FileVersion[0],FileVersion[1],FileVersion[2],FileVersion[3]]); vsProductVersion: Result:=format('%d.%d.%d.%d',[ProductVersion[0],ProductVersion[1],ProductVersion[2],ProductVersion[3]]); end; regards, Anton -- _______________________________________________ Lazarus mailing list http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.lazarus.freepascal.org/pipermail/lazarus/attachments/20131106/e3761d22/attachment.html>

Reply by email

Anton Kavalenka
to Antonio Fortuny
Antonio Fortuny wrote 9 lines
Le 06/11/2013 14:41, Anton Kavalenka a ?crit : > The unit versionresource is part of package fcl-res I already use it for Linux with a Linux executable file > > Unit allow x-platform version resource extraction and parsing. > rsrc:=TVersionResource.Create; > Stream := TResourceStream.CreateFromID(*hMod*, 1, PChar(RT_VERSION)); What's *hMod *stands for ? Looks like a pointer of so (PtrUint)
Handle of EXE (hInstance) or .SO hMod:=Loadlibrary(dll_name);

Only sections of loaded into memory image can be reached. Otherwise use binutils objcopy.

regards,
Anton
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.lazarus.freepascal.org/pipermail/lazarus/attachments/20131106/9e26978f/attachment-0001.html>

Reply by email

Sven Barth
to Antonio Fortuny: Le 06/11/2013 14:41, Anton Kavalenka a ?crit : I already use it for Linux with a Linux…
Antonio Fortuny wrote 18 lines
Le 06/11/2013 14:41, Anton Kavalenka a ?crit : > The unit versionresource is part of package fcl-res I already use it for Linux with a Linux executable file > > Unit allow x-platform version resource extraction and parsing. > rsrc:=TVersionResource.Create; > Stream := TResourceStream.CreateFromID(*hMod*, 1, PChar(RT_VERSION)); What's *hMod *stands for ? Looks like a pointer of so (PtrUint) > rsrc.SetCustomRawDataStream(Stream); > with res do > case it of > vsFileVersion: > Result:=format('%d.%d.%d.%d',[FileVersion[0],FileVersion[1],FileVersion[2],FileVersion[3]]); > vsProductVersion: > Result:=format('%d.%d.%d.%d',[ProductVersion[0],ProductVersion[1],ProductVersion[2],ProductVersion[3]]); > end; >

Hmm... nice... we already seem to have cross platform support :)

You could try something like this (untested, just made up from the code I see in fcl-res!):

=== code begin ===

uses
   resource, winpeimagereader, elfreader, versionresource;
var
   res: TResources;
   abstrres: TAbstractResource;
begin
   res := TResources.Create;
   try
     res.LoadFromFile('whatever.exe'); // or 'whatever' for ELF files
     abstrres := res.Find(RT_VERSION, 1);
     if abstrres is TVersionResource then
       ...
   finally
     res.Free;
   end;
end.

=== code end ===

Regards,
Sven
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.lazarus.freepascal.org/pipermail/lazarus/attachments/20131106/c9fbd54a/attachment.html>

Reply by email

Sven Barth
to Anton Kavalenka: Handle of EXE (hInstance) or .SO hMod:=Loadlibrary(dll_name); Only sections of loaded…
Anton Kavalenka wrote 11 lines
On 06.11.2013 17:39, Antonio Fortuny wrote: > > Le 06/11/2013 14:41, Anton Kavalenka a ?crit : >> The unit versionresource is part of package fcl-res > I already use it for Linux with a Linux executable file >> >> Unit allow x-platform version resource extraction and parsing. >> rsrc:=TVersionResource.Create; >> Stream := TResourceStream.CreateFromID(*hMod*, 1, PChar(RT_VERSION)); > What's *hMod *stands for ? Looks like a pointer of so (PtrUint) Handle of EXE (hInstance) or .SO hMod:=Loadlibrary(dll_name);

Which is not what Antonio needs, because he wants to access a PE executable on Linux and an ELF executable on Windows.

Regards,
Sven
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.lazarus.freepascal.org/pipermail/lazarus/attachments/20131106/b4d49b05/attachment.html>

Reply by email

Antonio Fortuny
to Sven Barth

Le 06/11/2013 15:52, Sven Barth a ?crit :

Show quoted text 14 lines
Am 06.11.2013 15:46, schrieb Anton Kavalenka: > On 06.11.2013 17:39, Antonio Fortuny wrote: >> >> Le 06/11/2013 14:41, Anton Kavalenka a ?crit : >>> The unit versionresource is part of package fcl-res >> I already use it for Linux with a Linux executable file >>> >>> Unit allow x-platform version resource extraction and parsing. >>> rsrc:=TVersionResource.Create; >>> Stream := TResourceStream.CreateFromID(*hMod*, 1, PChar(RT_VERSION)); >> What's *hMod *stands for ? Looks like a pointer of so (PtrUint) > Handle of EXE (hInstance) or .SO hMod:=Loadlibrary(dll_name); Which is not what Antonio needs, because he wants to access a PE executable on Linux and an ELF executable on Windows.

Right Sven. It is a beginning anyway. Read my next post in a couple of minutes
Antonio;

Show quoted text 10 lines
Regards, Sven -- _______________________________________________ Lazarus mailing list http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus
Sita Software *Antonio Fortuny* Senior Software engineer 220, avenue de la Libert? L-4602 Niederkorn Tel.: +352 58 00 93 - 93 www.sitasoftware.lu <http://www.sitasoftware.lu> Your IT Partner -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.lazarus.freepascal.org/pipermail/lazarus/attachments/20131106/6e7336f1/attachment.html> -------------- next part -------------- A non-text attachment was scrubbed... Name: bjebbidi.jpg Type: image/jpeg Size: 2306 bytes Desc: not available URL: <http://lists.lazarus.freepascal.org/pipermail/lazarus/attachments/20131106/6e7336f1/attachment.jpg> -------------- next part -------------- A non-text attachment was scrubbed... Name: bejdeafd.jpg Type: image/jpeg Size: 921 bytes Desc: not available URL: <http://lists.lazarus.freepascal.org/pipermail/lazarus/attachments/20131106/6e7336f1/attachment-0001.jpg>

Reply by email

Antonio Fortuny
to Anton Kavalenka: Handle of EXE (hInstance) or .SO hMod:=Loadlibrary(dll_name); Only sections of loaded…

Le 06/11/2013 15:46, Anton Kavalenka a ?crit :

Handle of EXE (hInstance) or .SO hMod:=Loadlibrary(dll_name);

Works fine on Win32 with *hInstance*: great ! 8-)
I guess it will run on Linux too
Thanks.

regards, Anton

The code I use for Linux is the next one, which works almost the same except that the source is a file:

function ReadVersionInfo(const sProgram: string; Out vv: String) :Boolean;
var
   RS : TResources;
   E : TElfResourceReader;
   VR : TVersionResource;
   I : Integer;
begin
   Result := False; //no version info at all in the file
   RS:=TResources.Create;
   try
     E:=TElfResourceReader.Create;
     try
       Rs.LoadFromFile(sProgram,E);
     finally
       E.Free;
     end;
     VR:=Nil;
     I:=0;
     While (VR=Nil) and (I<RS.Count) do begin
       if RS.Items[i] is TVersionResource then
         VR:=TVersionResource(RS.Items[i]);
       Inc(I);
     end;
     Result:=(VRNil);
     if Result then begin
       vv:= Format('%d.%d.%d.%d',[VR.FixedInfo.FileVersion[0],
VR.FixedInfo.FileVersion[1], VR.FixedInfo.FileVersion[2],
VR.FixedInfo.FileVersion[3]]);
     End ;
   Finally
     RS.FRee;
   end;

Question is: does an equivalent to the "T*Elf*ResourceReader" exist for Windows executable files ?
I'm pretty sure that you do guess what I'm trying to do: have only one fuction to retrieve the version of any program on any platform. If a version using a file name can be setup, wonking on the current program is easy: check on ParamStr(0).
Maybe a couple of [$IFDEF ...} will be needed but this is not an issue. BTW, if the procedure works for WinCE too I'll be the happiest man on world. If this piece of code could be helpfull to others, it could be integrated to FPC or Lazarus, whatever.
It will need some rewriting though.

Antonio.

Show quoted text 7 lines
-- _______________________________________________ Lazarus mailing list http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus
Sita Software *Antonio Fortuny* Senior Software engineer 220, avenue de la Libert? L-4602 Niederkorn Tel.: +352 58 00 93 - 93 www.sitasoftware.lu <http://www.sitasoftware.lu> Your IT Partner -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.lazarus.freepascal.org/pipermail/lazarus/attachments/20131106/6010defe/attachment-0001.html> -------------- next part -------------- A non-text attachment was scrubbed... Name: djbjhagh.jpg Type: image/jpeg Size: 2306 bytes Desc: not available URL: <http://lists.lazarus.freepascal.org/pipermail/lazarus/attachments/20131106/6010defe/attachment-0002.jpg> -------------- next part -------------- A non-text attachment was scrubbed... Name: dhihjhgh.jpg Type: image/jpeg Size: 921 bytes Desc: not available URL: <http://lists.lazarus.freepascal.org/pipermail/lazarus/attachments/20131106/6010defe/attachment-0003.jpg>

Reply by email

Sven Barth
to Antonio Fortuny
Antonio Fortuny wrote 58 lines
Le 06/11/2013 15:46, Anton Kavalenka a ?crit : > Handle of EXE (hInstance) or .SO hMod:=Loadlibrary(dll_name); Works fine on Win32 with *hInstance*: great ! 8-) I guess it will run on Linux too Thanks. > > regards, > Anton The code I use for Linux is the next one, which works almost the same except that the source is a file: function ReadVersionInfo(const sProgram: string; Out vv: String) :Boolean; var RS : TResources; E : TElfResourceReader; VR : TVersionResource; I : Integer; begin Result := False; //no version info at all in the file RS:=TResources.Create; try E:=TElfResourceReader.Create; try Rs.LoadFromFile(sProgram,E); finally E.Free; end; VR:=Nil; I:=0; While (VR=Nil) and (I<RS.Count) do begin if RS.Items[i] is TVersionResource then VR:=TVersionResource(RS.Items[i]); Inc(I); end; Result:=(VRNil); if Result then begin vv:= Format('%d.%d.%d.%d',[VR.FixedInfo.FileVersion[0], VR.FixedInfo.FileVersion[1], VR.FixedInfo.FileVersion[2], VR.FixedInfo.FileVersion[3]]); End ; Finally RS.FRee; end; Question is: does an equivalent to the "T*Elf*ResourceReader" exist for Windows executable files ? I'm pretty sure that you do guess what I'm trying to do: have only one fuction to retrieve the version of any program on any platform. If a version using a file name can be setup, wonking on the current program is easy: check on ParamStr(0). Maybe a couple of [$IFDEF ...} will be needed but this is not an issue. BTW, if the procedure works for WinCE too I'll be the happiest man on world. If this piece of code could be helpfull to others, it could be integrated to FPC or Lazarus, whatever. It will need some rewriting though.

If you look at my other mail you'll see the solution. The reader unit for Windows PE files is WinPEImageReader. And you can avoid ifdefs by additionally to unit "resources" using the units "elfreader", "winpeimagereader" and "versionresource". Then you can do "Rs.LoadFromFile(sProgram);" (the explicit reader isn't needed as the extension will be used) and either loop through all resources like you currently do or use "Rs.Find(RT_VERSION, 1)" which should(!) return you the correct version resource.

Regards,
Sven
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.lazarus.freepascal.org/pipermail/lazarus/attachments/20131106/930ee0e2/attachment.html>

Reply by email

Antonio Fortuny
to Sven Barth

Le 06/11/2013 16:31, Sven Barth a ?crit :

If you look at my other mail you'll see the solution. The reader unit for Windows PE files is WinPEImageReader.

You're rigth and I used your comment to buil the test and it runs nice. 8-) Next step is to build some general procedure to retrieve the version of any pogram on any platform as far as far as the source file is accessible and has the platform executable signature. I think I have all the peices right now. Leave some days (I have other things to do for which I'm paid and a boss looking over my shoulder >:o , he is very comprehensive though).

Anyway, thank you to you two.
I'ill come back here when I have something clean and working.

Antonio.

And you can avoid ifdefs by additionally to unit "resources" using the units "elfreader", "winpeimagereader" and "versionresource". Then you can do "Rs.LoadFromFile(sProgram);"

Does make sense. In fact that's exactly what I've done just before your post.

(the explicit reader isn't needed as the extension will be used) and either loop through all resources like you currently do or use "Rs.Find(RT_VERSION, 1)" which should(!) return you the correct version resource.

Which avoids the ridiculous loop

Show quoted text 9 lines
Regards, Sven -- _______________________________________________ Lazarus mailing list http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus
Sita Software *Antonio Fortuny* Senior Software engineer 220, avenue de la Libert? L-4602 Niederkorn Tel.: +352 58 00 93 - 93 www.sitasoftware.lu <http://www.sitasoftware.lu> Your IT Partner -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.lazarus.freepascal.org/pipermail/lazarus/attachments/20131106/2326d60d/attachment.html> -------------- next part -------------- A non-text attachment was scrubbed... Name: fbhdfeff.jpg Type: image/jpeg Size: 2306 bytes Desc: not available URL: <http://lists.lazarus.freepascal.org/pipermail/lazarus/attachments/20131106/2326d60d/attachment.jpg> -------------- next part -------------- A non-text attachment was scrubbed... Name: icbdgbgf.jpg Type: image/jpeg Size: 921 bytes Desc: not available URL: <http://lists.lazarus.freepascal.org/pipermail/lazarus/attachments/20131106/2326d60d/attachment-0001.jpg>

Reply by email

Hans-Peter Diettrich
to Antonio Fortuny: Le 06/11/2013 15:46, Anton Kavalenka a ?crit : Works fine on Win32 with *hInstance*:…
I'm pretty sure that you do guess what I'm trying to do: have only one fuction to retrieve the version of any program on any platform.

Please understand that every platform has its own executable file formats. This means that your program must include an executable file loader for every supported platform.

Sven already explained where these loaders can be found (WinPEImageReader...), you have to manage that *all* these loaders become part of your program.

DoDi

Reply by email

Antonio Fortuny
to Antonio Fortuny: Hi Folks. Currently I can extract any Windows program version as far as it has been…

Hi again.

I succeeded to make one source unit which when used into any Lazarus unit, gives the version of any file as far as the file :
- has been compiled whith Lazarus or Delphi
- version information is in the resource data ad hoc (as Lazarus and Delphi provide)
The file to analyze can be any executable file provided that the standard OS signatures are at the beginning of the file:
- 'MZ' as the first two chars of the file for any windows program (inclusive WinCE)
- #127+'ELF' as the first four chars of a Linux executable file The unit can be compiled by Lazarus (or FPC I guess) on Win32, Win64, Linux x86_64 (I guess i386 too)
Targets can be Win32, WinCE, Win64, Linux x86_64
A program using the version unit runs on Win32, win64, winCE, Linux x86_64 Whatever the target can be, there is no need to change anything. Same source runs on all named platforms.
In case of trouble, the unit is supposed not to blow up. It gives a blank version intead.?
See th source unit as attachment.

As I'm not perfect, so I suppose that my code could easily be changed, adapted or made better in any way. Feel free to comment for improvements There are not very much comments as code is almost self explanatory but there improvements can be made as well.

Antonio.

-------------- next part --------------
unit uProgramVersion;
{
Author: Antonio Fortuny (a(DOT)fortuny(AT)sitasoftawre(DOT)lu ) Date: nov/2013
Company: Sita Software
Location: Luxembourg
www.sita.lu
}
interface

uses
  Classes,
  {$IFNDEF LINUX}
  windows,
  {$ENDIF}
  SysUtils;
type
  TVersion = record
    Major, Minor, Release, Build: Integer;
  end;
  PTVersion = ^TVersion;
{$IFDEF WINCE}
function ReadVersionInfo(const sProgram: WideString; Out vv: PTVersion) :Boolean;
function ProgramVersion(const sProgram: WideString) : WideString;
function ProgramVersionOnly(const sProgram: WideString) : WideString;
function ProgramFullVersion(const sProgram: WideString) : WideString;
function AnyProgramVersion(const sProgram: WideString): WideString; overload;
function AnyProgramVersion(const sProgram: string; Out vv: PTVersion) :Boolean; overload;
{$ELSE}
function ReadVersionInfo(const sProgram: string; Out vv: PTVersion) :Boolean;
function ProgramVersion(const sProgram: string) : string;
function ProgramVersionOnly(const sProgram: string) : string;
function ProgramFullVersion(const sProgram: string) : string;
function AnyProgramVersion(const sProgram: string): String; overload;
function AnyProgramVersion(const sProgram: string; Out vv: PTVersion) :Boolean; overload;
{$ENDIF}
function CurrentProgramVersion(const sProgram: string; const ExecType: char='W'): String;
implementation

uses
elfreader,
winpeimagereader,
resource,

  versionresource;
{$IFDEF WINCE}
function ReadVersionInfo(const sProgram: WideString; Out vv: PTVersion): Boolean;
{$ELSE}
function ReadVersionInfo(const sProgram: string; Out vv: PTVersion) :Boolean;
{$ENDIF}
begin
  if AnyProgramVersion(sProgram, vv) then
    Result := True
  else begin
    Result := False;
    vv := New(PTVersion);
    vv^.Major := 0;
    vv^.Minor := 0;
    vv^.Release := 0;
    vv^.Build := 0;
  end;
end;
{$IFDEF WINCE}
function ProgramVersionOnly(const sProgram: WideString) : WideString;
{$ELSE}
function ProgramVersionOnly(const sProgram: string): string;
{$ENDIF}
var
  vver: PTVersion=nil;
begin
  try
    Result := '0.0.0.0';
    if ReadVersionInfo(sProgram, vver) then begin
      //VersionProgramme := Format('%d.%d.%d.%d', [vver.Major, vver.Minor, vver.Release, vver.Build]);
      Result := Format('%d.%d.%d.%d', [vver^.Major, vver^.Minor, vver^.Release, vver^.Build]);
    end;
  finally
    if Assigned(vver) then
      Dispose(vver);
  end;
end;
{$IFDEF WINCE}
function ProgramFullVersion(const sProgram: WideString) : WideString;
{$ELSE}
function ProgramFullVersion(const sProgram: string) : string;
{$ENDIF}
var
  vver: PTVersion=nil;
begin
  // Initialisation de l'application:
  try
    Result := '000.000.000.000';
    if sProgram = EmptyStr then
      Exit;
    if ReadVersionInfo(sProgram, vver) then begin
      //VersionProgramme := Format('%d.%d.%d.%d', [vver.Major, vver.Minor, vver.Release, vver.Build]);
      Result := Format('%.3d.%.3d.%.3d.%.3d', [vver^.Major, vver^.Minor, vver^.Release, vver^.Build]);
    end;
  finally
    if Assigned(vver) then
      Dispose(vver);
  end;
end;
function CurrentProgramVersion(const sProgram: string; const ExecType: char='W'): String;
var
  RS : TResources;
  E : TWinPEImageResourceReader=nil;
  EL : TElfResourceReader=nil;
  VR : TVersionResource;
  I : Integer;
  wProgram: String;
  ar: array[0..4] of byte;
begin
{
Msg := CurrentProgramVersion(ParamStr(0));
DoLog(Format('version ce programme %s', [Msg]));
Msg := CurrentProgramVersion('D:\Compiled\Lazarus\i386-win32\ipconsole.exe');
DoLog(Format('version lazarus win32 "D:\Compiled\Lazarus\i386-win32\ipconsole.exe" %s', [Msg]));
Msg := CurrentProgramVersion('D:\Compiled\BackupClient.exe');
DoLog(Format('version Delphi win32 "D:\Compiled\BackupClient.exe" %s', [Msg]));
Msg := CurrentProgramVersion('D:\Compiled\Lazarus\arm-wince\Commandes.exe');
DoLog(Format('version Delphi winCE "D:\Compiled\Lazarus\arm-wince\Commandes.exe" %s', [Msg]));
try
  Msg := CurrentProgramVersion('T:\compiled\TestVersionLinux', 'L');
  DoLog(Format('version Delphi winCE "T:\compiled\TestVersionLinux" %s', [Msg]));
except
  DoLog(Format('version Delphi winCE "T:\compiled\TestVersionLinux" %s', ['Exception']));
end;
}
  if sProgram = EmptyStr then
    wProgram := ParamStr(0)
  else
    wProgram := sProgram;
  RS:=TResources.Create;
  try
    try
      if ExecType = 'W' then begin
        E := TWinPEImageResourceReader.Create;
        Rs.LoadFromFile(wProgram, E);
      end else begin
        EL := TElfResourceReader.Create;
        Rs.LoadFromFile(wProgram, EL);
      end;
    finally
      if Assigned(E) then
        E.Free;
      if Assigned(EL) then
        EL.Free;
    end;
    VR:=Nil;
    I:=0;
    While (VR=Nil) and (I < RS.Count) do begin
      if RS.Items[i] is TVersionResource then
        VR := TVersionResource(RS.Items[i]);
      Inc(I);
    end;
    if VR  Nil then begin
      Result := Format('%d.%d.%d.%d',[VR.FixedInfo.FileVersion[0], VR.FixedInfo.FileVersion[1], VR.FixedInfo.FileVersion[2], VR.FixedInfo.FileVersion[3]]);
    End ;
  Finally
    RS.FRee;
  end;
  {
  try
    E:=TWinPEImageResourceReader.Create;
    try
      Rs.LoadFromFile(wProgram, E);
    finally
      E.Free;
    end;
    VR:=Nil;
    I:=0;
    While (VR=Nil) and (I < RS.Count) do begin
      if RS.Items[i] is TVersionResource then
        VR:=TVersionResource(RS.Items[i]);
      Inc(I);
    end;
    if VR  Nil then begin
      Result := Format('%d.%d.%d.%d',[VR.FixedInfo.FileVersion[0], VR.FixedInfo.FileVersion[1], VR.FixedInfo.FileVersion[2], VR.FixedInfo.FileVersion[3]]);
    End ;
  Finally
    RS.FRee;
  end;
  }
end;
{$IFDEF WINCE}
function AnyProgramVersion(const sProgram: WideString): WideString;
{$ELSE}
function AnyProgramVersion(const sProgram: string): String;
{$ENDIF}
var
  vv: PTVersion;
begin
  if AnyProgramVersion(sProgram, vv) then begin
    Result := Format('%d.%d.%d.%d', [vv^.Major, vv^.Minor, vv^.Release, vv^.Build]);
    Dispose(vv);
  end
  else
    Result := '0.0.0.0';
end;
{$IFDEF WINCE}
function AnyProgramVersion(const sProgram: string; Out vv: PTVersion) :Boolean;
{$ELSE}
function AnyProgramVersion(const sProgram: string; Out vv: PTVersion) :Boolean;
{$ENDIF}
const
  WIN_EXE: String = 'MZ';
  LINUX_EXE: String = #127 + 'ELF';
var
  wFileStr: TFileStream;
  RS : TResources;
  E : TWinPEImageResourceReader=nil;
  EL : TElfResourceReader=nil;
  VR : TVersionResource;
  I : Integer;
  {$IFDEF WINCE}
  wProgram: WideString;
  {$ELSE}
  wProgram: String;
  {$ENDIF}
  ar: array[0..4] of byte;
  ExecType: char;
begin
  Result := False;
  vv := New(PTVersion);
  with vv^ do begin
    Major:= -1;
    Minor := 0;
    Release := 0;
    Build := 0;
  end;
  if sProgram = EmptyStr then
    wProgram := ParamStr(0)
  else
    wProgram := sProgram;
  if not FileExists(wProgram) then begin
    // program name without path, assume directory of executing program
    if Pos(DirectorySeparator, wProgram) = 0 then begin
      wProgram := IncludeTrailingPathDelimiter(ExtractFilePath(ParamStr(0))) + sProgram;
      if not FileExists(wProgram) then
        Exit;
    end else
      // no path delimiter, get out
      Exit;
  end else
    wProgram := sProgram;
  wFileStr := TFileStream.Create(sProgram, fmOpenRead);
  try
    // check what kind of executable an get resources accordingly
    wFileStr.Read(ar, 4);
  Finally
    wFileStr.Free;
  end;
  if CompareMem(@(ar), Pchar(WIN_EXE), 2) then
    ExecType := 'W'
  else
  if CompareMem(@(ar), Pchar(LINUX_EXE), 4) then
    ExecType := 'L'
  else
    Exit;
  RS:=TResources.Create;
  try
    try
      if ExecType = 'W' then begin
        E := TWinPEImageResourceReader.Create;
        Rs.LoadFromFile(wProgram, E);
      end else begin
        EL := TElfResourceReader.Create;
        Rs.LoadFromFile(wProgram, EL);
      end;
    finally
      if Assigned(E) then
        E.Free;
      if Assigned(EL) then
        EL.Free;
    end;
    VR:=Nil;
    I:=0;
    While (VR=Nil) and (I < RS.Count) do begin
      if RS.Items[i] is TVersionResource then
        VR := TVersionResource(RS.Items[i]);
      Inc(I);
    end;
    if VR  Nil then begin
      with vv^ do begin
        Major:= VR.FixedInfo.FileVersion[0];
        Minor := VR.FixedInfo.FileVersion[1];
        Release := VR.FixedInfo.FileVersion[2];
        Build := VR.FixedInfo.FileVersion[3];
      end;
      Result := True
    End ;
  Finally
    RS.FRee;
  end;
end;
{$IFDEF WINCE}
function ProgramVersion(const sProgram: WideString): WideString;
{$ELSE}
function ProgramVersion(const sProgram: string) : string;
{$ENDIF}
begin
  // Initialisation de l'application:
  Result := ExtractFileName(sProgram) + ' v.' + ProgramVersionOnly(sProgram);
end;
end.

Reply by email

Sven Barth
to Antonio Fortuny
Antonio Fortuny wrote 22 lines
Hi again. I succeeded to make one source unit which when used into any Lazarus unit, gives the version of any file as far as the file : - has been compiled whith Lazarus or Delphi - version information is in the resource data ad hoc (as Lazarus and Delphi provide) The file to analyze can be any executable file provided that the standard OS signatures are at the beginning of the file: - 'MZ' as the first two chars of the file for any windows program (inclusive WinCE) - #127+'ELF' as the first four chars of a Linux executable file The unit can be compiled by Lazarus (or FPC I guess) on Win32, Win64, Linux x86_64 (I guess i386 too) Targets can be Win32, WinCE, Win64, Linux x86_64 A program using the version unit runs on Win32, win64, winCE, Linux x86_64 Whatever the target can be, there is no need to change anything. Same source runs on all named platforms. In case of trouble, the unit is supposed not to blow up. It gives a blank version intead.? See th source unit as attachment.

Note: as you are using the platform independant fcl-res it should run on any platform where fcl-res is supported and can read any PE (Win32, Win64, WinCE, NativeNT) or ELF (all supported Linux and likely also supported FreeBSD, NetBSD and OpenBSD systems and maybe also others (Solaris?)) binary where we support using resources.

Regards,
Sven

Reply by email

Michael Van Canneyt
to Sven Barth
Sven Barth wrote 27 lines
Am 07.11.2013 15:08, schrieb Antonio Fortuny: > Hi again. > > I succeeded to make one source unit which when used into any Lazarus unit, > gives the version of any file as far as the file : > - has been compiled whith Lazarus or Delphi > - version information is in the resource data ad hoc (as Lazarus and Delphi > provide) > The file to analyze can be any executable file provided that the standard > OS signatures are at the beginning of the file: > - 'MZ' as the first two chars of the file for any windows program > (inclusive WinCE) > - #127+'ELF' as the first four chars of a Linux executable file > The unit can be compiled by Lazarus (or FPC I guess) on Win32, Win64, Linux > x86_64 (I guess i386 too) > Targets can be Win32, WinCE, Win64, Linux x86_64 > A program using the version unit runs on Win32, win64, winCE, Linux x86_64 > Whatever the target can be, there is no need to change anything. Same > source runs on all named platforms. > In case of trouble, the unit is supposed not to blow up. It gives a blank > version intead.? > See th source unit as attachment. Note: as you are using the platform independant fcl-res it should run on any platform where fcl-res is supported and can read any PE (Win32, Win64, WinCE, NativeNT) or ELF (all supported Linux and likely also supported FreeBSD, NetBSD and OpenBSD systems and maybe also others (Solaris?)) binary where we support using resources.

The fileinfo unit - distributed by default with FPC - has this functionality since ages. It allows you to extract any information from the version info resource, on all supported FPC platforms.

Michael.

Reply by email