2009-07-08 15 views
1

Ich möchte ein Setup-Paket für die bedingte Aktualisierung eines vorhandenen Pakets entwickeln. Ich möchte die vorhandene Softwareversion auf die zu installierende Version überprüfen. Um dies zu tun, muss ich die Versionszeichenfolgen vergleichen.Wie konvertiert man einen String-Versionswert in Inno-Setup-Skripte in einen numerischen Wert?

Wie kann ich den String-Wert in einem Inno-Setup-Skript in einen numerischen Wert konvertieren?

RegQueryStringValue(HKEY_LOCAL_MACHINE, 'Software\Blah blah', 'Version', version) 
version = 'V1.R2.12'; 
numVersion := ??string_to_numerical_value??(version); 
+0

Ist die letzte Nummer (.12) für den Vergleich relevant? Angenommen, "R" steht für "release", dann hätten Sie nur eine Build-Nummer. Wenn Sie also einen festen Release-Prozess haben, können Sie ihn ignorieren. – Treb

Antwort

4

Dies ist ein wenig komplizierter, da Sie Versionen wie 'V1.R2.12' und 'V0.R15.42' korrekt behandeln möchten - mit der einfachen Konvertierung in der anderen Antwort würden Sie 1212 und 1542 erhalten , die nicht so vergleichbar wären, wie Sie es erwarten würden.

Sie müssen entscheiden, wie groß jeder Teil der Versionsnummer sein kann, und multiplizieren Sie die Teile mit diesem Wert, um eine korrekte Endnummer zu erhalten. Etwas wie folgt aus:

[Code] 
function string_to_numerical_value(AString: string; AMaxVersion: LongWord): LongWord; 
var 
    InsidePart: boolean; 
    NewPart: LongWord; 
    CharIndex: integer; 
    c: char; 
begin 
    Result := 0; 
    InsidePart := FALSE; 
    // this assumes decimal version numbers !!! 
    for CharIndex := 1 to Length(AString) do begin 
    c := AString[CharIndex]; 
    if (c >= '0') and (c <= '9') then begin 
     // new digit found 
     if not InsidePart then begin 
     Result := Result * AMaxVersion + NewPart; 
     NewPart := 0; 
     InsidePart := TRUE; 
     end; 
     NewPart := NewPart * 10 + Ord(c) - Ord('0'); 
    end else 
     InsidePart := FALSE; 
    end; 
    // if last char was a digit the last part hasn't been added yet 
    if InsidePart then 
    Result := Result * AMaxVersion + NewPart; 
end; 

Sie können dies testen mit dem folgenden Code:

function InitializeSetup(): Boolean; 
begin 
    if string_to_numerical_value('V1.R2.12', 1) < string_to_numerical_value('V0.R15.42', 1) then 
    MsgBox('Version ''V1.R2.12'' is not as recent as version ''V0.R15.42'' (false)', mbConfirmation, MB_OK); 
    if string_to_numerical_value('V1.R2.12', 100) > string_to_numerical_value('V0.R15.42', 100) then 
    MsgBox('Version ''V1.R2.12'' is more recent than version ''V0.R15.42'' (true)', mbConfirmation, MB_OK); 
    Result := FALSE; 
end; 

Ob 10, 100 oder 1000 für AMaxVersion passieren, hängt von der Anzahl und Reichweite Ihrer Versionsnummer Teile. Beachten Sie, dass Sie die Ergebnisvariable LongWord, die einen maximalen Wert von 2^32-1 hat, nicht überlaufen lassen dürfen.

0

Ich habe nicht versucht, dass (und meine Pascal Wissen ist ein bisschen rostig), aber so etwas wie die folgenden funktionieren sollte:

function NumericVersion(s: String): Integer; 
var 
    i: Integer; 
    s1: String; 
begin 
    s1 := ''; 
    for i := 0 to Length(s)-1 do 
    if (s[i] >= '0') and (s[i] <= '9') then 
     s1 := s1 + s[i]; 

    Result := StrToIntDef(s1, 0); 
end; 

Bitte nicht, dass Sie mit dem spielen müssen werde Anfangs- und Endwert für i, da ich nicht sicher bin, ob es auf Null basiert oder nicht (s[0] kann die Länge des Strings enthalten, wenn es sich um einen "Pascal String" handelt).

+0

Pascal-Strings sind einbasig, aber selbst wenn dies behoben ist, wird Ihre Lösung bei Eckenfehlern fehlschlagen - siehe meine Antwort. – mghie

+0

Sie haben natürlich Recht - ich wollte nur das OP in die richtige Richtung weisen. Ich habe nicht erwartet, dass meine Lösung das Problem vollständig löst ;-) Sie erhalten von mir eine Erwiderung für Ihre Antwort. –

0

Ich habe zwei Versionszeichenfolgen (tatsächlich eine Zeichenfolge und ein DWORD-Wert) in der Registrierung implementiert, um die Komplexität zu überwinden.

displayversion="v1.r1.0" 
version="10100" (=1*10^4 + 1*10^2 + 0*10^0) 

Das ist einfach. Dies ist zwar keine Antwort auf diese Frage, jedoch könnte man anders denken, wenn man mit Komplexität konfrontiert wird, die auf einfachere Weise vermieden werden könnte.

Verwandte Themen