Inno Setup: 检查新更新

6
阅读完这篇文章如何从互联网资源中读取文本文件?后,我已经根据自己的需求调整了代码,但是还存在一些问题。
我的目标是在运行设置时检查新的更新。1)如果没有新的更新,则不显示任何消息。2)如果有新的更新,则显示一个消息询问是否要下载它。
以下是我的代码:
procedure InitializeWizard;
var
  DxLastVersion: string;
  DxSetupVersion: String;

begin
  if DownloadFile('http://dex.wotanksmods.com/latestver.txt', DxLastVersion)  then
    MsgBox(DxLastVersion, mbInformation, MB_YESNO)
  else
    MsgBox(DxLastVersion, mbError, MB_OK)
end;

非常感谢您提前的帮助。

如果您将版本号存储为单个整数值,比较就会变得更加容易。这样,比较只需要一行代码,而常见的版本模式“x.x.x”需要解析和比较每个值。那就不止一行了。 - TLama
我对设置进行了修改,通常是一些小的修改,因此我通常需要有2.3这样的版本。两个数值就足够了。你能帮我吗?我已经在这个问题上工作了几天,但我无法解决它。非常感谢。 - DeXon
1
你可以将数字$00020003(或131075)表示为版本2.3。 - Miral
我一直在检查我的代码,认为按照@TLama所说的简单方式(将版本号作为单个整数值)会更容易。但是我仍然无法做到。有人可以帮助我吗?提前感谢。 - DeXon
1个回答

11

既然您决定使用通用的版本字符串模式,那么您需要一个函数来解析和比较安装程序中的版本字符串和从您网站下载的版本字符串。由于Inno Setup中没有内置这样的函数,因此您需要自己编写一个。

我看到了一些比较版本字符串的函数,例如在this script中使用的函数,但我决定编写自己的函数。它可以检测无效的版本字符串,并将缺少的版本块视为0,这会导致像以下这样的版本字符串的比较是相等的:

1.2.3
1.2.3.0.0.0

以下脚本可能实现你想要的功能(设置版本由AppVersion指令定义):


[Setup]
AppName=My Program
AppVersion=1.2.3
DefaultDirName={pf}\My Program

[Code]
const
  SetupURL = 'http://dex.wotanksmods.com/setup.exe';
  VersionURL = 'http://dex.wotanksmods.com/latestver.txt';

type
  TIntegerArray = array of Integer;
  TCompareResult = (
    crLesser,
    crEquals,
    crGreater
  );

function Max(A, B: Integer): Integer;
begin
  if A > B then Result := A else Result := B;
end;

function CompareValue(A, B: Integer): TCompareResult;
begin
  if A = B then
    Result := crEquals
  else
  if A < B then
    Result := crLesser
  else
    Result := crGreater;
end;

function AddVersionChunk(const S: string; var A: TIntegerArray): Integer;
var
  Chunk: Integer;
begin
  Chunk := StrToIntDef(S, -1);
  if Chunk <> -1 then
  begin
    Result := GetArrayLength(A) + 1;
    SetArrayLength(A, Result);
    A[Result - 1] := Chunk;
  end
  else
    RaiseException('Invalid format of version string');
end;

function ParseVersionStr(const S: string; var A: TIntegerArray): Integer;
var
  I: Integer;
  Count: Integer;
  Index: Integer;
begin
  Count := 0;
  Index := 1;

  for I := 1 to Length(S) do
  begin
    case S[I] of
      '.':
      begin
        AddVersionChunk(Copy(S, Index, Count), A);
        Count := 0;
        Index := I + 1;
      end;
      '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
      begin
        Count := Count + 1;
      end;
    else
      RaiseException('Invalid char in version string');
    end;
  end;
  Result := AddVersionChunk(Copy(S, Index, Count), A);
end;

function GetVersionValue(const A: TIntegerArray; Index,
  Length: Integer): Integer;
begin
  Result := 0;
  if (Index >= 0) and (Index < Length) then
    Result := A[Index];
end;

function CompareVersionStr(const A, B: string): TCompareResult;
var
  I: Integer;
  VerLenA, VerLenB: Integer;
  VerIntA, VerIntB: TIntegerArray;
begin
  Result := crEquals;

  VerLenA := ParseVersionStr(A, VerIntA);
  VerLenB := ParseVersionStr(B, VerIntB);

  for I := 0 to Max(VerLenA, VerLenB) - 1 do
  begin
    Result := CompareValue(GetVersionValue(VerIntA, I, VerLenA),
      GetVersionValue(VerIntB, I, VerLenB));
    if Result <> crEquals then
      Exit;
  end;
end;

function DownloadFile(const URL: string; var Response: string): Boolean;
var
  WinHttpRequest: Variant;
begin
  Result := True;
  try
    WinHttpRequest := CreateOleObject('WinHttp.WinHttpRequest.5.1');
    WinHttpRequest.Open('GET', URL, False);
    WinHttpRequest.Send;
    Response := WinHttpRequest.ResponseText;
  except
    Result := False;
    Response := GetExceptionMessage;
  end;
end;

function InitializeSetup: Boolean;
var
  ErrorCode: Integer;
  SetupVersion: string;
  LatestVersion: string;
begin
  Result := True;

  if DownloadFile(VersionURL, LatestVersion) then
  begin
    SetupVersion := '{#SetupSetting('AppVersion')}';
    if CompareVersionStr(LatestVersion, SetupVersion) = crGreater then
    begin
      if MsgBox('There is a newer version of this setup available. Do ' +
        'you want to visit the site ?', mbConfirmation, MB_YESNO) = IDYES then
      begin
        Result := not ShellExec('', SetupURL, '', '', SW_SHOW, ewNoWait,
          ErrorCode);
      end;
    end;
  end;
end;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接