'Getting application version number in Lazarus project not working
I'm using the following unit to try to read the application version number in a Lazarus project but GetProductVersion always returns 0.0.0.0
http://forum.lazarus.freepascal.org/index.php?topic=13957
I'm using Lazarus 1.2.4 with FPC 2.6.4 on Windows 7.
I get no errors when I compile and link and run the application so it appears that the unit is included correctly...
I have no idea where else to look for what's not working. Can someone give me some pointers?
Solution 1:[1]
I finally got to the bottom of this.. and it's just a little catch-out that might help someone so I'll post what I was doing wrong.
There are actually three different versions in a Lazarus project, and they are all in Project Options-> Version info:
- Version numbering, which is in its own little box.
- ProductVersion, which is in 'Other info'.
- FileVersion, which is in 'Other info'.
It's actually obvious when you read Mike.Cornflakes description at http://forum.lazarus.freepascal.org/index.php?topic=13957 but I was not seeing the wood for the trees.
Just make sure if you are setting one value, you are reading the right one with Mike's functions.
(The discussion at the link above also explains the difference between using FileVersion and ProductVersion (apparently Windows documentation specifies that Product Version indicates the version of a product that a dll is supposed to be used with.)
Solution 2:[2]
An alternative exists, which is to read into a compiled executable file, and try to locate the VS_VERSION_INFO structure, then read properties from within it.
This does not require any classes for handling lazarus resources. Also, this way you can read version information not only from your calling application, but also from any other application by just reading its binary file.
It is actually the latter that I often need to perform in various automation scripts (ie for packaging my lazarus apps as .deb on linux). So I worked out a unit with both a procedural and an objective access to this, which you can use. This unit only uses two other FPC standard units, namely Classes and SysUtils - an nothing else! Very little overhead!
You can read VS_VERSION_INFO from any file, including the calling application by supplying Application.ExeName as an argument.
Here is the unit: https://sourceforge.net/p/all-things-ubuntu-library/code/HEAD/tree/trunk/ATUpackages/ATU/ATU-src/atulazversioninfo.pas
Here is the Wiki page: https://sourceforge.net/p/all-things-ubuntu-library/wiki/atuLazVersionInfo/
The wiki page includes the following usage example:
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 link is just for convenience, but in order for explaining the actual mechanism used please see an output of an instantfpc script that uses the linked code:
So the way Lazarus embeds version information in an executable is by compiling VS_VERSION_INFO structure into the output file. You can locate it in the file, because it will be a BTSTR string constant equal to "VS_VERSION_INFO", where every character is a two byte word encoded with UTF-16 and a null termination character (also a two byte word), which is also referred as PWIDECHAR.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | |
Solution 2 | Kris Jace |