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;