I am using the CreateInputFilePage function to create a page with an input field and a Browse button that allows selection of a path and file. The problem is that I don't want to select a file to open, I want to specify a file to save to. The default behaviour when specifying a path and file that doesn't exist is to prompt
File not found. Check the file name and try again.
Unfortunately, this isn't the behaviour required if specifying a file to save to. In this scenario it needs to prompt
File does not exist. Create the file?
or something similar and allow selection of the chosen path and file.
Ideally, the Open button in the Browse dialog should also be changed to read "Save".
Is it possible to modify this behaviour as described and change the button text? If so, how could this be done?
Use TInputFileWizardPage.IsSaveButton property.
To implement the confirmation, handle TWizardPage.OnNextButtonClick event.
var
FileIndex: Integer;
function InputFileCheck(Page: TWizardPage): Boolean;
var
Path: string;
begin
Result := True;
Path := Trim(TInputFileWizardPage(Page).Values[FileIndex]);
if Length(Path) = 0 then
begin
MsgBox('No file specified.', mbError, MB_OK);
Result := False;
end
else
if not FileExists(Path) then
begin
Result :=
MsgBox('File does not exist. Create the file?', mbConfirmation, MB_YESNO) = IDYES;
end;
end;
procedure InitializeWizard;
var
Page: TInputFileWizardPage;
begin
Page := CreateInputFilePage('...', '...', '...', '...');
Page.OnNextButtonClick := #InputFileCheck;
FileIndex := Page.Add('...', '...', '...');
Page.IsSaveButton[FileIndex] := True;
...
end;
Related
I am building an installer and would like to ask the user to restart using a radio button. I would also like to include an option to open the user guide if the user selects "No, I will restart later". My current method for asking the user to open the user guide is putting it in the [Run] section like this:
[Run]
Filename: "{app}\userguide.pdf"; Description: "View the User Guide"; Flags: shellexec runasoriginaluser postinstall nowait unchecked
This works perfectly, it even opens in the default PDF viewer. However, whenever I try to include a restart option, it overrides the user guide option and completely removes it. So, trying:
[Code]
function NeedRestart(): Boolean;
begin
Result := True;
end;
as well as:
[Setup]
AlwaysRestart=yes
work in the sense that they include an option for restart but they also override the user guide button. Is there a way to make a custom page that, upon checking the "No I will restart later" radio button, will show an option on opening the user guide? I am not too familiar with using Inno Setup and Delphi/Pascal.
You have to code that. For example you can add your own checkbox for starting the user guide:
[Setup]
AlwaysRestart=yes
[Files]
Source: "userguide.pdf"; DestDir: "{app}"
[Code]
var
LaunchCheckbox: TCheckbox;
procedure YesNoRadioClicked(Sender: TObject);
begin
// Disable the user guide checkbox when "restart" is selected
LaunchCheckbox.Enabled := WizardForm.NoRadio.Checked;
end;
procedure InitializeWizard();
begin
LaunchCheckbox := TCheckbox.Create(WizardForm.FinishedPage);
LaunchCheckbox.Caption := 'View the User Guide';
LaunchCheckbox.Checked := False;
LaunchCheckbox.Left := WizardForm.YesRadio.Left;
LaunchCheckbox.Width := WizardForm.YesRadio.Width;
LaunchCheckbox.Height := ScaleY(LaunchCheckbox.Height);
LaunchCheckbox.Parent := WizardForm.FinishedPage;
if (WizardForm.YesRadio.OnClick <> nil) or (WizardForm.NoRadio.OnClick <> nil) then
begin
Log('Restart radio button event handler unexpectedly set');
end
else
begin
WizardForm.YesRadio.OnClick := #YesNoRadioClicked;
WizardForm.NoRadio.OnClick := #YesNoRadioClicked;
end;
end;
procedure CurPageChanged(CurPageID: Integer);
begin
if CurPageID = wpFinished then
begin
// Adjust to the initial start of restart selection
YesNoRadioClicked(nil);
// Only now the restart radio buttons have their definitive vertical position
LaunchCheckbox.Top :=
WizardForm.NoRadio.Top + WizardForm.NoRadio.Height + ScaleY(16);
end;
end;
procedure CurStepChanged(CurStep: TSetupStep);
var
ErrorCode: Integer;
begin
if CurStep = ssDone then
begin
if (not WizardSilent) and
(not WizardForm.YesRadio.Checked) and
LaunchCheckbox.Checked then
begin
Log('Opening user guide');
ShellExecAsOriginalUser(
'open', ExpandConstant('{app}\userguide.pdf'), '', '', SW_SHOWNORMAL,
ewNoWait, ErrorCode);
end;
end;
end;
The code assumes AlwaysRestart. Were the restart conditional, the code will need an update to adjust to a different layout of the Finished page, when restart is not needed. For a full solution see my installer for WinSCP:
https://github.com/winscp/winscp/blob/master/deployment/winscpsetup.iss
In my setup, in the browser showed by a "Browse" button (wpSelectDir or CreateInputDirPage for example), a Network is never shown.
I've searched a while on this but I haven't found any solution for now.
Is there a way to show network and let the user select a network path?
Thanks for any help on this!
Hardly.
But you can re-implement the button using the BrowseForFolder function, which does show the network.
For example for the CreateInputDirPage:
var
Page: TInputDirWizardPage;
procedure DirBrowseButtonClick(Sender: TObject);
var
Path: String;
begin
Path := Page.Values[0];
if BrowseForFolder(SetupMessage(msgBrowseDialogLabel), Path, True) then
begin
Page.Values[0] := Path;
end;
end;
procedure InitializeWizard();
begin
Page := CreateInputDirPage(...);
Page.Add('');
Page.Buttons[0].OnClick := #DirBrowseButtonClick;
end;
I have a setup script that allows the user to specify where they would like to install my application. It is in the form of a Pascal script within the [Code] block.
var
SelectUsersPage: TInputOptionWizardPage;
IsUpgrade : Boolean;
UpgradePage: TOutputMsgWizardPage;
procedure InitializeWizard();
var
AlreadyInstalledPath: String;
begin
{ Determine if it is an upgrade... }
{ Read from registry to know if this is a fresh install or an upgrade }
if RegQueryStringValue(HKLM, 'Software\Microsoft\Windows\CurrentVersion\Uninstall\{#MyAppId}_is1', 'Inno Setup: App Path', AlreadyInstalledPath) then
begin
{ So, this is an upgrade set target directory as installed before }
WizardForm.DirEdit.Text := AlreadyInstalledPath;
{ and skip SelectUsersPage }
IsUpgrade := True;
{ Create a page to be viewed instead of Ready To Install }
UpgradePage := CreateOutputMsgPage(wpReady,
'Ready To Upgrade', 'Setup is now ready to upgrade {#MyAppName} on your computer.',
'Click Upgrade to continue, or click Back if you want to review or change any settings.');
end
else
begin
IsUpgrade:= False;
end;
{ Create a page to select between "Just Me" or "All Users" }
SelectUsersPage := CreateInputOptionPage(wpLicense,
'Select Users', 'For which users do you want to install the application?',
'Select whether you want to install the library for yourself or for all users of this computer. Click next to continue.',
True, False);
{ Add items }
SelectUsersPage.Add('All users');
SelectUsersPage.Add('Just me');
{ Set initial values (optional) }
SelectUsersPage.Values[0] := False;
SelectUsersPage.Values[1] := True;
end;
So the question is how could I support a silent installation? When a user invokes /SILENT or /VERYSILENT the installer defaults to SelectUsersPage.Values[1], which is for Just Me. I want to help support the user that wants to change the installation directory with providing an answer file.
I didn't develop all of this code, and am a newbie with Pascal.
Thanks.
You can add a custom key (say Users) to the .inf file created by the /SAVEINF.
Then in the installer, lookup the /LOADINF command-line argument and read the key and act accordingly:
procedure InitializeWizard();
var
InfFile: string;
I: Integer;
UsersDefault: Integer;
begin
...
InfFile := ExpandConstant('{param:LOADINF}');
UsersDefault := 0;
if InfFile <> '' then
begin
Log(Format('Reading INF file %s', [InfFile]));
UsersDefault :=
GetIniInt('Setup', 'Users', UsersDefault, 0, 0, ExpandFileName(InfFile));
Log(Format('Read default "Users" selection %d', [UsersDefault]));
end
else
begin
Log('No INF file');
end;
SelectUsersPage.Values[UsersDefault] := True;
end;
My application requires .NET Framework to be installed so I run .NET installation in PrepareToIntall event function. While the installation is running I would like to display some simple message on Wizard.
I found How to set the status message in [Code] Section of Inno install script? but the solution there doesn't work for me.
I tried
WizardForm.StatusLabel.Caption := CustomMessage('InstallingDotNetMsg');
and also
WizardForm.PreparingLabel.Caption := CustomMessage('InstallingDotNetMsg');
EDIT
I have to do this in PrepareToInstall function, because I need to stop the setup when .net installation fails.
Code looks like this right now:
function PrepareToInstall(var NeedsRestart: Boolean): String;
var
isDotNetInstalled : Boolean;
errorCode : Integer;
errorDesc : String;
begin
isDotNetInstalled := IsDotNetIntalledCheck();
if not isDotNetInstalled then
begin
//WizardForm.PreparingLabel.Caption := CustomMessage('InstallingDotNetMsg');
WizardForm.StatusLabel.Caption := CustomMessage('InstallingDotNetMsg');
ExtractTemporaryFile('dotNetFx40_Full_x86_x64.exe');
if not ShellExec('',ExpandConstant('{tmp}\dotNetFx40_Full_x86_x64.exe'),'/passive /norestart', '', SW_HIDE, ewWaitUntilTerminated, errorCode) then
begin
errorDesc := SysErrorMessage(errorCode);
MsgBox(errorDesc, mbError, MB_OK);
end;
isDotNetInstalled := WasDotNetInstallationSuccessful();
if not isDotNetInstalled then
begin
Result := CustomMessage('FailedToInstalldotNetMsg');
end;
end;
end;
Any Ideas how to achieve this?
The StatusLabel is hosted by the InstallingPage wizard page while you're on PreparingPage page in the PrepareToInstall event method. So that's a wrong label. Your attempt to set the text to the PreparingLabel was correct, but failed because that label is hidden by default (it is shown when you return non empty string as a result to the event method).
But you can show it for a while (you are using ewWaitUntilTerminated flag, so your installation is synchronous, thus it won't hurt anything):
[Code]
function PrepareToInstall(var NeedsRestart: Boolean): String;
var
WasVisible: Boolean;
begin
// store the original visibility state
WasVisible := WizardForm.PreparingLabel.Visible;
try
// show the PreparingLabel
WizardForm.PreparingLabel.Visible := True;
// set a label caption
WizardForm.PreparingLabel.Caption := CustomMessage('InstallingDotNetMsg');
// do your installation here
finally
// restore the original visibility state
WizardForm.PreparingLabel.Visible := WasVisible;
end;
end;
Another solution is to use CreateOutputProgressPage to display a progress page over the top of the Preparing to Install page. See the CodeDlg.iss example script included with Inno for an example of the usage; it's fairly straightforward.
If the specified path does not already exist on the user's system, it will be created automatically. But I dont want it to crate automatically. The setup install a notepad++plugin, however if notepad++ is not installed on the user system, it creates a notepad++ file. I want to implement a code which ask user "notepad++ is not installed on your system do you wish to continue?"
I am new in innosetup compiler, so I need help about the code part. I found an example on the internet., but that is not the exact code that I want. So please help me..
function NextButtonClick(PageId: Integer): Boolean;
begin
Result := True;
if (PageId = wpSelectDir) and not FileExists(ExpandConstant('{app}\yourapp.exe')) then begin
MsgBox('YourApp does not seem to be installed in that folder. Please select the correct folder.', mbError, MB_OK);
Result := False;
exit;
end;
end;
function NextButtonClick(CurPageID: Integer): Boolean;
begin
Result := True;
if (CurPageID = wpSelectComponents) and IsComponentSelected('notepad_plugin') then
if not DirExists('/*your directory*/') then
begin
MsgBox('Component Selection:' #13#13 'Notepad++ could not be found on your system.', mbInformation, MB_OK);
Result := False;
end;
end;