batch-filecomponentsinno-setuppascalscript

Create a dynamic list of Inno Setup components/types from external source (file or folder contents)


I have a batch file (setting changer) that uses xcopy to list specific files formats in a specific folder, then allows me to type in one of the names and the script uses that name to copy that file to another location.

First xcopy creates a copy of the original as a backup (rolling backup only 1 copy) then does the file copy (extension is fixed in batch only body of filename needed This works great BUT I would love to try and do this in Inno Setup for a nice clean GUI.

I would like to populate the list of components/types from this list of files found in a specific fixed folder. Or even create an ini file with those names in (extra step but maybe better control). Main problem that might prevent this from being possible is not knowing how many entries it would be an array. If only 1 entry or file only 1 option (1 or a) if 4 then user can select 1 of 4 (a, b, c or d). I would extract the file name to create the name/description.

then on completion the same task as my batch would happen, backup (easy always the same name like start.ini) then copy the file e.g. example1.ini and overwrite start.ini

ini might be most flexible as I can imagine later adding new sections to change the actions performed.

Is this possible or stretching this program too far. No rush as my batch works for now but the less typing and manual steps the better for continued use.

I found an example to list contents to a dialog window but I could not figure how to use this to populate components. TLama - List all files in a directory


Solution

  • You cannot create the components dynamically on runtime (you can on compile-time).


    But it's not difficult to implement a custom dynamic components-like page using the CreateCustomPage and the TNewCheckListBox.

    Then in the CurStepChanged(ssInstall) you process the selected files/components as your need.

    Dynamic components list

    [Code]
    
    const
      SourcePath = 'C:\somepath';
    
    var
      CustomSelectTasksPage: TWizardPage;
      ComponentsList: TNewCheckListBox;
    
    procedure InitializeWizard();
    var
      FindRec: TFindRec;
      SelectComponentsLabel: TNewStaticText;
    begin
      CustomSelectTasksPage :=
        CreateCustomPage(
          wpSelectComponents, SetupMessage(msgWizardSelectComponents),
          SetupMessage(msgSelectComponentsDesc));
    
      SelectComponentsLabel := TNewStaticText.Create(WizardForm);
      SelectComponentsLabel.Parent := CustomSelectTasksPage.Surface;
      SelectComponentsLabel.Top := 0;
      SelectComponentsLabel.Left := 0;
      SelectComponentsLabel.Width := CustomSelectTasksPage.Surface.Width;
      SelectComponentsLabel.AutoSize := False;
      SelectComponentsLabel.ShowAccelChar := False;
      SelectComponentsLabel.WordWrap := True;
      SelectComponentsLabel.Caption := SetupMessage(msgSelectComponentsLabel2);
      WizardForm.AdjustLabelHeight(SelectComponentsLabel);
    
      ComponentsList := TNewCheckListBox.Create(WizardForm);
      ComponentsList.Parent := CustomSelectTasksPage.Surface;
      ComponentsList.Top :=
        SelectComponentsLabel.Top + SelectComponentsLabel.Height + ScaleY(8);
      ComponentsList.Left := 0;
      ComponentsList.Width := CustomSelectTasksPage.Surface.Width;
      ComponentsList.Height := CustomSelectTasksPage.Surface.Height - ComponentsList.Top;
    
      if FindFirst(ExpandConstant(AddBackslash(SourcePath) + '*.dat'), FindRec) then
      begin
        try
          repeat
            ComponentsList.AddCheckBox(FindRec.Name, '', 0, False, True, False, False, nil);
          until not FindNext(FindRec);
        finally
          FindClose(FindRec);
        end;
      end;
    end;
    
    procedure CurStepChanged(CurStep: TSetupStep);
    var
      I: Integer;
      FileName: string;
      SourceFilePath: string;
      TargetFilePath: string;
    begin
      if CurStep = ssInstall then
      begin
        for I := 0 to ComponentsList.Items.Count - 1 do
        begin
          if ComponentsList.Checked[I] then
          begin
            FileName := ComponentsList.Items[I];
            SourceFilePath := AddBackslash(SourcePath) + FileName;
            TargetFilePath := AddBackslash(ExpandConstant('{app}')) + FileName;
            if FileCopy(SourceFilePath, TargetFilePath, False) then
            begin
              Log(Format('Installed "%s".', [FileName]));
            end
              else
            begin
              Log(Format('Failed to install "%s".', [FileName]));
            end;
          end;
        end;
      end;
    end;