I want to program an installer that will install certain programs by selecting a user. Every user has defined assignments which program should be installed. For now, you have to use the components section to configure the programs. But my goal is to configure it with a text file. Example for text file could be like:
User1 User2 User3 User4
Program 1 x x x x
Program 2 x x
Program 3 x x
Here is my code:
[Types]
Name: "User1"; Description: "User 1"
Name: "User2"; Description: "User 2"
Name: "User3"; Description: "User 3"
Name: "User4"; Description: "User 4"
Name: "Custom"; Description: "Custom"
Name: "Random"; Description:"Random"; Flags: iscustom
[Components]
Name: "Select"; Description: "Alle auswählen:"; Types: User1 User2 User3 User4
Name: "Select\Program_1"; Description: "Program_1"; Types: User1 User2 User3 User4
Name: "Select\Program_2"; Description: "Program_2"; Types: User2 User4
Name: "Select\Program_3"; Description: "Program_3"; Types: User1 User3
[Files]
Source: "TEST \Software\x64\Program_1"; DestDir: "{app}\Program_1"; \
Flags: ignoreversion recursesubdirs; Components: Select\Program_1;
Source: "TEST \Software\x64\Program_2"; DestDir: "{app}\Program_2"; \
Flags: ignoreversion recursesubdirs; Components: Select\Program_2;
Source: "TEST \Software\x64\Program_3"; DestDir: "{app}\Program_3"; \
Flags: ignoreversion recursesubdirs; Components: Select\Program_3;
[Code]
var
TypesPage: TWizardPage;
User1_Button: TNewRadioButton;
User2_Button: TNewRadioButton;
User4_Button: TNewRadioButton;
User3_Button: TNewRadioButton;
Custom_Button: TNewRadioButton;
procedure InitializeWizard();
begin
{ Create custom "types" page }
TypesPage := CreateInputOptionPage(wpSelectDir,
'Select User', '' ,
'Please select the right User',true,false);
User1_Button := TNewRadioButton.Create(TypesPage);
User1_Button.Parent := TypesPage.Surface;
User1_Button.Caption := 'User 1';
User1_Button.Top := 50;
User1_Button.Height := ScaleY(User1_Button.Height);
User1_Button.Checked := (WizardForm.TypesCombo.ItemIndex = 0);
User2_Button := TNewRadioButton.Create(TypesPage);
User2_Button.Parent := TypesPage.Surface;
User2_Button.Caption := 'User 2';
User2_Button.Height := ScaleY(User2_Button.Height);
User2_Button.Top := User1_Button.Top + User1_Button.Height + ScaleY(16);
User2_Button.Checked := (WizardForm.TypesCombo.ItemIndex = 1);
User3_Button := TNewRadioButton.Create(TypesPage);
User3_Button.Parent := TypesPage.Surface;
User3_Button.Caption := 'User 3';
User3_Button.Height := ScaleY(User3_Button.Height);
User3_Button.Top := User2_Button.Top + User2_Button.Height + ScaleY(16);
User3_Button.Checked := (WizardForm.TypesCombo.ItemIndex = 2);
User 4_Button := TNewRadioButton.Create(TypesPage);
User 4_Button.Parent := TypesPage.Surface;
User 4_Button.Caption := 'User 4';
User 4_Button.Height := ScaleY(User4_Button.Height);
User 4_Button.Top := User3_Button.Top + User3_Button.Height + ScaleY(16);
User 4_Button.Checked := (WizardForm.TypesCombo.ItemIndex = 3);
Custom_Button := TNewRadioButton.Create(TypesPage);
Custom_Button.Parent := TypesPage.Surface;
Custom_Button.Caption := 'Custom';
Custom_Button.width := 200;
Custom_Button.Height := ScaleY(Custom_Button.Height);
Custom_Button.Top := User4_Button.Top + User4_Button.Height + ScaleY(16);
Custom_Button.Checked := (WizardForm.TypesCombo.ItemIndex = 4);
WizardForm.TypesCombo.Visible := False; { Dropdown List removed }
WizardForm.IncTopDecHeight(WizardForm.ComponentsList,
-(WizardForm.ComponentsList.Top-WizardForm.TypesCombo.Top));
end;
function NextButtonClick(CurPageID: Integer): Boolean;
begin
if CurPageID = TypesPage.ID then
begin
if User1_Button.Checked then WizardForm.TypesCombo.ItemIndex :=0
else
if User2_Button.Checked then WizardForm.TypesCombo.ItemIndex := 1
else
if User3_Button.Checked then WizardForm.TypesCombo.ItemIndex := 2
else
if User4_Button.Checked then WizardForm.TypesCombo.ItemIndex := 3
else
if Custom_Button.Checked then WizardForm.TypesCombo.ItemIndex := 4;
WizardForm.TypesCombo.OnChange(WizardForm.TypesCombo);
end;
Result:= true;
end;
As you do not seem to care about the configuration file format, let's pick INI file, as Inno Setup has functions to parse it:
[Users]
user1=Program1,Program3
user2=Program1,Program2
user3=Program1,Program3
user4=Program1,Program2
Then the following script will do:
[Types]
Name: "user1"; Description: "User 1"
Name: "user2"; Description: "User 2"
Name: "user3"; Description: "User 3"
Name: "user4"; Description: "User 4"
[Files]
Source: "TEST \Software\x64\Program_1"; DestDir: "{app}\Program_1"; \
Flags: ignoreversion recursesubdirs; Check: ShouldInstallProgram('Program1')
Source: "TEST \Software\x64\Program_2"; DestDir: "{app}\Program_2"; \
Flags: ignoreversion recursesubdirs; Check: ShouldInstallProgram('Program2')
Source: "TEST \Software\x64\Program_3"; DestDir: "{app}\Program_3"; \
Flags: ignoreversion recursesubdirs; Check: ShouldInstallProgram('Program3')
[Code]
function ShouldInstallProgram(ProgramName: string): Boolean;
var
UserName: string;
ProgramsStr: string;
Programs: TStringList;
begin
UserName := WizardSetupType(False);
ProgramsStr :=
GetIniString('Users', UserName, '', ExpandConstant('{src}\UserPrograms.ini'));
Programs := TStringList.Create;
Programs.CommaText := ProgramsStr;
Result := (Programs.IndexOf(ProgramName) >= 0);
Programs.Free;
end;
Type names must be lowercase for this to work. And casing of program names matter.
As the code now actually does not use the [Types]
at all, you can replace the WizardSetupType
with direct check to your custom page selection. And you can remove the redundant [Types]
section and your NextButtonClick
event function.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.