Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Delphi "Version Compare" / Major/Minorversion Vergleich (https://www.delphipraxis.net/195457-version-compare-major-minorversion-vergleich.html)

slemke76 1. Mär 2018 19:39

"Version Compare" / Major/Minorversion Vergleich
 
Hallo zusammen,

ich möchte gerne sicher gehen, dass meine Anwendung (mindestens) gegen eine bestimmte Indy-Version compiliert ist - auch um versehntlich nicht auf die mitgelieferte Version "zurückzufallen".
Da gibt es die MajorVersion, MinorVersion, Release und Build Angabe in der IdVers.inc.

Unter PHP gibt es so eine prima Vergleichsfunktion: http://php.net/manual/de/function.version-compare.php
Gibt es etwas ähnliches unter Delphi?

Oder muss ich so etwas machen und in einer {$IF} Bedingung vergleichen?
(gsIdVersionMajor*1000*1000*1000)+(gsIdVersionMino r*1000*1000)+(gsIdVersionRelease*1000)+gsIdVersion Build => meinegewünschteversion

lg
Sebastian

Dalai 1. Mär 2018 21:46

AW: "Version Compare" / Major/Minorversion Vergleich
 
Multiplikation hab ich früher auch mal benutzt. Später bin ich auf eine Funktion _VersionCompare() im AutoIt gestoßen, die zwar recht lang ist, aber der Code ist gut verständlich. Die Funktion bekommt zwei Parameter (die zu vergleichenden Versionen), die an den darin enthaltenen Punkten gesplittet werden. Verglichen werden dann einfach die Einzelteile, und ein Abbruch erfolgt, sobald eine Ungleichheit gefunden wurde. Die Funktion fällt auf Stringvergleich zurück, sollte das nötig sein (eine Stelle bzw. ein Parameter kein Ordinalwert).

Sowas sollte sich in Delphi analog umsetzen lassen. Bei Interesse einfach mal AutoIt runterladen (ZIP genügt), und einen Blick in Include\Misc.au3 werfen. Auch als Nicht-AutoItler sollte man sich im Code zurechtfinden.

Grüße
Dalai

Ghostwalker 2. Mär 2018 03:59

AW: "Version Compare" / Major/Minorversion Vergleich
 
Hier mal meine Lösung:


Delphi-Quellcode:
unit Unit10;

interface
uses
  System.Classes,System.SysUtils;

Type
  TVersion = record
    private
      fmajor,fminor,frelease,fbuild : Integer;
    public
      property Major:integer read fmajor write fmajor;
      property Minor:integer read fminor write fminor;
      property Release:integer read frelease write frelease;
      Property Build:integer read fbuild write fbuild;

      Procedure SetVersion(major,minor,release,build:integer);
      Procedure FromString(VersionStr:string);
      function isEqualTo(Versionstr:string):boolean;

  end;
implementation

procedure TVersion.FromString(VersionStr: string);
var
  str : TStrings;

begin
  str := TStringlist.Create;
  str.Delimiter := '.';
  str.DelimitedText := VersionStr;
  fmajor := StrToInt(str.Strings[0]);
  fminor := StrToInt(str.Strings[1]);
  frelease := StrToInt(str.strings[2]);
  fbuild := StrToInt(str.Strings[3]);
  str.Free;
end;

function TVersion.isEqualTo(Versionstr: string):boolean;
var
  str : TStrings;
  hlp : integer;
begin
  str := Tstringlist.Create;
  str.Delimiter := '.';
  str.DelimitedText := VersionStr;
  result := false;
  hlp := StrToInt(str.Strings[0]);
  if (hlp = fmajor) then
  begin
    hlp := StrToInt(str.Strings[1]);
    if (hlp = fminor) then
    begin
      hlp := StrToInt(str.Strings[2]);
      if (hlp = frelease) then
      begin
        hlp := StrToInt(str.Strings[3]);
        if (hlp = fbuild) then
          result := true;
      end;
    end;
  end;
  str.Free;
end;

procedure TVersion.SetVersion(major: Integer; minor: Integer; release: Integer; build: Integer);
begin
  fmajor := major;
  fminor := minor;
  frelease : release;
  fbuild := build;
end;
end.
Anwendung:

Delphi-Quellcode:
  :
  const cDesiredVersion = '10.12.13.1294';
  :
  var vers : TVersion;
  :
  begin
    vers.FromString(cDesiredVersion);
    if (vers.isEqualTo(gsIdVersion)) then
      //wenn die Version passt
    else
     //wenn die Version nicht passt
  end;
Das ganze funktioniert zur Laufzeit (also wenn das Programm schon compiliert wurde).

Um das compilieren mit einer falschen Version zu unterbinden musst du den Weg über $IF gehen.

Bernhard Geyer 2. Mär 2018 07:23

AW: "Version Compare" / Major/Minorversion Vergleich
 
Bedenke das auch Versionnummern mit Buchstaben möglich sind.
Also 12.1.15b

Ghostwalker 2. Mär 2018 08:41

AW: "Version Compare" / Major/Minorversion Vergleich
 
Da hast du Recht. Die notwendigen Anpassungen sollten aber nicht wirklich das große Problem sein :)

himitsu 2. Mär 2018 10:04

AW: "Version Compare" / Major/Minorversion Vergleich
 
Wäre es nicht ganz einfach, wenn man einach nur ein NaturalCompare, oder wie man das immer nennen mag, nutzt?
Also wo Zahlen wir Zahlen und nicht als Strings verglichen werden, so wie bei der Sortierung im Explorer.

Und schon ist es egal wieviele Punkte/Nummern oder ob Buchstaben.
Eventuell noch die Leerzeichen ignorieren, bzw. durch Punkte ersetzen und doppelte Punkte entfernen.

slemke76 2. Mär 2018 10:07

AW: "Version Compare" / Major/Minorversion Vergleich
 
Hallo zusammen,

vielen Dank für die Anregungen - die Lösung aus dem AutoIT gefällt mir ab besten, da man nicht nur den exakten Vergleich sondern auch kleiner/größer machen könnte.

Ein Naturalcompare wird vermutlich bei diesem Beispiel nicht korrekt funktionieren: 10.6.2 gegen 10.10.2 - da wird die 10.10 als "älter" erkannt, da 1 vor 6 sortiert wird. Oder täusche ich mich jetzt?

Da ich derjenige bin, der das Program compiliert, möchte ich auch gerne die Meldung beim compilieren haben - eine Ausgabe zur Laufzeit (irgendwo in einer Unit, die man womöglich nicht jedesmal neu durchtestet) könnte man (= ich) übersehen ;-)

Ich habe es jetzt mehrere Lösungen, die ich nicht vorenthalten möchte:

Delphi-Quellcode:
{$i IdCompilerDefines.inc}

{$IFNDEF INDY100}
  {$MESSAGE Error 'This project must be compiled against Indy 10'}
{$ENDIF}
{$IFNDEF 10_6_2}
  {$MESSAGE Error 'This project must be compiled against Indy 10.6.2'}
{$ENDIF}
Wobei ich die Benennung von "10_6_2" unglücklich finde - "INDY10_6_2" wäre wohl besser gewesen, zumal folgende Bedingung nicht funktioniert: {$IF not Defined(INDY100) or not Defined(10_6_2)}

Das ganze macht natürlich nur einen exakten Vergleich - das ist etwas unglücklich, deswegen habe ich das anders gelöst - zuerst habe ich noch Multipliziert, aber dann bitweise verschoben und verknüpft - auch wenn nicht relevant bei heuten CPUs sicherlich die schnellste Lösung:

Delphi-Quellcode:
const
  {$i IdVers.inc}

  gsIdMinVersionMajor = 10;
  gsIdMinVersionMinor = 6;
  gsIdMinVersionRelease = 2;

  gsIdActualBitwise = ( gsIdVersionMajor shl 20) OR ( gsIdVersionMinor shl 10) OR gsIdVersionRelease;
  gsIdMinimumBitwise = ( gsIdMinVersionMajor shl 20 ) OR ( gsIdMinVersionMinor shl 10 ) OR gsIdMinVersionRelease;

{$IF not Declared(gsIdActualBitwise) or ( gsIdActualBitwise < gsIdMinimumBitwise )}
  {$MESSAGE Error 'Indy Version is too old.'}
{$IFEND}
Ich hoffe, es hilft irgendwann einmal jemanden ;-)

Grüße
Sebastian

himitsu 2. Mär 2018 10:15

AW: "Version Compare" / Major/Minorversion Vergleich
 
Statt Integern vielleicht mit Floats?

major.minor
major.minorxyz

1.2.3.4

1.020304

Delphi-Referenz durchsuchenCompilerVersion

slemke76 2. Mär 2018 10:30

AW: "Version Compare" / Major/Minorversion Vergleich
 
Hallo,

kann nicht ganz folgen, stehe auf dem Schlauch ;-) Bekommt man das schöner hin?

Die Definition, die von den Indys zur Verfügung steht sieht so aus: https://github.com/graemeg/indy/blob...tem/IdVers.inc

Sebastian

Uwe Raabe 2. Mär 2018 10:55

AW: "Version Compare" / Major/Minorversion Vergleich
 
Delphi-Quellcode:
{$IF (gsIdVersionMajor <> 10) or (gsIdVersionMinor <> 6) or (gsIdVersionRelease <> 2) or (gsIdVersionBuild <> 0)}
{$MESSAGE Fatal 'Falsche Indy-Version!'}
{$ENDIF}


Alle Zeitangaben in WEZ +1. Es ist jetzt 11:16 Uhr.
Seite 1 von 2  1 2      

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz