Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Compare version strings in Inno Setup

I'm reading the value of an INF file, now I need to compare it with the installer version, but when I compile I get an error:

Unknown identifier: CompareVersion

What is wrong?

[Code]

function GetKeyValue(const AKeyName, AFileName, ADefault: string): string;
var  
  I: Integer;
  KeyPos: Integer;
  KeyFull: string;
  FileLines: TArrayOfString;
begin
  Result := ADefault;
  if LoadStringsFromFile(AFileName, FileLines) then
  begin
    KeyFull := AKeyName + '=';
    for I := 0 to GetArrayLength(FileLines) - 1 do
    begin
      FileLines[I] := TrimLeft(FileLines[I]);
      KeyPos := Pos(KeyFull, FileLines[I]);
      if KeyPos > 0 then
      begin
        Result := Copy(FileLines[I], KeyPos + Length(AKeyName) + 1, MaxInt);
        Break;
      end;
    end;
  end;
end;

var
  L2Ver2: TLabel;

procedure DirEditChange(Sender: TObject);
var
  FilePath: string;
begin
  FilePath := AddBackslash(WizardForm.DirEdit.Text) + 'left4dead2\steam.inf';
  L2Ver2.Caption := GetKeyValue('PatchVersion', FilePath, 'N/A');
  if (CompareVersion( L2Ver2.Caption, '{#MyAppOldVersion}') = 0) then
    begin
      ...
    end 
end;

I have the error in this line:

if (CompareVersion( L2Ver2.Caption, '{#MyAppOldVersion}') = 0) then

{#MyAppOldVersion} is already defined.

This post is related to my previous question: Read an INF file during the Setup.

If anyone can help, I would appreciate.

like image 630
Williams Mogollon Avatar asked Jun 15 '16 03:06

Williams Mogollon


People also ask

How to compare two version numbers?

To compare version numbers, compare their revisions in left-to-right order. Revisions are compared using their integer value ignoring any leading zeros. This means that revisions 1 and 001 are considered equal. If a version number does not specify a revision at an index, then treat the revision as 0 .

How do I create an inno file?

Go to Menu, Project, then Compile to compile and create the setup file. This will create a complete installer. Run the Setup and your application will be installed correctly. Innosetup offers an awesome alternative to create great looking Installers for free.


1 Answers

There's no CompareVersion function in Inno Setup (there is one since 6.1, see below).

You need to define your own.

Something like:

function CompareVersion(V1, V2: string): Integer;
var
  P, N1, N2: Integer;
begin
  Result := 0;
  while (Result = 0) and ((V1 <> '') or (V2 <> '')) do
  begin
    P := Pos('.', V1);
    if P > 0 then
    begin
      N1 := StrToInt(Copy(V1, 1, P - 1));
      Delete(V1, 1, P);
    end
      else
    if V1 <> '' then
    begin
      N1 := StrToInt(V1);
      V1 := '';
    end
      else
    begin
      N1 := 0;
    end;
  
    P := Pos('.', V2);
    if P > 0 then
    begin
      N2 := StrToInt(Copy(V2, 1, P - 1));
      Delete(V2, 1, P);
    end
      else
    if V2 <> '' then
    begin
      N2 := StrToInt(V2);
      V2 := '';
    end
      else
    begin
      N2 := 0;
    end;

    if N1 < N2 then Result := -1
      else
    if N1 > N2 then Result := 1;
  end;
end;
  • Returns 0, if the versions are equal.
  • Returns -1, if the V1 is older than the V2.
  • Returns 1, if the V1 is newer than the V2.
  • 1.12 is considered newer than 1.1.
  • 1.1 is considered the same as 1.1.0.
  • Throws an exception, when a version is syntactically invalid (only digits and dots are allowed).

Inno Setup 6.1 and newer supports version comparing nativelly with its ComparePackedVersion function (use GetPackedVersion to obtain binary version in the required form).


Unit tests:

procedure CompareVersionTest(V1, V2: string; Expected: Integer);
var
  R: Integer;
  M: string;
begin
  M := Format('Comparing [%s] vs. [%s] - expecting %d - ', [V1, V2, Expected]);
  R := CompareVersion(V1, V2);
  if R <> Expected then
  begin
    RaiseException(M + Format('Failed - Got %d', [R]));
  end
    else
  begin
    Log(M + 'Passed');
  end;
end;

procedure CompareVersionTests;
begin
  CompareVersionTest('1', '1', 0);
  CompareVersionTest('1.2', '1.2', 0);
  CompareVersionTest('1.2.3', '1.2.3', 0);
  CompareVersionTest('1', '2', -1);
  CompareVersionTest('1', '3', -1);
  CompareVersionTest('2', '3', -1);
  CompareVersionTest('2', '1', 1);
  CompareVersionTest('3', '1', 1);
  CompareVersionTest('3', '2', 1);
  CompareVersionTest('1', '12', -1);
  CompareVersionTest('12', '2', 1);
  CompareVersionTest('12', '12', 0);
  CompareVersionTest('1.2', '1.3', -1);
  CompareVersionTest('1.3', '1.2', 1);
  CompareVersionTest('1.2', '11.2', -1);
  CompareVersionTest('11.2', '1.2', 1);
  CompareVersionTest('1.1', '1.12', -1);
  CompareVersionTest('1.11', '1.12', -1);
  CompareVersionTest('1.12', '1.1', 1);
  CompareVersionTest('1.12', '1.11', 1);
  CompareVersionTest('1', '1.0', 0);
  CompareVersionTest('1.0', '1', 0);
  CompareVersionTest('1', '1.1', -1);
  CompareVersionTest('1.1', '1', 1);
  CompareVersionTest('1.12.123', '1.12.124', -1);
  CompareVersionTest('1.12.124', '1.12.123', 1);
  CompareVersionTest('1.12.123', '1.13.1', -1);
  CompareVersionTest('1.13.1', '1.12.123', 1);
  CompareVersionTest('1.12.123', '1.13', -1);
  CompareVersionTest('1.13', '1.12.123', 1);
  CompareVersionTest('1.12', '1.13.1', -1);
  CompareVersionTest('1.13.1', '1.12', 1);
end;

If you want to run the unit tests, just call CompareVersionTests in InitializeSetup.

like image 83
Martin Prikryl Avatar answered Sep 30 '22 08:09

Martin Prikryl