Use two/multiple selected directories from custom page in Files section - inno-setup

I need create custom page of two destination.
I've done:
#define MyAppName "TESTPROG"
[Setup]
AppName={#MyAppName}
DefaultDirName=C:\test\{#MyAppName}
DefaultGroupName={#MyAppName}
[Code]
var
Page: TInputDirWizardPage;
DataDir: String;
procedure InitializeWizard;
begin
Page := CreateInputDirPage(wpWelcome,
'Select Personal Data Location', 'Where should personal data files be stored?',
'Personal data files will be stored 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');
Page.Add('Local APP');
Page.Add('Local Storage');
Page.Values[0] := ('C:\My Program');
Page.Values[1] := ('D:\My Program');
DataDir := Page.Values[0];
end;
I need to know how and where I set DefaultDirName with Page.Values[0] and Page.Values[1]
I need it because some part of my files will be in a folder and others in other folder.
For example:
[Files]
Source: C:\TEST\DLL1.bat; DestDir: Page.Values[0]\sys1;
Source: C:\TEST\DLL2.bat; DestDir: Page.Values[1]\sys2;

Use a scripted constant:
[Files]
Source: C:\TEST\DLL1.bat; DestDir: "{code:GetDir|0}\sys1"
Source: C:\TEST\DLL2.bat; DestDir: "{code:GetDir|1}\sys2"
[Code]
var
Page: TInputDirWizardPage;
function GetDir(Param: string): string;
begin
Result := Page.Values[StrToInt(Param)];
end;
procedure InitializeWizard;
begin
Page := CreateInputDirPage(...);
...
end;
If you want to use one of the (the first) paths from the TInputDirWizardPage instead of the path from "Select Destination Location" page, you have three options.
Disable the "Select Destination Location" page using DisableDirPage directive:
DisableDirPage=yes
Copy the path from the TInputDirWizardPage to the hidden "Select
Destination Location" page, when the user presses Next button:
var
Page: TInputDirWizardPage;
function InputDirPageNextButtonClick(Sender: TWizardPage): Boolean;
begin
{ Use the first path as the "destination path" }
WizardForm.DirEdit.Text := Page.Values[0];
Result := True;
end;
procedure InitializeWizard();
begin
Page := CreateInputDirPage(...);
...
Page.OnNextButtonClick := #InputDirPageNextButtonClick;
end;
To complement that you may also consider copying the initial WizardForm.DirEdit to your custom box. This way you make sure that 1) on re-install/upgrade, the previously selected value is reused; 2) /DIR command-line switch works. For that see How to make Inno Setup /DIR command line switch work with custom path page.
Replace all uses of the {app} constant with {code:GetDir|0}.
Make Inno Setup not create the {app} path using CreateAppDir directive:
CreateAppDir=no
(this implies DisableDirPage=yes).
And have the uninstall files be stored in the first path using UninstallFilesDir directive:
UninstallFilesDir={code:GetDir|0}
Contrary to 1), with this approach the previous installation path won't get reused for the later upgrade/re-install. To implement that see Inno Setup Prompt user for a folder and store the value.
Do not use the CreateInputDirPage, but rather add a second path input box on the "Select Destination Location" page (SelectDirPage).

Related

How to set my own variable in [Setup] and read it from [Code]

I'm trying to create a script in Inno Setup to pull files from a GitHub repository, extract it, and write it to a directory defined in the [Setup] section.
[Setup]
MyVariable={userappdata}\MetaQuotes\Terminal\{#MyAppName}
[Code]
procedure CurStepChanged(CurStep: TSetupStep);
begin
// Copy the selected files to the selected directory
if not FileCopy(Output + '\file1.txt', MyVariable + '\file1.txt', False) then
begin
MsgBox('Failed to copy file1.txt to the selected directory.', mbError, MB_OK);
Abort();
end;
if not FileCopy(Output + '\file2.txt', MyVariable + '\file2.txt', False) then
begin
MsgBox('Failed to copy file2.txt to the selected directory.', mbError, MB_OK);
Abort();
end;
end;
Obviously, this won't compile because MyVariable hasn't been defined in the Pascal script. Only, I'm not sure how to reference the value in [Setup]. Or am I going about this in the wrong way?
Well, you can read the [Setup] section directives with SetupSetting preprocessor function:
How to read a [Setup] parameter in the Pascal code?
But you cannot invent your own new directives.
But you can either:
Use preprocessor variable using #define directive (the way you already use it for MyAppName):
#define MyVariable "{userappdata}\MetaQuotes\Terminal\" + MyAppName
It does not matter where you place the #define as long as it it before you use the variable.
Use it like this in the Pascal Script:
ExpandConstant('{#MyVariable}\file1.txt')
The ExpandConstant is to expand the {userappdata}.
Use Pascal Script constant:
[Code]
const
MyVariable = '{userappdata}\MetaQuotes\Terminal\{#MyAppName}';
Use it like any other Pascal Script variable/constant.
ExpandConstant(MyVariable) + '\file1.txt'

Inno Setup - Renaming MsgBox Title Bar [duplicate]

This question already has answers here:
How to change MsgBox message caption at runtime?
(2 answers)
Closed 5 years ago.
This is my code:
[Code]
procedure CurStepChanged(CurStep: TSetupStep);
var
ErrorCode: integer;
begin
if CurStep = ssPostInstall then
begin;
if MsgBox('Czy chcesz zainstalować pakiet DirectX9?', mbConfirmation, MB_YESNO) = IDYES then
begin
ShellExec('', ExpandConstant('{src}\directx\dxsetup.exe'), '', '', SW_SHOW, ewWaitUntilTerminated, ErrorCode);
end;
end;
end;
It is possible to rename title only of this one MsgBox? Suppose I want to create another MsgBox and i want have 2 another titles for example: Instalator #1, Instalator #2. The change in language files will affect on both MsgBox'es.
1) You can change titles for all message boxes (and also for all dialogs) in your .isl file located in Inno Setup installation directory:
Edit Languages\Polish.isl (in your case) or Default.isl (for English) and change SetupAppTitle to your desired value.
2) You cannot set different titles to various MsgBox-es as Inno Setup does not support this, but you can implement your own MSgBox dialog like regular Windows form and set title that way.

WizardForm.DirEdit.Text not updating properly. Inno setup

I am trying to set the path in the 'choose install directory' form using INNO setup. Here is my code
procedure CurPageChanged(pageID: Integer);
var
sInstallDir: String;
begin
// Default install dir is the IIS install path
if (pageID = wpSelectDir) then begin
sInstallDir := GetIISInstallPath + '\MyFolder';
Log('GetIISInstallPath: '+ GetIISInstallPath);
Log('sInstallDir: ' + sInstallDir);
WizardForm.DirEdit.Text := sInstallDir;
end;
end;
The problem I am having is that 'GetIISInstallPath' returns me 'c:\inetpub\wwwroot and that is what I see in the WizardForm. It seems to not add the MyFolder bit.
I printed out the involved variables and they all have the correct value.
sInstallDir shows up as 'C:\inetpub\wwwroot\MyFolder' but it does not show in the text field. It shows (as mentioned) only 'C:\inetpub\wwwroot'.
Please advise.
Thank You
Your code works fine for me but, can I suggest you to use
[Setup]
...
DefaultDirName={code:GetDefaultDirName}
[code]
...
function GetDefaultDirName(): String;
begin
Result := GetIISInstallPath + '\MyFolder';
end;
Doing this the "GetIISInstallPath + \MyFolder" will be your default directory

Need an equivalent to sharedfile for start-menu shortcut in inno

I have 2 installers for 2 different applications, both of which also install a common support/diagnostic tool.
For the exe file I have added the sharedfile flag, so that when a user installs both applications and then uninstalls one of them, the diagnostic tool remains.
However, I also add a start-menu shortcut to the diagnostic tool, which gets deleted by the uninstaller.
How can I make the shortcut remain if one of the applications still exists, or if the diagnostic tool exe is still there, but delete if both applications are removed (or only one was installed in the first place)?
[files]
Source: "{app}_dynamic\SupportApp\*.*"; DestDir: "{app}\SupportApp"; Flags: sharedfile; Components: Support
[icons]
Name: "{group}\Tools\Send diagnostic logs"; Filename: "{app}\SupportApp\Support.exe"; Flags: uninsneveruninstall; Components: Support
[edit]
Came up with this:
(initial work done by TLama: https://stackoverflow.com/a/12645836/2021217)
[code]
procedure CurUninstallStepChanged(CurUninstallStep: TUninstallStep);
begin
if CurUninstallStep = usPostUninstall then
begin
if (not(FileExists(ExpandConstant('{app}') + '\SupportApp\Support.exe'))) then
begin
if (MsgBox('deleting "' + ExpandConstant('{group}') + '\Tools". "' + ExpandConstant('{app}') + '\SupportApp\Support.exe" doesnt exist', mbConfirmation, MB_YESNO) = IDYES) then
begin
DeleteFile('"' + ExpandConstant('{group}') + '\Tools\Send diagnostic logs"');
DeleteFile('"' + ExpandConstant('{group}') + '\Tools\Send diagnostic logs.lnk"');
RemoveDir('"' + ExpandConstant('{group}') + '\Tools"');
end;
end;
end;
end;
It all seems to work, except for the deletion part...the deletefile and removedir function calls don't seem to work!
Any help is appreciated
[code]
procedure CurUninstallStepChanged(CurUninstallStep: TUninstallStep);
begin
if CurUninstallStep = usPostUninstall then
begin
if (not(FileExists(ExpandConstant('{app}\SupportApp\Support.exe')))) then
DelTree(ExpandConstant('{group}\Tools'), True, True, True);
end;
end;
Many Thanks to TLama for guiding me to a final solution.

Inno Setup: Install only if not VERYSILENT

I would like to install and regsiter a certain file only if the setup is not run as VERYSILENT.
I don't know how I could achieve this.
My current line is
Source: "M:\sqlite36_engine.dll"; DestDir: {sys}; Flags: uninsneveruninstall ignoreversion
Can somebody tell me how this can be done?
Thank you!
Since there is still no runtime function or variable to determine if the setup is running in very silent mode, you need to make your own function to check this by iterating command line parameters. For conditional installing of a certain file we're using the Check parameter, which can take such function for getting the condition by its returned value. The following script should do what you want:
[Files]
Source: "M:\sqlite36_engine.dll"; DestDir: {sys}; Flags: uninsneveruninstall ignoreversion; Check: not IsVerySilent
[Code]
function IsVerySilent: Boolean;
var
I: Integer;
begin
Result := False;
for I := 1 to ParamCount do
if CompareText(ParamStr(I), '/verysilent') = 0 then
begin
Result := True;
Exit;
end;
end;

Resources