Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Versionsnummern vergleichen? (https://www.delphipraxis.net/104114-versionsnummern-vergleichen.html)

TheMiller 27. Nov 2007 16:31


Versionsnummern vergleichen?
 
Hallo,

ich ermittle Versionsnummern mit GetFileVersion und bekomme zB: 1.0.0.0 zurück. Kann ich diesen String mit anderen Versionsnummern im gleichen Format mit den normalen Vergleichsoperatoren < > vergleichen, oder muss ich erst die Punkte extrahieren um Probleme vorzubeugen?

Danke im Voraus

Progman 27. Nov 2007 16:35

Re: Versionsnummern vergleichen?
 
Wenn sie immer gleich sind, kannst du sie als Strings vergleichen.
Ich meine natürlich, wenn das Format immer das Gleiche ist ;)

TheMiller 27. Nov 2007 16:37

Re: Versionsnummern vergleichen?
 
Gut danke.

Das Format ist immer gleich.

Bye

Luckie 27. Nov 2007 16:42

Re: Versionsnummern vergleichen?
 
Schreib dir eine Funktion, die dir die Bestandteile in einem Record oder so zurückgibt. Das wäre für mich die saubere Lösung.

Laufi 27. Nov 2007 16:46

Re: Versionsnummern vergleichen?
 
hallo

Versionsnummern sind doch ganz normale Integer!

liebe Grüsse laufi

Progman 27. Nov 2007 16:50

Re: Versionsnummern vergleichen?
 
Die Function GetFileVersion (jedenfalls die ich kenne) arbeitet ja intern mit Integer. Bastelt dann eben nur einen String zusammen. Dürfte ja gar nicht so schwer sein, die umzuschreiben, so dass sie einen Record mit 4 Integer ausgibt.

TheMiller 27. Nov 2007 16:52

Re: Versionsnummern vergleichen?
 
Ja oder so. Ich benutze diese Funktion und habe mir die Version in ein Format mit Punkten umwandeln lassen. Dann lass ich das sein und nutze einfach nur die Integer, da ich sowieso gleich mit der Version 1.0.0.0 starte und nicht mit 0.1.0.0 oder so. Von daher dürfte das mit den Integern keine Probleme geben. Ein Record ist doch nicht unbedingt notwendig, oder?

Progman 27. Nov 2007 16:56

Re: Versionsnummern vergleichen?
 
wäre aber sicherer, es kann ja mal 1.2.4.33 mit 1.22.5.7 verglichen werden, da lohnt sich schon der Aufwand, die vier Felder eines Records zu vergleichen.

lbccaleb 27. Nov 2007 17:06

Re: Versionsnummern vergleichen?
 
enferne doch einfach aus der versionsnr. die punkte (.) und dann hast du eine normal integer zahle, die ja dann auch systematisch grösser sein sollte immer ;-)

das ganze kannst dann noch per strtoint zu einen integer machen und dann einfach mit der neuesten überprüfen, die zb auf nem serverliegt oder wo auch immer er sie her hat!!

mfg

ibp 27. Nov 2007 17:12

Re: Versionsnummern vergleichen?
 
Zitat:

Zitat von lbccaleb
enferne doch einfach aus der versionsnr. die punkte (.) und dann hast du eine normal integer zahle, die ja dann auch systematisch grösser sein sollte immer ;-)...

das glaube ich nicht!

Gegenbeweis..

1.23.45.67 < 2.0.0.0

1234567>2000

lbccaleb 27. Nov 2007 17:17

Re: Versionsnummern vergleichen?
 
ja dann muss er eben nur noch auf das höchste maß von stellen den integer erhöhen!! oder nicht??


edit:

Zitat:

Zitat von ibp
Zitat:

Zitat von lbccaleb
enferne doch einfach aus der versionsnr. die punkte (.) und dann hast du eine normal integer zahle, die ja dann auch systematisch grösser sein sollte immer ;-)...

das glaube ich nicht!

Gegenbeweis..

1.23.45.67 < 2.0.0.0

1234567>2000

ja aber

1234567<2000000

muss er also nur die anzahl der zahlen noch ausfindig machen und die durch nullen am ende editieren... oder hab ich da gerade nen denkfehler??

thkerkmann 27. Nov 2007 17:19

Re: Versionsnummern vergleichen?
 
Hi,

hier mal was aus meinem Fundus

Delphi-Quellcode:
function NumDots(s: string): integer;
var
  i: integer;
begin
  result := 0;
  for i := 1 to length(s) do
    if s[i] = '.' then
      inc(result);
end;

function CmdSplit(var S: string; c: char): string;
var
  i: integer;
begin
  i := pos(c, s);
  if i = 0 then
  begin
    result := s;
    s := '';
  end
  else
  begin
    result := copy(s, 1, i - 1);
    if i < length(s) then
      s := copy(s, i + 1, length(s) - i)
    else
      s := '';
  end;
end;

function CompareVersion(v1, v2: string): integer;
var
  iv_1: integer;
  iv_2: integer;
begin
  result := 0;
  if NumDots(v1) > NumDots(v2) then
    result := 1 // v1 hat mehr punkte als v2 -> v1 ist jünger
  else if NumDots(v1) < NumDots(v2) then
    result := -1 // v2 hat mehr punkte als v1 -> v2 ist jünger
  else
  begin // gleich viele punkte im versions-string
    while (length(v1) > 0) and (length(v2) > 0) do
    begin
      iv_1 := StrToIntDef(CmdSplit(v1, '.'), 0);
      iv_2 := StrToIntDef(CmdSplit(v2, '.'), 0);
      if iv_1 < iv_2 then
      begin
        result := -1;
        break;
      end
      else if iv_1 > iv_2 then
      begin
        result := 1;
        break;
      end
      else // if equal
      begin
        // continue compare loop
      end;
    end;
  end;
end;
Viel Spass damit

Gruss

Progman 27. Nov 2007 17:21

Re: Versionsnummern vergleichen?
 
Die sicherste Variante ist doch ein Record in der Form
Delphi-Quellcode:
MajorVersion,SubVersion,SubSubVersion,BuildNummer: Integer;
und dann eben von MajorVersion abwärts zu vergleichen.

Hawkeye219 27. Nov 2007 17:42

Re: Versionsnummern vergleichen?
 
@thkerkmann

Delphi-Quellcode:
if (CompareVersion('2.0', '1.0') <> CompareVersion('2.0', '1.5.1')) then
  ShowMessage ('Ooops!');
Gruß Hawkeye

thkerkmann 27. Nov 2007 17:51

Re: Versionsnummern vergleichen?
 
@Hawkeye:

Ja das stimmt :oops:
Ich verwende diese Routine nur zum Vergleichen von standard Versionsnummern (maj.min.sub.build), da ist mir das noch gar nicht aufgefallen.
Deine Beispiele würden bei mir so aussehen: 2.0.0 vs 1.5.1, da meine Programme alle mit der gleichen Komponente dafür gearbeitet haben.
Neue Programme nutzen die Delphi Versionsnummernresource und haben dann immer 4 Stellen, auch da klappt es.

Gruss

PaddyL 27. Nov 2007 17:53

Re: Versionsnummern vergleichen?
 
Seltsam, ähnliches Problem kam vor kurzer Zeit in einem anderen Forum auf, wo ich folgende Delphi Lösung vorstellte:

Delphi-Quellcode:
program Project1;

{$APPTYPE CONSOLE}
{$DEFINE DEBUG}

uses
  SysUtils, Classes;

type
  TCVSResult = (csEqual, csFirst, csSecond);
  TStrArray = array of string;

function Explode(Border, S: string): TStrArray;
var
  S2: string;
  I: Integer;
  a: TStrArray;
begin
  I := 0;
  S2 := S + Border;
  repeat
    SetLength(A, Length(A) + 1);
    a[I] := Copy(S2, 0, Pos(Border, S2) - 1);
    Delete(S2, 1, Length(a[I] + Border));
    Inc(I);
  until S2 = '';
  Result := a;
end;

function StringReplaceCharacters(Str: String): String;
var
  I: Integer;
begin
  Str := StringReplace(Str, ' ', '', [rfIgnoreCase]);
  Str := StringReplace(Str, 'alpha', '.-26', [rfIgnoreCase]);
  Str := StringReplace(Str, 'beta', '.-25', [rfIgnoreCase]);
  for I := 0 to 19 do
    Str := StringReplace(Str, 'RC' + IntToStr(I), '.-' + IntToStr(20 - I),
                         [rfIgnoreCase]);
  for I := 0 to 25 do
    Str := StringReplace(Str, Chr(Ord('a') + I), '.-' + IntToStr(26 - I + 20),
                         [rfIgnoreCase]);
  Result := Str;
end;

function CompareVersionStrings(Str1, Str2: String): TCVSResult;
var
  S1, S2: String;
  Stl: array[0..1] of TStrArray;
  I: Integer;
  X: Integer;
begin
  {$IFDEF DEBUG}
    WriteLn('Debug: comparing' + Str1 + ' vs ' + Str2);
  {$ENDIF}
  Result := csEqual;
  S1 := StringReplaceCharacters(Str1);
  S2 := StringReplaceCharacters(Str2);

  if S1 = S2 then
    Exit;

  Stl[0] := Explode('.', S1);
  Stl[1] := Explode('.', S2);

  I := 0;
  if Length(Stl[0]) > Length(Stl[1]) then
  begin
    X := 1;
    Result := csFirst;
  end
  else if Length(Stl[0]) < Length(Stl[1]) then
  begin
    X := 0;
    Result := csSecond;
  end;

  for I := 0 to Length(Stl[X]) -1 do
  begin
    {$IFDEF DEBUG}
      WriteLn('Debug: '+Stl[0][I]+' vs '+Stl[1][I]);
    {$ENDIF}
    if StrToInt(Stl[0][I]) > StrToInt(Stl[1][I]) then
    begin
      Result := csFirst;
      Exit;
    end
    else if StrToInt(Stl[0][I]) < StrToInt(Stl[1][I]) then
    begin
      Result := csSecond;
      Exit;
    end;
  end;
end;

begin
  case CompareVersionStrings('1.0RC1', '1.0a') of
    csFirst: WriteLn('First one');
    csSecond: WriteLn('Second one');
    csEqual: WriteLn('Equal Strings');
  end;
  ReadLn;
end.
Die Aufgabenstellung hier war allerdings bei Strings wie:
Code:
1a
1b
1RC1
1RC2
1.1
1.1.1
1.1.2
1.2
1.2fix
1.2fix2
2a
...
den neusten Finden zu können.

TheMiller 27. Nov 2007 18:28

Re: Versionsnummern vergleichen?
 
Na da habe ich eine schöne Diskussion entfacht. Ich denke, ich werde das doch mit Records machen...

Danke

Progman 27. Nov 2007 18:30

Re: Versionsnummern vergleichen?
 
ja, ist auch zukunftssicherer, wenn man vielleicht irgendwann mal wissen will, ob Programm1 die gleiche Hauptversionsnummer hat aber eine andere Unterversionsnummer als Programm2, kann man das mit der Record-Lösung am einfachsten vergleichen.

TheMiller 27. Nov 2007 18:37

Re: Versionsnummern vergleichen?
 
hm.. ich weiß aber grad nicht, wie ich das mit records löse... Ich steht anscheind auf dem Schlauch... kann mir jemand mal kurz helfen? Es fehlt mir der Ansatz...

Hawkeye219 27. Nov 2007 19:27

Re: Versionsnummern vergleichen?
 
Hi,

ohne Records und auch ziemlich fehlertolerant, aber die Routine sollte ihren Zweck auf Intel-Systemen erfüllen:

Delphi-Quellcode:
function VersionNumberFromString (s: string): Int64;
var
  ErrPos : Integer;
  Index : Integer;
  Parts : packed array [0..3] of Word;
begin
  FillChar (Parts, SizeOf(Parts), 0);
  for Index := 3 downto 0 do
    begin
      Val (s, Parts[Index], ErrPos);
      if (ErrPos = 0) then
        Break;
      Delete (s, 1, ErrPos);
    end;
  Result := Int64(Parts);
end;

// Beispiel für einen Aufruf:
if (VersionNumberFromString('2.0') > VersionNumberFromString('1.5.10.9999')) then
  ShowMessage ('Update verfügbar!');
Gruß Hawkeye


Alle Zeitangaben in WEZ +1. Es ist jetzt 13:48 Uhr.

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