Come convertire un valore versione stringa in un valore numerico in script di installazione Inno?

StackOverflow https://stackoverflow.com/questions/1097462

Domanda

voglio sviluppare un pacchetto di installazione per la condizionale l'aggiornamento di un pacchetto esistente. Voglio controllare la versione del software esistente con la versione a-essere-installato. Per fare questo, devo confrontare le stringhe di versione.

Come posso convertire il valore stringa in un valore numerico in uno script Inno Setup?

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

Soluzione

Questo è un po 'più difficile, come si vorrebbe gestire versioni come 'V1.R2.12' e 'V0.R15.42' correttamente - con la semplice conversione in altra risposta che si otterrebbe il 1212 e il 1542, che non sarebbe confrontare il modo in cui ci si aspetterebbe.

È necessario decidere quanto grande ogni parte del numero di versione può essere, e moltiplicare le parti da tale valore per ottenere un numero finale corretta. Qualcosa di simile a questo:

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

È possibile verificare questo con il seguente codice:

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;

Se si passa a 10, 100 o 1000 per AMaxVersion dipende dal numero e la gamma della versione parti numerici. Si noti che non è necessario traboccare variabile di risultato LongWord, che ha un valore massimo di 2 ^ 32 -. 1

Altri suggerimenti

Non ho provato (e la mia conoscenza Pascal è un po 'arrugginito), ma qualcosa di simile alla seguente dovrebbe funzionare:

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;

Si prega di non che dovrete giocare con il valore di inizio e di fine i come io non sono sicuro se è a base zero oppure no (s[0] può contenere la lunghezza della stringa, se si tratta di un "Pascal String ").

Ho implementato due stringhe di versione (in realtà una stringa e un valore DWORD) nel Registro di sistema per superare la complessità.

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

E 'semplice. Anche se non una risposta a questa domanda, ma si potrebbe pensare il contrario di fronte alla complessità, che potrebbero essere evitati in modo più semplice.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top