Inno Setup:安装.NET framework,重启系统并继续安装

Inno Setup: Install .NET framework, reboot the system and continue installation

我需要安装一些系统先决条件,并在完成它们后重新启动系统,然后它必须从我停止的地方继续安装。先决条件是 .NET 框架和 Windows.

的更新

我的 [Code] 部分:

const
  (*** Customize the following to your own name. ***)
  RunOnceName = 'My Program Setup restart';

  QuitMessageReboot = 'Os requisitos para a instalação do sistema não estão completos. Precisamos reiniciar seu computador para continuar a instalação do sistema.'#13#13'Depois de reiniciar o seu computador, o setup irá continuar a instalação após o primeiro login com uma conta administradora.';
  QuitMessageError = 'Error. Cannot continue.';

var
  Restarted: Boolean;
  ResultCode: Integer;

function InitializeSetup(): Boolean;
begin
  Restarted := ExpandConstant('{param:restart|0}') = '1';

  if not Restarted then begin
    Result := not RegValueExists(HKLM, 'Software\Microsoft\Windows\CurrentVersion\RunOnce', RunOnceName);
    if not Result then
      MsgBox(QuitMessageReboot, mbError, mb_Ok);
  end else
    Result := True;
end;

function DetectAndInstallPrerequisites: Boolean;
begin
  (*** Place your prerequisite detection and installation code below. ***)
  (*** Return False if missing prerequisites were detected but their installation failed, else return True. ***)

  if not Exec(ExpandConstant('{tmp}\dotNetFx40_Full_x86_x64.exe'), '/q /norestart', '', SW_SHOW, ewWaitUntilTerminated, ResultCode) then
  begin
    MsgBox(QuitMessageReboot + IntToStr(ResultCode) + '....',
      mbError, MB_OK);    
  end;

  Result := True;
end;

function Quote(const S: String): String;
begin
  Result := '"' + S + '"';
end;

function AddParam(const S, P, V: String): String;
begin
  if V <> '""' then
    Result := S + ' /' + P + '=' + V;
end;

function AddSimpleParam(const S, P: String): String;
begin
 Result := S + ' /' + P;
end;

procedure CreateRunOnceEntry;
var
  RunOnceData: String;
begin
  RunOnceData := Quote(ExpandConstant('{srcexe}')) + ' /restart=1';
  RunOnceData := AddParam(RunOnceData, 'LANG', ExpandConstant('{language}'));
  RunOnceData := AddParam(RunOnceData, 'DIR', Quote(WizardDirValue));
  RunOnceData := AddParam(RunOnceData, 'GROUP', Quote(WizardGroupValue));
  if WizardNoIcons then
    RunOnceData := AddSimpleParam(RunOnceData, 'NOICONS');
  RunOnceData := AddParam(RunOnceData, 'TYPE', Quote(WizardSetupType(False)));
  RunOnceData := AddParam(RunOnceData, 'COMPONENTS', Quote(WizardSelectedComponents(False)));
  RunOnceData := AddParam(RunOnceData, 'TASKS', Quote(WizardSelectedTasks(False)));

  (*** Place any custom user selection you want to remember below. ***)

  //<your code here>

  RegWriteStringValue(HKLM, 'Software\Microsoft\Windows\CurrentVersion\RunOnce', RunOnceName, RunOnceData);
end;

function PrepareToInstall(var NeedsRestart: Boolean): String;
var
  ChecksumBefore, ChecksumAfter: String;
begin
  ChecksumBefore := MakePendingFileRenameOperationsChecksum;
  if DetectAndInstallPrerequisites then begin
    ChecksumAfter := MakePendingFileRenameOperationsChecksum;
    if ChecksumBefore <> ChecksumAfter then begin
      CreateRunOnceEntry;
      NeedsRestart := True;
      Result := QuitMessageReboot;
    end;
  end else
    Result := QuitMessageError;
end;

function ShouldSkipPage(PageID: Integer): Boolean;
begin
  Result := Restarted;
end;

return 是变量 QuitMessageReboot 与具有值 2.

ResultCode 连接

dotNetFx40_Full_x86_x64.exe 安装者:

[Files]
;.Net Framework
Source: "Dependencias\.Net Framework\dotNetFx40_Full_x86_x64.exe"; DestDir: "{tmp}"; \
    Flags: deleteafterinstall

顾名思义,PrepareToInstall event 发生在安装之前。这些文件尚未安装。所以 Exec 显然失败了,因为没有什么可执行的。

您可以使用 ExtractTemporaryFile function:

从代码中提取 dotNetFx40_Full_x86_x64.exe
[Files]
Source: "...\dotNetFx40_Full_x86_x64.exe"; Flags: dontcopy

[Code]
function DetectAndInstallPrerequisites: Boolean;
var
  ResultCode: Integer;
  Success: Boolean;
begin
  ExtractTemporaryFile('dotNetFx40_Full_x86_x64.exe');

  WizardForm.PreparingLabel.Caption := 'Installing .NET framework...';
  WizardForm.PreparingLabel.Visible := True;
  try
    Success :=
      Exec(
        ExpandConstant('{tmp}\dotNetFx40_Full_x86_x64.exe'), '/q /norestart', '',
        SW_SHOW, ewWaitUntilTerminated, ResultCode);
  finally
    WizardForm.PreparingLabel.Caption := '';
    WizardForm.PreparingLabel.Visible := False;
  end;

  if not Success then
  ...
end;

确保将 dontcopy flag 添加到 [Files] 部分条目。