Inno setup: don't show option if it is not checked - inno-setup

After looking at this example Inno Setup: Function to select a component I've added another option to my code but what I'm trying to do (and I don't know if it is possible) is that if in the components section an option hasn't been marked, I don't want it to appear in Page1.Add('help'); or Page1.Add('readme\de');
[Setup]
AppName=My Program
AppVerName=My Program v.1.2
DefaultDirName={pf}\My Program
[Types]
Name: full; Description: Full installation
Name: compact; Description: Compact installation
Name: custom; Description: Custom installation; Flags: iscustom
[Components]
Name: program; Description: Program Files; Types: full compact custom; Flags: fixed
Name: help; Description: Help File; Types: full
Name: readme; Description: Readme File; Types: full
Name: readme\en; Description: English; Flags: exclusive
Name: readme\de; Description: German; Flags: exclusive
[Code]
var
Page1: TInputOptionWizardPage;
Procedure BackupCheckCreate();
var
StaticText: TNewStaticText;
begin
Page1 := CreateInputOptionPage(wpReady, 'Optional Actions Test',
'Which actions should be performed?',
'Please select all optional actions you want to be performed, then click Next.', False, False);
Page1.Add('help');
Page1.Add('readme\de');
Page1.Values[0] := False;
Page1.Values[1] := False;
end;
function ShouldSkipPage(PageID: Integer): Boolean;
begin
Result := (PageID = Page1.ID) and (not IsComponentSelected('help') and not IsComponentSelected('readme\de'));
end;
procedure InitializeWizard();
begin
BackupCheckCreate();
end;

There is no easy way to hide items from TInputOptionWizardPage or generally any custom page at this time. So conditional showing certain check box items on your options page by selected components is not an easy task. So before digging into some hacky ways I would suggest you another way.
From the caption of the page you are creating it looks like you need the [Tasks] section. This section allows you to create additional task check boxes with simple binding to the selected components. Check this example:
[Setup]
AppName=My Program
AppVersion=1.5
DefaultDirName={pf}\My Program
[Types]
Name: full; Description: Full installation
Name: compact; Description: Compact installation
Name: custom; Description: Custom installation; Flags: iscustom
[Components]
Name: main; Description: "Program Files"; Types: full compact custom; Flags: fixed
Name: backup; Description: "Backup DB"; Types: full
Name: restore; Description: "Restore DB"; Types: full
[Tasks]
; if "backup" component is selected, these two tasks appear
Name: backuptask1; Description: "Backup 1"; GroupDescription: "Backup Tasks:"; Components: backup
Name: backuptask2; Description: "Backup 2"; GroupDescription: "Backup Tasks:"; Components: backup
; if "restore" component is selected, these two tasks appear
Name: restoretask1; Description: "Restore 1"; GroupDescription: "Restore Tasks:"; Components: restore
Name: restoretask2; Description: "Restore 2"; GroupDescription: "Restore Tasks:"; Components: restore

Related

Allow restricting and configuring Components for multiple installation Types in Inno Setup

I have two types of installation in the Components section, like these:
The behaviour I'd like to achieve is:
Installation type "Main1 installation", default type, all components checked but "Main2", which must be disabled.
Then if type "Main2 installation" is selected, component "Main1" must be disabled and unchecked and all "Optional" components unchecked but available to be checked.
This is my code by now:
[Types]
Name: "main1"; Description: "Main1 installation"
Name: "main2"; Description: "Main2 installation"; Flags: iscustom
[Components]
Name: "Main1"; Description: "Main 1"; Types: main1
Name: "Main2"; Description: "Main 2"; Types: main2
Name: "Optional1"; Description: "Optional 1"; Types: main1
Name: "Optional2"; Description: "Optional 2"; Types: main1
Name: "Optional3"; Description: "Optional 3"; Types: main1
You cannot do this with Inno Setup Types. There can only be one custom type, not multiple (two in your case). Types also cannot disable the components.
But you can give up on Types and implement a custom type-like drop down.
Though your requirements are not completely defined, so I cannot give you complete solution (Does the component selection reset when type changes? What does happen with type when you customize the components selection? What happens on upgrade? Etc...).
But this should give you some idea:
[Types]
Name: "dummy"; Description: "dummy"; Flags: iscustom
[Components]
Name: "Main1"; Description: "Main 1"
Name: "Main2"; Description: "Main 2"
Name: "Optional1"; Description: "Optional 1"
Name: "Optional2"; Description: "Optional 2"
Name: "Optional3"; Description: "Optional 3"
[Code]
var
MyTypesCombo: TNewComboBox;
procedure MyTypesComboChange(Sender: TObject);
var
I: Integer;
begin
for I := 0 to WizardForm.ComponentsList.Items.Count - 1 do
begin
WizardForm.ComponentsList.ItemEnabled[I] :=
(I = MyTypesCombo.ItemIndex) or (I >= 2);
WizardForm.ComponentsList.Checked[I] :=
(I = MyTypesCombo.ItemIndex) or ((I >= 2) and (MyTypesCombo.ItemIndex = 0));
end;
end;
procedure InitializeWizard();
var
Delta: Integer;
begin
MyTypesCombo := TNewComboBox.Create(WizardForm);
MyTypesCombo.Parent := WizardForm.TypesCombo.Parent;
MyTypesCombo.Left := WizardForm.TypesCombo.Left;
MyTypesCombo.Top := WizardForm.TypesCombo.Top;
MyTypesCombo.Width := WizardForm.TypesCombo.Width;
MyTypesCombo.Height := WizardForm.TypesCombo.Height;
MyTypesCombo.Style := WizardForm.TypesCombo.Style;
MyTypesCombo.Anchors := WizardForm.TypesCombo.Anchors;
MyTypesCombo.TabOrder := WizardForm.TypesCombo.TabOrder;
MyTypesCombo.Items.Add('Main1 installation');
MyTypesCombo.Items.Add('Main2 installation');
MyTypesCombo.OnChange := #MyTypesComboChange;
MyTypesCombo.ItemIndex := 0;
MyTypesComboChange(nil);
WizardForm.IncTopDecHeight(
WizardForm.ComponentsList, MyTypesCombo.Height + ScaleY(3));
end;

Multiple Inno Setup Types that have optional Components

I am trying to create a Inno Setup installer (with Inno Setup 6.2.0) that has multiple setup Types where more than one can have optional Components (as well as fixed components). For example, suppose I want to have the following setup types:
Instructor
Student
If the "Instructor" setup type is selected, I would like to have an "Instructor - Fixed" component (which must be installed), plus two optional components "Instructor- Optional 1" and "Instructor - Optional 2".
Similarly for the "Student" setup type, I would like a fixed component plus a couple of optional components.
Below is the starting point for my experiments:
[Types]
Name: TYPE_INSTRUCTOR ; Description: "Instructor" ;
Name: TYPE_STUDENT ; Description: "Student" ;
[Components]
Name: COMP_INSTRUCTOR ; Description: "Instructor" ; Types: TYPE_INSTRUCTOR
Name: COMP_INSTRUCTOR\FIXED ; Description: "Instructor - Fixed" ; Types: TYPE_INSTRUCTOR ; Flags: fixed
Name: COMP_INSTRUCTOR\OPTIONAL_1 ; Description: "Instructor - Optional 1" ; Types: TYPE_INSTRUCTOR
Name: COMP_INSTRUCTOR\OPTIONAL_2 ; Description: "Instructor - Optional 2" ; Types: TYPE_INSTRUCTOR
Name: COMP_STUDENT ; Description: "Student" ; Types: TYPE_STUDENT
Name: COMP_STUDENT\FIXED ; Description: "Student - Fixed" ; Types: TYPE_STUDENT ; Flags: fixed
Name: COMP_STUDENT\OPTIONAL_1 ; Description: "Student - Optional 1" ; Types: TYPE_STUDENT
Name: COMP_STUDENT\OPTIONAL_2 ; Description: "Student - Optional 2" ; Types: TYPE_STUDENT
[Files]
Source: "InstFixed.txt" ; DestDir: {app} ; Components: COMP_INSTRUCTOR\FIXED
Source: "InstOpt1.txt" ; DestDir: {app} ; Components: COMP_INSTRUCTOR\OPTIONAL_1
Source: "InstOpt2.txt" ; DestDir: {app} ; Components: COMP_INSTRUCTOR\OPTIONAL_2
Source: "StuFixed.txt" ; DestDir: {app} ; Components: COMP_STUDENT\FIXED
Source: "StuOpt1.txt" ; DestDir: {app} ; Components: COMP_STUDENT\OPTIONAL_1
Source: "StuOpt2.txt" ; DestDir: {app} ; Components: COMP_STUDENT\OPTIONAL_2
I have tried a few different things, but nothing has succeeded in achieving what I need. I have tried:
Adding Flags: iscustom to both setup types (my thinking was to indicate that both are customisable). However, Inno Setup only seems to allow for one customisable type.
Making just one of the setup type to have Flags: iscustom (e.g. adding it to TYPE_INSTRUCTOR). However, that does not work as I would like, because I can then end up with invalid combinations, e.g. I can select a mixture of Instructor and Student components.
The only way I can think to get around this is to have setup types for every possible combination. That would not be practical (this example is not my real problem, just a simple case to illustrate it, I would end up with a very large list of setup types).
Thank you in advance for any workable solutions.
That's not possible. At least not without some heavy customization with Pascal Scripting.
Way easier is to drop the Types altogether and use two top-level mutually-exclusive components and couple of optional subcomponents:
[Types]
Name: "custom"; Description: "Custom installation"; Flags: iscustom
[Components]
Name: "intructor"; Description: "Instructor"; Flags: exclusive
Name: "intructor\opt1"; Description: "Optional 1"
Name: "intructor\opt2"; Description: "Optional 2"
Name: "student"; Description: "Student"; Flags: exclusive
Name: "student\opt1"; Description: "Optional 1"
Name: "student\opt2"; Description: "Optional 2"

Prechecked or unchecked components in Inno Setup custom install

I only need 1 custom installation type with 3 components :
The first is needed, so checked and readonly.
The second is optional but part of the default, so checked and writable.
The third is just optional, so unchecked and writable.
If I don't specify a type explicitly, I don't manage to have components checked by default.
If I specify one, I don't manage to have the last component unchecked as default.
I tried with 2 types but, it has no meaning as it's only one custom installation.
Any idea how to get the expected behavior with a single type?
[Types]
Name: "standard"; Description: "Standard installation";
Name: "custom"; Description: "Custom installation"; Flags: iscustom
[Components]
Name: "first"; Description: "First Component"; Types: standard custom; Flags: fixed
Name: "second"; Description: "Second Component"; Types: standard custom;
Name: "third"; Description: "Third Component"; Types: custom;
This should do:
[Types]
Name: "custom"; Description: "Dummy custom installation"; Flags: iscustom
[Components]
Name: "first"; Description: "First Fixed Component"; Types: custom; Flags: fixed
Name: "second"; Description: "Second Checked Component"; Types: custom
Name: "third"; Description: "Third Unchecked Component"

Inno Setup - Correct use of [Types], [Components] and [Tasks]

I am writing a script that requires users to choose which parts of the application to install:
Application only, DataBase Engine only, Data only, or any combination of these.
I know I should be using the [Components] section to define these, but I am getting confused by the interplay between Types, Components and Tasks - for one, I thought [Tasks] was for "extra" installations, but then I saw code that links explicitly the three.
Can anyone point me to a good explanation of how these work together? - I am sure there is one...
Thanks
Components are made of one or more Types. In the script you'll use the Components as selector depending on the Type chosen by the end user. Components can be used in the Tasks because depending on the Types chosen by the user a Task will have or not to be executed.
For example:
; 'Types': What get displayed during the setup
[Types]
Name: "full"; Description: "Full installation";
Name: "app"; Description: "Fapplication only";
Name: "dbengine"; Description: "Database engine only";
Name: "data"; Description: "Data only";
; Components are used inside the script and can be composed of a set of 'Types'
[Components]
Name: "full"; Description: "Full installation"; Types: full app dbengine app
Name: "app"; Description: "Fapplication only"; Types: app
Name: "dbengine"; Description: "Database engine only";Types: dbengine
Name: "data"; Description: "Data only"; Types: data
; Defines which files are setup, based on the differents components
[Files]
Source: "MyApp.exe"; DestDir: "{app}"; Flags: ignoreversion; Components: full app
Source: "ADll.dll"; DestDir: "{app}"; Flags: ignoreversion; Components: full app
Source: "Engine.dll"; DestDir: "{app}"; Flags: ignoreversion; Components: full dbengine
Source: "data_0"; DestDir: "{app}"; Flags: ignoreversion; Components: full data
Source: "data_1"; DestDir: "{app}"; Flags: ignoreversion; Components: full data
; In the same fashion, a task can be set for a specific component
[Tasks]
Name: desktopicon; Description: "Create a &desktop icon"; GroupDescription: "Additional icons:"; Components: full app
My understanding is that a Component is a basically a set of files - it constitutes a major 'component' of what can be installed. A 'type' of installation is a selection of components that it makes sense to install together. Here's the way I would code #az01 's example.
; Lists types of installations - the user is presented
; with a list containing these Descriptions:
[Types]
Name: "full"; Description: "Full installation";
Name: "app-only"; Description: "Application only";
Name: "engine-only"; Description: "Database engine only";
Name: "data-only"; Description: "Data only";
; This lists the installable components of the product and
; specifies which type of install they are included in
[Components]
Name: "app"; Description: "Application"; Types: full app-only
Name: "engine"; Description: "Database engine"; Types: full engine-only
Name: "data"; Description: "Data"; Types: full data-only
; each file is assigned to one component, unless it is shared between
; components, in which case maybe it should go in a 'shared' component.
[Files]
Source: "MyApp.exe"; DestDir: "{app}"; Flags:; Components: app
Source: "ADll.dll"; DestDir: "{app}"; Flags:; Components: app
Source: "Engine.dll"; DestDir: "{app}"; Flags:; Components: engine
Source: "data_0"; DestDir: "{app}"; Flags: ignoreversion; Components: data
Source: "data_1"; DestDir: "{app}"; Flags: ignoreversion; Components: data
A complete explanation can be found on Innosetup help page :
Components and Tasks Parameters
and [Components] section
I give you below a generic sample :
[Components]
Name: a; Description: a
Name: b; Description: b
[Tasks]
Name: p; Description: a or b; Components: a or b
Name: q; Description: a and b; Components: a and b
Name: r; Description: not a or b; Components: not a or b
Name: s; Description: not (a or b); Components: not (a or b)
Name: t; Description: a or b - old style; Components: a b

Inno-setup: Store all user's choices in an INI file

I would like to store all the choices made by a user (or the default values, if the user did not change them) during installation in an .INI file. I know about the command-line option /LOADINF and /SAVEINF, but I would like to have a similar capability without depending on the command line. This would be used to keep settings in case of re-installation, but also to define a set of settings (that are defined by an administrator) to be used in multiple installations accross decentralized offices.
Thanks for the help
It is possible to do what you are looking for. You'll need a fair amount of code in your [code] section though. I did something similar a number of years ago but I was only reading the INI. I never wrote to the INI file. you should be able to write to it using SetIni* (SetIniString, SetIniBool, etc.) functions. You can read the INI file using GetIni* functions. Here's a quick sample I threw together that gives an idea:
; Script generated by the Inno Setup Script Wizard.
; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES!
#define MyAppName "My Program"
#define MyAppVersion "1.5"
#define MyAppPublisher "My Company, Inc."
#define MyAppURL "http://www.example.com/"
#define MyAppExeName "MyProg.exe"
[Setup]
; NOTE: The value of AppId uniquely identifies this application.
; Do not use the same AppId value in installers for other applications.
; (To generate a new GUID, click Tools | Generate GUID inside the IDE.)
AppId={{4CCA332F-C69B-48DF-93B4-145EB88A1BCB}
AppName={#MyAppName}
AppVersion={#MyAppVersion}
;AppVerName={#MyAppName} {#MyAppVersion}
AppPublisher={#MyAppPublisher}
AppPublisherURL={#MyAppURL}
AppSupportURL={#MyAppURL}
AppUpdatesURL={#MyAppURL}
DefaultDirName={code:GetDefaultDir}
DefaultGroupName={#MyAppName}
OutputBaseFilename=setup
Compression=lzma
SolidCompression=yes
[Languages]
Name: "english"; MessagesFile: "compiler:Default.isl"
[Tasks]
Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked
[Files]
Source: "C:\util\innosetup\Examples\MyProg.exe"; DestDir: "{app}"; Flags: ignoreversion
; NOTE: Don't use "Flags: ignoreversion" on any shared system files
[Icons]
Name: "{group}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"
Name: "{commondesktop}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; Tasks: desktopicon
[Run]
Filename: "{app}\{#MyAppExeName}"; Description: "{cm:LaunchProgram,{#StringChange(MyAppName, "&", "&&")}}"; Flags: nowait postinstall skipifsilent
[Code]
var
FinishedInstall : boolean;
function GetDefaultDir(def: string): string;
var
sInstallPath : string;
bRes : boolean;
begin
sInstallPath := GetIniString('Common', 'TargetDir', ExpandConstant('{pf}') + '\myApp', ExpandConstant('{src}') + '\myappsetup.INI');
Result := sInstallPath;
end;
procedure CurStepChanged(CurStep: TSetupStep);
begin
if CurStep = ssPostInstall then
FinishedInstall := True;
end;
procedure DeinitializeSetup();
var
bIni : boolean;
begin
if FinishedInstall then
bIni := SetIniString('Common', 'TargetDir',ExpandConstant('{app}'), ExpandConstant('{app}') + '\myappsetup.INI');
end;

Resources