Menu

atuLazVersionInfo

Krzysztof Kamil Jacewicz

SYNOPSIS:

(see trunk version)

This unit will extract VS_VERSION_INFO data from a binary file. Without using Lazarus Resources. It will read binary and ASCII data embedded in a compiled executable, locate the VS_VERSION_INFO record, and read it directly. An application can use this unit for a procedural or objective access to the version control embedded in itself or in another executable.

COMPATIBILITY:

2022-04-27:
Tested on Linux (x86_64 and armhf) against Linux (ELF) and Windows (EXE) binaries.
Tested against x86, x86_64 and armhf ELF binaries
Unicode (UTF-16) seems working without issue (decoded Chinese Traditional characters)
The code has a test to detect if endianness of the system is different from the endiannes in a binary file, and in theory it should automatically switch to appropriate mode at run-time, but this feature has not been fully tested.

2022-04-26:
Only tested against VERSION_INFO compiled into executables by Lazarus IDE,
not sure if it also works for other executables.
Tested on Linux amd86_64 and armhf, should compile everywhere.
Tested against Linux ELF executables, not tested on EXE files yet.

USAGE EXAMPLE:

A preferred usage is via an instance of [TEmbeddedVersionInfo] class. Let's say we want to print Version Information embedded in the current GUI Lazarus Application. On Linux we can print to a stdout directly from a GUI application (on windows stdout pipe is closed by default and requires additional steps to open it). So under a button on the main form we place such a code:

  procedure TMainForm.Button1Click(Sender: TObject);
    var
      EVI : TEmbeddedVersionInfo;  //this gives us access to VS_VERSION_INFO embedded in an executable by Lazarus
      fn  : string;
      i   : integer;
    begin
      fn := Application.ExeName; //here we will read the executable of the current app. But we can also read other app.
      writeln('scanning for VS_VERSION_INFO in '+ExtractFileName(fn)+'...'); //we will print information to STDOUT
      EVI := TEmbeddedVersionInfo.Create(fn); //Constructor Automatically calls LoadFromFile method
      try
        if(not EVI.HasVersionInfo)then 
          begin
            writeln('not found.');
            exit;
          end;
        writeln('Found at offset #'+IntToHex(EVI.VersionInfoOffset, 16));
        writeln;
        for i:=0 to EVI.KeyCount-1 do writeln(EVI.Keys[i] + ' = ' + EVI.ValueByIndex[i]);
      finally
      end;
    end;

The example above prints data to STDOUT, and comes from a Linux application. So we can run the application from the command line, and then have both the application GUI and the terminal open for us to see. After pressing the Button one, the code above will execute, and in the terminal window we will see an output like this:

user@mymachine:~/Documents/code/lazarus/demoApp$ ./demoApp_x86_64-linux 
Gtk-Message: 16:53:42.370: Failed to load module "canberra-gtk-module"
scanning for VS_VERSION_INFO in demoApp_x86_64-linux...
Found at offset ##0000000000B7A45D

Comments = Copyright 2022 by Perun Inc. (perun.tw), Author: Kris Jacewicz (kris@perun.tw)
CompanyName = Perun Inc.
FileDescription = 
FileVersion = 0.9.32.0
InternalName = 
LegalCopyright = 
LegalTrademarks = 
OriginalFilename = 
ProductName = 劈隆有限公司
ProductVersion = 

As you can see above, the unicode text is supported. The ProductName key has a value in Traditional Chinese. We access the information embedded in the Version data by an array property. We can read the data by text keys, and by integer index. But the [TEmbeddedVersionInfo] class has more named properties for a direct access. Most of the Version properties are of text type, but a Version property is an array of 4 word numbers corresponding to parsed portions of the version string in this format: major.minor.release.build (ie. 0.9.0.0).

Below is an example of usage on Linux against 3rd party Windows binary files (EXE format), which were not compiled with FPC/Lazarus. The application called from the command line is just a quickly made demo, a standard Lazarus Application, it reads path to a binary from command line and prints extracted and parsed VS_VERION_INFO data. If you investigate the entire content of the terminal window, you will realise that in the working folder thatre are some windows binaries as well as some linux binaries. A standard file commandis used to detect the format and confirm that they are indeed two kinds of binary executables from different operating systems. The linux executable is built with Lazarus IDE. The other tested exe file is not. The demo tool can parse VS_VERSION_INFO data from both, and even Chinese Traditional characters are properly decoded and displayed:

screen


Related

Wiki: TEmbeddedVersionInfo

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.