2

既存のパッケージを条件付きでアップグレードするためのセットアップ パッケージを開発したいと考えています。インストール予定のバージョンに対して既存のソフトウェアのバージョンを確認したい。そのためには、バージョン文字列を比較する必要があります。

Innoセットアップスクリプトで文字列値を数値に変換するにはどうすればよいですか?

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

3 に答える 3

4

'V1.R2.12'や'V0.R15.42'のようなバージョンを正しく処理したいので、これはもう少しトリッキーです-他の答えの単純な変換では、1212と1542が得られますが、そうではありませんあなたが期待する方法を比較してください。

バージョン番号の各部分の大きさを決定し、その部分にその値を掛けて、正しい終了番号を取得する必要があります。このようなもの:

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

次のコードでこれをテストできます。

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;

10、100、または1000に合格するかどうかAMaxVersionは、バージョン番号のパーツの数と範囲によって異なります。LongWord最大値が2^32-1である結果変数をオーバーフローさせてはならないことに注意してください。

于 2009-07-08T19:24:57.940 に答える
1

私はそれを試していません (そして私の Pascal の知識は少しさびています) が、次のようなものがうまくいくはずです:

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;

iゼロベースかどうかわからないため、開始値と終了値をいじる必要があることに注意してください( s[0]「パスカル文字列」の場合、文字列の長さが含まれる場合があります)。

于 2009-07-08T12:59:58.790 に答える
0

複雑さを克服するために、レジストリに2つのバージョン文字列(実際には1つの文字列と1つのdword値)を実装しました。

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

それは簡単です。この質問に対する答えではありませんが、複雑さに直面したときに逆のことを考えるかもしれません。これは、より簡単な方法で回避できます。

于 2009-07-13T08:39:59.813 に答える