Inno setup: check for new updates

Since you've decided to use a common version string pattern, you'll need a function which will parse and compare a version string of your setup and the one downloaded from your site. And because there is no such function built-in in Inno Setup, you'll need to have your own one.

I've seen a few functions for comparing version strings, like e.g. the one used in this script, but I've decided to write my own. It can detect an invalid version string, and treats the missing version chunks as to be 0, which causes comparison of version strings like follows to be equal:

1.2.3
1.2.3.0.0.0

 

The following script might do what you want (the setup version is defined by the AppVersion directive):

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

 

posted on 2019-03-12 17:03  liujx2019  阅读(403)  评论(0编辑  收藏  举报

导航