Inno设置:检查新的更新

时间:2014-03-08 12:09:01

标签: inno-setup

阅读完这篇文章How to read a text file from the Internet resource?之后,我已根据我的需要调整了代码,但我遇到了一些问题。

我想要做的是,当我运行设置时,它会检查新的更新。 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;

非常感谢先进。

1 个答案:

答案 0 :(得分:9)

由于您决定使用通用版本字符串模式,因此您需要一个功能来解析和比较您的设置的版本字符串和从您的网站下载的版本字符串。而且因为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;