Inno Setup: Delete folder with Task function - inno-setup

How can I delete a folder using a task function which must be executed when hitting Next button in Additional Task panel?
Thanks so much in advanced.

To check whether certain task is selected you can use the IsTaskSelected function. So, to meet your requirement you can write something like this:
[Setup]
AppName=My Program
AppVersion=1.5
DefaultDirName={pf}\My Program
[Tasks]
Name: deletefolder; Description: "Delete a folder"; GroupDescription: "Group Description:"
[Code]
function NextButtonClick(CurPageID: Integer): Boolean;
begin
// allow the setup turning to the next page
Result := True;
// if we are on the Additional Tasks page and the task is selected, then...
if (CurPageID = wpSelectTasks) and IsTaskSelected('deletefolder') then
// here call the RemoveDir or DelTree function depending on your needs
end;

Related

Inno Setup, prompt for task based on results of script function

With Inno Setup, I have a task which I want to be conditional based on the results of a Pascal Script function. If the function returns true, the task will be displayed and the user can either check or un-check it. Otherwise, the task will not be shown.
You are looking for the Check parameter:
[Tasks]
Name: mytask; Description: "My Task"; Check: IsTaskValid
[Code]
function IsTaskValid: Boolean;
begin
Result := { Your decision logic };
end;

downloading files over the internet, if the component has been selected (WITH Inno Tools Downloader)

This code actually download me the files and it does not matter whether the selected component is "test" or not. I want those two files download, if you select a component, can do that? I use Inno Inno Setup 5 + Tools Downloader)
[Components]
Name: Dictionaries; Description: "test"; Types: Full; ExtraDiskSpaceRequired: 50;
[Languages]
Name: english; MessagesFile: compiler:Default.isl
#include ReadReg(HKEY_LOCAL_MACHINE,'Software\Sherlock Software\InnoTools\Downloader','ScriptPath','');
[Code]
procedure InitializeWizard();
begin
itd_init;
itd_addfile('http://www.sherlocksoftware.org/petz/files/dogz5.zip',expandconstant('{tmp}\dogz5.zip'));
itd_addfile('http://www.sherlocksoftware.org/petz/files/petz4.zip',expandconstant('{tmp}\petz4.zip'));
itd_downloadafter(wpReady);
end;
procedure CurStepChanged(CurStep: TSetupStep);
begin
if CurStep=ssInstall then begin
filecopy(expandconstant('{tmp}\dogz5.zip'),expandconstant('{app}\dogz5.zip'),false);
filecopy(expandconstant('{tmp}\petz4.zip'),expandconstant('{app}\petz4.zip'),false);
end;
end;
Yes, that's possible. Your are looking for a little helper function called
IsComponentSelected().
It's basically a boolean tester accepting a component name from the [components] and returning the checkbox value (selected=true).
// for a single component
if IsComponentSelected('NameOfTheComponent') then idpAddFile(URL, ...);`
// multiple components with one selection
if IsComponentSelected('dictionaries') then
begin
idpAddFile(URL1, ...);
idpAddFile(URL2, ...);
end;
Comment by TLama:
In which event and where to enqueue the download files?
I would suggest to use the NextButtonClick event with a condition, that the current (CurPage) has to be the component selection screen (wpSelectComponents).
In other words: when you are on the component selection screen and press next, only the selected components are added to the downloader.
The code could look like this:
function NextButtonClick(CurPage: Integer): Boolean;
(*
Called when the user clicks the Next button.
If you return True, the wizard will move to the next page.
If you return False, it will remain on the current page (specified by CurPageID).
*)
begin
if CurPage = wpSelectComponents then
begin
if IsComponentSelected('NameOfTheComponent') then idpAddFile(URL, ...);
end; // of wpSelectComponents
Result := True;
end;
Sidenote: you might switch your download lib to https://code.google.com/p/inno-download-plugin/ This has better features, including decent https support and is actively maintained. InnoTools Download by SherlockSoftware is outdated (2008).

Change AppId using [Code] just before the installation in Inno Setup

In a setup I give the user the option to install either a 32 or 64 bit version using radio buttons.
I then want to append either _32 or _64 to the AppId.
I know I can change the AppId using scripted constants but the needed function is called while Setup is starting. But at this point the radio buttons do not yet exist and thus I receive the error "Could not call proc".
I consulted the Inno Setup help and I read that you can change the AppId at any given point before the installation process has started (if I understood correctly).
So how do I manage to do this?
I am looking forward to your answers!
Some of the {code:...} functions for certain directive values are called more than one time and the AppId is one of them. To be more specific, it is called twice. Once before a wizard form is created and once before the installation starts. What you can do is just to check if the check box you're trying to get the value from exists. You can simply ask if it's Assigned like follows:
[Setup]
AppId={code:GetAppID}
...
[Code]
var
Ver32RadioButton: TNewRadioButton;
Ver64RadioButton: TNewRadioButton;
function GetAppID(const Value: string): string;
var
AppID: string;
begin
// check by using Assigned function, if the component you're trying to get a
// value from exists; the Assigned will return False for the first time when
// the GetAppID function will be called since even WizardForm not yet exists
if Assigned(Ver32RadioButton) then
begin
AppID := 'FDFD4A34-4A4C-4795-9B0E-04E5AB0C374D';
if Ver32RadioButton.Checked then
Result := AppID + '_32'
else
Result := AppID + '_64';
end;
end;
procedure InitializeWizard;
var
VerPage: TWizardPage;
begin
VerPage := CreateCustomPage(wpWelcome, 'Caption', 'Description');
Ver32RadioButton := TNewRadioButton.Create(WizardForm);
Ver32RadioButton.Parent := VerPage.Surface;
Ver32RadioButton.Checked := True;
Ver32RadioButton.Caption := 'Install 32-bit version';
Ver64RadioButton := TNewRadioButton.Create(WizardForm);
Ver64RadioButton.Parent := VerPage.Surface;
Ver64RadioButton.Top := Ver32RadioButton.Top + Ver32RadioButton.Height + 4;
Ver64RadioButton.Caption := 'Install 64-bit version';
end;

Skipping custom pages based on optional components in Inno Setup

In a prior question I asked how to have three optional components, where the user could also specify the locations for each component separately (e.g. a code part and two HTML web applications). #Miral gave me a great answer which I have now implemented:
three components in three user defined locations
I have a small esthetic issue remaining. I am always creating and asking the user for a CreateInputDirPage, in the wizard. The question comes after the wpSelectComponents.
Question: How do I skip the page if the component was not selected. That is, how do I skip my custom page?
I have a feeling it has to do with ShouldSkipPage(). But I have no idea what the PageID for my custom page is, and how to test to see what components were selected.
function ShouldSkipPage(PageID: Integer): Boolean;
The wizard calls this event function to determine whether or not a particular page (specified by PageID) should be shown at all. If you return True, the page will be skipped; if you return False, the page may be shown.
My script is enclosed below:
[Components]
Name: "Watson"; Description: "Watson Component"; Types: onlywatson full
Name: "Toby"; Description: "Toby Component"; Types: onlytoby full
Name: "Sherlock"; Description: "Sherlock Component"; Types: onlysherlock full
[Code]
var
TobyDirPage: TInputDirWizardPage;
SherlockDirPage: TInputDirWizardPage;
procedure InitializeWizard;
begin
TobyDirPage := CreateInputDirPage(wpSelectComponents,
'Select Location for Toby Web Pages', 'Where should we store the sample Toby application files?',
'The sample Toby stand-alone map application will be saved in the following folder.'#13#10#13#10 +
'To continue, click Next. If you would like to select a different folder, click Browse.',
False, 'New Folder');
{ Add item (with an empty caption) }
TobyDirPage.Add('');
{ Set initial value (optional) }
TobyDirPage.Values[0] := ExpandConstant('c:\wwwroot\Toby');
SherlockDirPage := CreateInputDirPage(wpSelectComponents,
'Select Location for Sherlock Web Pages', 'Where should we store the Sherlock Catalog Search Tool?',
'Sherlock.html and it'#39 + 's associated files will be saved in the following folder.'#13#10#13#10 +
'To continue, click Next. If you would like to select a different folder, click Browse.',
False, 'New Folder');
{ Add item (with an empty caption) }
SherlockDirPage.Add('');
{ Set initial value (optional) }
SherlockDirPage.Values[0] := ExpandConstant('c:\wwwroot\Sherlock');
end;
function GetTobyDir(Param: String): String;
begin
{ Return the selected TobyDir }
Result := TobyDirPage.Values[0];
end;
function GetSherlockDir(Param: String): String;
begin
{ Return the selected TobyDir }
Result := SherlockDirPage.Values[0];
end;
As you correctly forefelt, you need to use the ShouldSkipPage event handler to conditionally skip the page. To check if a certain component is selected use the IsComponentSelected function and finally, to get ID of your custom page you need to store its ID. Putting all together might give you the following example script:
[Setup]
AppName=My Program
AppVersion=1.5
DefaultDirName={pf}\My Program
OutputDir=userdocs:Inno Setup Examples Output
[Components]
Name: "help"; Description: "Help File";
[Code]
var
CustomPageID: Integer;
procedure InitializeWizard;
var
CustomPage: TInputDirWizardPage;
begin
CustomPage := CreateInputDirPage(wpSelectComponents, 'Caption',
'Description', 'SubCaption', False, 'NewFolderName');
CustomPage.Add('Input');
{ store your custom page ID to further use in the ShouldSkipPage event }
CustomPageID := CustomPage.ID;
end;
function ShouldSkipPage(PageID: Integer): Boolean;
begin
{ initialize result to not skip any page (not necessary, but safer) }
Result := False;
{ if the page that is asked to be skipped is your custom page, then... }
if PageID = CustomPageID then
{ if the component is not selected, skip the page }
Result := not IsComponentSelected('help');
end;
My take on this is to use the TWizardPageShouldSkipEvent, I've made only a case-and-point script:
[Code]
var
TobyDirPage: TInputDirWizardPage;
function SkipEvent (Sender: TWizardPage): Boolean;
begin
Result := not IsComponentSelected('Toby');
end;
procedure InitializeWizard;
begin
TobyDirPage := CreateInputDirPage(wpSelectComponents, yadda yadda yadda
TobyDirPage.OnShouldSkipPage := #SkipEvent;
end;
Now, OnShouldSkipPage fires right after pressing Next on wpSelectComponents and before TobyDirPage gets painted and since you can attach that event to the page itself you don't need to fiddle with PageID's.

Controlling Custom Page To Show After Specific Tasks

After couple of hours googling and struggling, and got no where, I decide to ask for help here.
What I am trying to accomplish, I am trying to get the IP from the user and use it as a command line parameter in my [Run] Section.
So I have this:
[Task]
Name: "License"; Description: "Usb Key License Driver"; GroupDescription: "UsbLicense"; Flags: checkedonce
Name: "License/Desktop"; Description: "Desktop License"; GroupDescription: "UsbLicense"; Flags: exclusive
Name: "License/NetworkClient"; Description: "Network Client License Key"; GroupDescription: "UsbLicense"; Flags: exclusive unchecked
Now if the user chooses Network client, I want to be able to show a custom page, and get the IP and use it like this:
[Run]
Filename: "{app}\Drivers\Program.exe"; Parameters: "/ip:{code:GetIPhere}"; StatusMsg: "Installing drivers..."; Tasks: License/NetworkClient
I managed to create my own page and ran this:
[Code]
procedure InitializeWizard();
begin
CustomForm_CreatePage(wpSelectDir);
end;
Now for my main question:
1) How do i control WHEN the custom form shows, it shows up before it activates before my Task page.
2) If i can get it to show AFTER task page? How do I write code to make it show under the "Client Network" condition only from task. (If i do this in NextButtonClick method, how do i know what is the page id of my custom page?)
Thanks for all you help, i am just geting so close to finishing my installer, but this is driving me nuts.
----EDITED----
I sovled my problem 1, there is a pageAfter parameter when creating the custom page, and we can use the selectedTask constant to determine it to appear AFTER the Task page:
procedure InitializeWizard();
begin
Form_CreatePage(wpSelectTasks);
end;
Thanks and Regards,
Kev84
You can use the Pascal Script WizardSelectedTasks, which will return you the string of tasks you have created, just do a "Pos" on the returned string and you'll be able to determine if your specific task was chosen.
[code]
function Form_ShouldSkipPage(Page: TWizardPage): Boolean;
var
selectedTask : string;
skipPage : bool;
begin
skipPage := true;
selectedTask := WizardSelectedTasks(false);
if (Pos('client', selectedTask) > 0) then
begin
skipPage := false;
end;
Result := skipPage;
end;

Resources