Search code examples
inno-setuppascalscript

How do you prompt a user to read a guide and restart/log off from their computer on the finished page using Inno Setup?


I am building an installer and would like to ask the user to restart using a radio button. I would also like to include an option to open the user guide if the user selects "No, I will restart later". My current method for asking the user to open the user guide is putting it in the [Run] section like this:

[Run]
Filename: "{app}\userguide.pdf"; Description: "View the User Guide"; Flags: shellexec runasoriginaluser postinstall nowait unchecked

This works perfectly, it even opens in the default PDF viewer. However, whenever I try to include a restart option, it overrides the user guide option and completely removes it. So, trying:

[Code]
function NeedRestart(): Boolean;
begin
    Result := True;
end;

as well as:

[Setup]
AlwaysRestart=yes

work in the sense that they include an option for restart but they also override the user guide button. Is there a way to make a custom page that, upon checking the "No I will restart later" radio button, will show an option on opening the user guide? I am not too familiar with using Inno Setup and Delphi/Pascal.


Solution

  • You have to code that. For example you can add your own checkbox for starting the user guide:

    [Setup]
    AlwaysRestart=yes
    
    [Files]
    Source: "userguide.pdf"; DestDir: "{app}"
    
    [Code]
    
    var
      LaunchCheckbox: TCheckbox;
    
    procedure YesNoRadioClicked(Sender: TObject);
    begin
      // Disable the user guide checkbox when "restart" is selected
      LaunchCheckbox.Enabled := WizardForm.NoRadio.Checked;
    end;
    
    procedure InitializeWizard();
    begin
      LaunchCheckbox := TCheckbox.Create(WizardForm.FinishedPage);
      LaunchCheckbox.Caption := 'View the User Guide';
      LaunchCheckbox.Checked := False;
      LaunchCheckbox.Left := WizardForm.YesRadio.Left;
      LaunchCheckbox.Width := WizardForm.YesRadio.Width;
      LaunchCheckbox.Height := ScaleY(LaunchCheckbox.Height);
      LaunchCheckbox.Parent := WizardForm.FinishedPage;
      if (WizardForm.YesRadio.OnClick <> nil) or (WizardForm.NoRadio.OnClick <> nil) then
      begin
        Log('Restart radio button event handler unexpectedly set');
      end
        else
      begin
        WizardForm.YesRadio.OnClick := @YesNoRadioClicked;
        WizardForm.NoRadio.OnClick := @YesNoRadioClicked;
      end;
    end;
    
    procedure CurPageChanged(CurPageID: Integer);
    begin
      if CurPageID = wpFinished then
      begin
        // Adjust to the initial start of restart selection
        YesNoRadioClicked(nil);
        // Only now the restart radio buttons have their definitive vertical position
        LaunchCheckbox.Top :=
          WizardForm.NoRadio.Top + WizardForm.NoRadio.Height + ScaleY(16);
      end;
    end;
    
    procedure CurStepChanged(CurStep: TSetupStep);
    var
      ErrorCode: Integer;
    begin
      if CurStep = ssDone then
      begin
        if (not WizardSilent) and
           (not WizardForm.YesRadio.Checked) and
           LaunchCheckbox.Checked then
        begin
          Log('Opening user guide');
          ShellExecAsOriginalUser(
            'open', ExpandConstant('{app}\userguide.pdf'), '', '', SW_SHOWNORMAL, 
            ewNoWait, ErrorCode);
        end;
      end;
    end;
    

    enter image description here


    The code assumes AlwaysRestart. Were the restart conditional, the code will need an update to adjust to a different layout of the Finished page, when restart is not needed. For a full solution see my installer for WinSCP:
    https://github.com/winscp/winscp/blob/master/deployment/winscpsetup.iss