2009-07-08 6 views
1

Je souhaite développer un package d'installation pour la mise à niveau conditionnelle d'un package existant. Je veux vérifier la version du logiciel existante par rapport à la version à installer. Pour ce faire, je dois comparer les chaînes de version. Comment puis-je convertir la valeur de chaîne en valeur numérique dans un script de configuration Inno?Comment convertir une valeur de version de chaîne en valeur numérique dans Inno Setup Scripts?

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

Le dernier nombre (0,12) est-il pertinent pour la comparaison? En supposant que 'R' soit synonyme de version, vous n'auriez qu'un seul numéro de build associé, donc si vous avez un processus de publication solide, vous pouvez l'ignorer. – Treb

Répondre

4

Ceci est un peu plus compliqué, car vous voudriez gérer des versions comme 'V1.R2.12' et 'V0.R15.42' correctement - avec la conversion simple dans l'autre réponse vous obtiendriez 1212 et 1542 , qui ne serait pas comparable à la façon dont vous vous attendriez.

Vous devez déterminer la taille de chaque partie du numéro de version et multiplier les parties par cette valeur pour obtenir un numéro de fin correct. Quelque chose comme ceci:

[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; 

Vous pouvez tester cela avec le code suivant:

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; 

Que vous passez 10, 100 ou 1000 pour AMaxVersion dépend du nombre et la portée de vos pièces de numéro de version. Notez que vous ne devez pas déborder la variable résultat LongWord, qui a une valeur maximale de 2^32 - 1.

0

Je n'ai pas essayé (et ma connaissance Pascal est un peu rouillé), mais quelque chose comme ce qui suit devrait fonctionner:

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; 

S'il vous plaît pas que vous aurez à jouer avec le la valeur de début et de fin pour i car je ne suis pas sûr si elle est basée sur zéro ou non (s[0] peut contenir la longueur de la chaîne s'il s'agit d'une "chaîne Pascal").

+0

Les chaînes de Pascal sont basées sur un seul, mais même avec ce corrigé votre solution échouera pour les cas de coin - voir ma réponse. – mghie

+0

Vous avez bien sûr raison - je voulais juste pointer l'OP dans la bonne direction. Je ne m'attendais pas à ce que ma solution gère entièrement le problème ;-) Vous obtiendrez un upvote pour votre réponse de ma part. –

0

J'ai implémenté deux chaînes de version (en fait une chaîne et une valeur dword) dans le registre pour surmonter la complexité.

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

C'est simple. Bien que n'étant pas une réponse à cette question, cependant on pourrait penser l'inverse en face de la complexité, ce qui pourrait être évité d'une manière plus simple.

Questions connexes