Search code examples
inno-setuppascalscript

Can we use the new "Version" functions in Inno Setup 6.1 to make the script simpler?


I have several places in my script where I work with version numbers:

  • Scenario 1

    #define AppVerText() \
       GetVersionComponents(SourceDir + '\Meeting Schedule Assistant.exe', \
           Local[0], Local[1], Local[2], Local[3]), \
       Str(Local[0]) + "." + Str(Local[1]) + "." + Str(Local[2])
    
  • Scenario 2

    { Is the installed version at least 14.14 ? }
        Result := (Major < 14) or
            ((Major = 14) and ((Minor < 14) or
            ((Minor = 14) and ((Bld < 26429) or
            ((Bld = 26429) and (Rbld < 3))))));
    if (Result) then
    

    The various values were extracted from registry keys.

  • Scenario 3

    { Check Windows Version }
    WindowsVersion := GetWindowsVersion;
    Log(Format('Windows Version: %x', [WindowsVersion]));
    (* Windows must be Win 7 SP1 (6.1.7601), Win 8.1 (6.3.9200) or higher,
        eg: Win 10 (10.0.10240)
        See: http://www.jrsoftware.org/ishelp/index.php?topic=winvernotes
        Microsoft .Net Framework 4.6.2 will only work with these operating systems. *)
    if (WindowsVersion <  MakeVersion(6, 1, 7601)) or
         ((WindowsVersion >= MakeVersion(6, 2, 0)) and
          (WindowsVersion < MakeVersion(6, 3, 0))) then
    begin
        MsgBox(SetupMessage(msgWindowsVersionNotSupported), mbError, MB_OK);
        Result := False;
    end;
    

    Which calls:

    function MakeVersion(Major, Minor, Build: Cardinal): Cardinal;
    begin
        Result := (Major shl 24) + (Minor shl 16) + Build;
    end;
    

I just wondered if we were able to make use of the new "version" Pascal functions etc. introduced in Inno Setup 6.1?


Solution

  • You can make use of ComparePackedVersion function (together with PackVersionComponents):

    Result :=
      (ComparePackedVersion(
        PackVersionComponents(Major, Minor, Bld, Rbld),
        PackVersionComponents(14, 14, 26429, 3)) < 0);
    

    It's not much improvement in terms of code length. But it's way less error prone and easier to understand.

    I believe it's actually safe to compare the packed versions numbers directly (at least unless your major version is not higher than 2^15). Though PackVersionComponents discourages that.

    Result :=
      (PackVersionComponents(Major, Minor, Bld, Rbld) <
       PackVersionComponents(14, 14, 26429, 3));
    

    Related question: Compare version strings in Inno Setup


    For the Windows version test, you can combine that with GetWindowsVersionEx:

    GetWindowsVersionEx(WinVer);
    WinVerPacked := PackVersionComponents(WinVer.Major, WinVer.Minor, WinVer.Build, 0);
    if (ComparePackedVersion(WinVerPacked, PackVersionComponents(6, 1, 7601, 0)) < 0) or
       ((ComparePackedVersion(WinVerPacked, PackVersionComponents(6, 2, 0, 0)) >= 0) and
        (ComparePackedVersion(WinVerPacked, PackVersionComponents(6, 3, 0, 0)) < 0)) then
    begin
      MsgBox(SetupMessage(msgWindowsVersionNotSupported), mbError, MB_OK);
      Result := False;
    end;
    

    And similarly as above, this should work too:

    if (WinVerPacked < PackVersionComponents(6, 1, 7601, 0)) or
       ((WinVerPacked >= PackVersionComponents(6, 2, 0, 0)) and
        (WinVerPacked < PackVersionComponents(6, 3, 0, 0))) then
    

    There's nothing to be improved on your first scenario.