Inno Setup - Define Disk Space by component

2019-04-15 19:01发布

问题:

By default, on the components page, Inno Setup adds the size of all the files inside to the size of the selected component (shows on the bottom of the page).

Now, I specifically need Inno Setup to require exactly as much as the current component's size is. How can I achieve that?

New code:

[Setup]
AppName=Dagon Video Tools
AppVersion=1.0
AppVerName=Dagon Video Tools
DefaultDirName={sd}\Tools\Dagon Video Tools
VersionInfoProductName=Dagon Video Tools
WizardImageFile=Include\WizardImage.bmp
WizardSmallImageFile=Include\WizardSmallImage.bmp
SetupIconFile=Include\Icon.ico

[Files]
.....

[ThirdParty]
UseRelativePaths=True

[Components]
Name: "Slasher"; Description: "Dagon Slasher"; Types: Slasher Full
Name: "Frankenstein"; Description: "Dagon Frankenstein"; Types: Frankenstein Full

[Types]
Name: "Full"; Description: "Full"
Name: "Slasher"; Description: "Dagon Slasher"
Name: "Frankenstein"; Description: "Dagon FrankenStein"

[Icons]
Name: "{group}\{cm:UninstallProgram,Dagon Slasher}"; Filename: "{uninstallexe}"; Components: Slasher
Name: "{group}\{cm:UninstallProgram,Dagon Frankenstein}"; Filename: "{uninstallexe}"; Components: Frankenstein
Name: "{group}\{cm:UninstallProgram,Dagon Video Tools}"; Filename: "{uninstallexe}"; Components: Slasher and Frankenstein


[Code]
procedure CurPageChanged(CurPageID: Integer);
Begin
if (CurPageID=wpSelectProgramGroup) then
  begin
  if IsComponentSelected('Slasher') then
    begin
      WizardForm.DirEdit.Text := ExpandConstant('{sd}\Tools\Dagon Slasher');
      WizardForm.GroupEdit.Text := 'Dagon Slasher';
    end;
  if IsComponentSelected('Frankenstein') then
    begin
      WizardForm.DirEdit.Text := ExpandConstant('{sd}\Tools\Dagon FrankenStein');
      WizardForm.GroupEdit.Text := 'Dagon FrankenStein';
    end;
  if IsComponentSelected('Slasher') and IsComponentSelected('Frankenstein') then
    begin
      WizardForm.GroupEdit.Text := 'Dagon Video Tools';
    end
  end;
End;

procedure OnTypeChange(Sender: TObject);
begin
  // set the item index in hidden TypesCombo
  WizardForm.TypesCombo.ItemIndex := TNewCheckListBox(Sender).ItemIndex;
  // notify TypesCombo about the selection change
  WizardForm.TypesCombo.OnChange(nil);
end;

procedure InitializeWizard;
var
  I: Integer;
  CheckListBox: TNewCheckListBox;
begin
  // create the TNewCheckListBox object and set the basic properties
  CheckListBox := TNewCheckListBox.Create(WizardForm);
  CheckListBox.Parent := WizardForm.SelectComponentsPage;
  CheckListBox.Left := WizardForm.TypesCombo.Left;
  CheckListBox.Top := WizardForm.TypesCombo.Top;
  CheckListBox.Width := WizardForm.TypesCombo.Width;
  CheckListBox.Height := CheckListBox.MinItemHeight * 
    WizardForm.TypesCombo.Items.Count + 4;
  CheckListBox.TabOrder := 0;
  // assign the selection change event
  CheckListBox.OnClickCheck := @OnTypeChange;
  // add radio buttons from all TypesCombo items, select the first item
  for I := 0 to WizardForm.TypesCombo.Items.Count - 1 do
    CheckListBox.AddRadioButton(WizardForm.TypesCombo.Items[I], 
      '', 0, I = 0, True, nil);
  // hide the TypesCombo combo box
  WizardForm.TypesCombo.Visible := False;
  WizardForm.ComponentsList.Visible := False;
  WizardForm.ComponentsDiskSpaceLabel.Visible := True;
end;

Posted the full code, since, as you can see, my code changes {app} and {group} depending on the component. I'm gonna have to go to work now, so I'll be offline next half of the day. This code seems to show the correct filesizes, I was going to some other functions attached to component selection, so, if this works I'm gonna have to post another question. Be back in ~8 hours.

回答1:

You are using setup components incorrectly. Your "Full pack" component is not a component. It is a combination of two components ("Part 1" + "Part 2"). As a consequence, the built-in Inno Setup logic does not match with your installer and now you ask how to workaround that. Do not try to workaround that, use Inno Setup correctly instead.

What you want is two components:

  • Part 1
  • Part 2

and three setup types:

  • Full pack (installs both "Part 1" and "Part 2" components)
  • Part 1 (installs "Part 1" component only)
  • Part 2 (installs "Part 2" component only)

If you use components instead of types because you like the "radio-button" selection more than the combo box (drop down menu), see Replace installation types Dropdown list by radio buttons.

This way you get the same GUI as on your screenshot, but working correctly.

In your case it probably does not make sense to show the component list at all. Make sure no type has iscustom flag to hide the components list and also to make sure it selects correct components (iscustom types do not select their components).

If you want to show the size label anyway, show it explicitly:

procedure InitializeWizard();
begin
  WizardForm.ComponentsDiskSpaceLabel.Visible := True;
end;

If you want to show even the components list with no custom type:

procedure InitializeWizard();
begin
  WizardForm.ComponentsList.Visible := True;
  WizardForm.ComponentsDiskSpaceLabel.Visible := True;
end;