I am trying to disable welcome page dynamically :
here are different option i tried
[SETUP]
DisableWelcomePage={code:ShouldSkipAutorun}
...
[CODE]
function ShouldSkipAutorun(Default: string):boolean;
begin
...
// will return true or false on whether to disable it or not
end;
error: "Value of [Setup] section directive "DisableWelcomePage" is invalid"
next I tried using shouldskippage but documentation says
This event function isn't called for the wpWelcome, wpPreparing, and wpInstalling pages, nor for pages that Setup has already determined should be skipped (for example, wpSelectComponents in an install containing no components
any help?
Use ShouldSkipPage function in inno.
Set DisableWelcomePage default value to no in [Setup] section.
[Setup]
DisableWelcomePage=no
Modify your [Code] section as below
[CODE]
function ShouldSkipAutorun():boolean;
begin
Result:=/** add you result here (TRUE or FALSE) **/;
end;
function ShouldSkipPage(PageID: Integer): Boolean;
begin
Result := False;
if PageID = wpWelcome then
begin
Result := ShouldSkipAutorun;
end;
end;
Related
I use this code to ask for a password:
Inno Setup - Move the password page before the welcome page (first page)
And this code for custom language selector:
Inno Setup - Language selector with VCL Styles
When I merge them, it does not work.
I need password before that the language selector, so this is no correct:
function InitializeSetup(): Boolean;
var
Language: string;
begin
Result := True;
Language := ExpandConstant('{param:LANG}');
if Language = '' then
begin
Log('No language specified, showing language dialog');
SelectLanguage();
Result := False;
Exit;
end
else
begin
Log('Language specified, proceeding with installation');
Result := AskPassword();
end;
end;
And this way, with an incorrect password the setup continues.
function InitializeSetup(): Boolean;
var
Language: string;
begin
Result := True;
Language := ExpandConstant('{param:LANG}');
if Language = '' then
begin
Result := AskPassword();
Log('No language specified, showing language dialog');
SelectLanguage();
Result := False;
Exit;
end
else
begin
Log('Language specified, proceeding with installation');
end;
end;
Inno Setup 6
Inno Setup 6 has event attributes features that helps solving this problem.
Just make sure that each of your event implementation have an unique name, e.g. appending unique suffix. And add event attribute with the name of the implemented event.
[Code]
function InitializeSetup(): Boolean;
begin
Result := ...
end;
<event('InitializeSetup')>
function InitializeSetup2(): Boolean;
begin
Result := ...
end;
Inno Setup 5
In general, the easiest is to keep both implementations of the event function separate and add one wrapper implementation that call both.
function InitializeSetup1(): Boolean;
var
Language: string;
begin
Result := True;
Language := ExpandConstant('{param:LANG}');
if Language = '' then
begin
Log('No language specified, showing language dialog');
SelectLanguage();
Result := False;
Exit;
end
else
begin
Log('Language specified, proceeding with installation');
Result := True;
end;
end;
function InitializeSetup2(): Boolean;
begin
Result := AskPassword();
end;
function InitializeSetup(): Boolean;
begin
{ Order the calls the way you want the checks to be performed }
Result :=
InitializeSetup2() and
InitializeSetup1();
end;
For more general discussion of the problem, see
Merging event function (InitializeWizard) implementations from different sources
Though in your specific case, it's more complicated, as you will also need to pass the password from the first instance to the other, similarly to how the language is passed from the first instance to the other.
So actually, the InitializeSetup2 (password) implementation will have to be similar like the InitializeSetup1 (language), not to ask for the password again.
I actually do not really understand, why you complicate the things so much by not asking for language before the password. It would actually make sense. To get a localized password prompt.
How can I prevent showing the splash screen when I need it?
Should I add some ISSI-code to do that?
Here is my code:
#define ISSI_Splash "C:\InnoSetupProject\Images\client.bmp"
#define ISSI_Splash_T 3
#define ISSI_Splash_X 500
#define ISSI_Splash_Y 220
[Code]
function ISSI_InitializeSetup : Boolean;
begin
Result := True;
if not RegValueExists(HKLM, 'SOFTWARE\MyApp\Client', 'LocaleID') then
if MsgBox('Client does not exist', mbCriticalError, MB_OK) = IDOK then
begin
Result := False;
{ How can I prevent showing the splash screen here? }
Exit;
end
end;
#define ISSI_InitializeSetup
#define ISSI_IncludePath "C:\ISSI"
#include ISSI_IncludePath+"\_issi.isi"
Instead of legacy ISSI_InitializeSetup function, use Inno Setup 6 event attributes:
[Code]
<event('InitializeSetup')>
function MyInitializeSetup: Boolean;
begin
Result := True;
if not RegValueExists(HKLM, 'SOFTWARE\MyApp\Client', 'LocaleID') then
if MsgBox('Client does not exist', mbCriticalError, MB_OK) = IDOK then
begin
Result := False;
end;
end;
and remove this:
#define ISSI_InitializeSetup
The MyInitializeSetup will be called before the ISSI InitializeSetup. And if it returns False, the ISSI won't ever be called, so no splash screen will show.
Check the documentation for Event Attributes:
The implementations will be called in order of their definition except that any main implementation (=the implementation without an event attribute) will be called last.
If the event function has a return value then lazy evaluation is performed:
InitializeSetup, BackButtonClick, NextButtonClick, InitializeUninstall:
All implementations must return True for the event function to be treated as returning True and an implementation returning False stops the calls to the other implementations.
I need a simple thing: have advance and normal installation buttons. For normal case it is all simple - I used default next button with some logic on NextButtonClick to set a condition variable and skeep some pages using ShouldSkipPage . Yet for advanced setup I created a new button and all I need it to do on click is to open next installer page:
procedure CurPageChanged(CurPageID : Integer);
begin
if CurPageID = wpWelcome then begin
AdvancedButton := TButton.Create(WizardForm);
AdvancedButton.Caption := 'Advanced Install';
AdvancedButton.Left := WizardForm.InfoAfterPage.Left + 10;
AdvancedButton.Top := WizardForm.InfoAfterPage.Height + 88;
AdvancedButton.Parent := WizardForm.NextButton.Parent;
# AdvancedButton.OnClick := What shall I call to open say next page (or some page by given PageID value)
end
else begin
AdvancedButton.Visible := False;
end;
end;
So What shall I call to open say next page (or some page by given PageID value) on my button click (could not find any NextPage or some SetPage function in Inno API)?
There is no such thing as "Direct jump to page" in Inno Setup.
All you need is to quietly skip certain pages in 'Advanced mode'.
Simply do the same as in regular installer. Set one variable for holding 'Advanced mode'. After clicking the Advance button:
[Code]
var
IsAdvanced: Boolean;
procedure AdvancedButtonClick(Sender: TObject);
begin
IsAdvanced := True;
WizardForm.NextButton.OnClick(nil);
end;
procedure InitializeWizard;
var
AdvancedButton: TNewButton;
begin
// not necessary; just for sure
IsAdvanced := False;
// create the button
AdvancedButton := TNewButton.Create(WizardForm);
AdvancedButton.Caption := 'Advanced Install';
AdvancedButton.Left := WizardForm.InfoAfterPage.Left + 10;
AdvancedButton.Top := WizardForm.InfoAfterPage.Height + 88;
AdvancedButton.Parent := WizardForm.NextButton.Parent;
AdvancedButton.OnClick := #AdvancedButtonClick;
end;
function ShouldSkipPage(PageID: Integer): Boolean;
begin
// the <page where you want to end up> fill with the wizard page constant
// of the page where you want to end up, e.g. wpReady
Result := IsAdvanced and (PageID <> <page where you want to end up>);
end;
With this logic you can simulate quiet 'jump' to certain page.
Is there a way to disable the Components Page for Upgrades? I would like to enable upgrades of my software but I don't want to allow the users to change the selection of components in case of an upgrade.
Instead the installer you upgrade all existing components from the first installation.
I am worried that it the user selects less components during the upgrade those missing components will stay installed as the old version and you get a mess.
I added the following to my script:
[Setup]
DisableDirPage=auto
DisableProgramGroupPage=auto
DirExistsWarning=auto
I just need a way to disable the components page and use the selection of the previous install (full install) for the upgrade. Is that possible?
I have found a related directive:
[Setup]
UsePreviousTasks=true
UsePreviousTasks is reading the existing section out of the registry which is good. Now I need to find a way to hide the selection window.
Thanks,
Wolfgang
To hide a page from user use the ShouldSkipPage event method. If you return True in this method, the page won't be shown to user. If False, the page will be displayed as usually. Here 's an example of how to check if the installation is an upgrade and if so, skip the Select Components wizard page:
[Setup]
AppId=B75E4823-1BC9-4AC6-A645-94027A16F5A5
AppName=My Program
AppVersion=1.5
DefaultDirName={pf}\My Program
; here is the place for your [Components] section and the rest of your script
[Code]
const
UninstallKey = 'Software\Microsoft\Windows\CurrentVersion\Uninstall\{#SetupSetting("AppId")}_is1';
function IsUpgrade: Boolean;
var
Value: string;
begin
Result := (RegQueryStringValue(HKLM, UninstallKey, 'UninstallString', Value) or
RegQueryStringValue(HKCU, UninstallKey, 'UninstallString', Value)) and (Value <> '');
end;
function ShouldSkipPage(PageID: Integer): Boolean;
begin
Result := (PageID = wpSelectComponents) and IsUpgrade;
end;
Another option you mentioned might be to disable all the controls of the page. The next script shows as the previous one how to check if the installation is an upgrade and if so, disables all the controls on the Select Components wizard page:
[Setup]
AppId=B75E4823-1BC9-4AC6-A645-94027A16F5A5
AppName=My Program
AppVersion=1.5
DefaultDirName={pf}\My Program
; here is the place for your [Components] section and the rest of your script
[Code]
const
UninstallKey = 'Software\Microsoft\Windows\CurrentVersion\Uninstall\{#SetupSetting("AppId")}_is1';
function IsUpgrade: Boolean;
var
Value: string;
begin
Result := (RegQueryStringValue(HKLM, UninstallKey, 'UninstallString', Value) or
RegQueryStringValue(HKCU, UninstallKey, 'UninstallString', Value)) and (Value <> '');
end;
procedure DisablePageControls(Page: TNewNotebookPage);
var
I: Integer;
begin
Page.Enabled := False;
for I := 0 to Page.ControlCount - 1 do
Page.Controls[I].Enabled := False;
end;
procedure InitializeWizard;
begin
if IsUpgrade then
DisablePageControls(WizardForm.SelectComponentsPage);
end;
The IsUpgrade function mentioned in TLama's answer has a bug. If AppId starts with a "{" which must be doubled, this isn't resolved and they registry key will not be found. Here's a corrected function that works for me:
function IsUpgrade: Boolean;
var
Value: string;
UninstallKey: string;
begin
UninstallKey := 'Software\Microsoft\Windows\CurrentVersion\Uninstall\' +
ExpandConstant('{#SetupSetting("AppId")}') + '_is1';
Result := (RegQueryStringValue(HKLM, UninstallKey, 'UninstallString', Value) or
RegQueryStringValue(HKCU, UninstallKey, 'UninstallString', Value)) and (Value <> '');
end;
Leave the separate const away for this function, it won't work with that extra function call.
Apart from that, 64-bit systems don't seem to cause any issues. If InnoSetup runs in 32-bit mode, the registry virtualisation is in effect and redirects you to the correct key already.
Something like that:
if CurPageID=wpSelectComponents then
begin
if ExtraOptionAvailable() then
begin
Wizardform.ComponentsList.Checked[6] := true;
Wizardform.ComponentsList.ItemEnabled[6] := true;
end else begin
Wizardform.ComponentsList.Checked[6] := false;
Wizardform.ComponentsList.ItemEnabled[6] := false;
end;
end;
Using Inno Setup 5.5.2 I am trying to conditionally skip selection of the installation directory depending on the existence of a path. Specifically, if the 'D:\' drive is available I want installation to it in a predefined location with no prompts, and if it is not available, provide prompts with a reasonable default.
I have code that works for DefaultDirName, but not for DisableDirPage:
[Code]
const
DefaultDrive = 'D:\';
AppFolder = 'SomeDir';
function GetDefaultDir( Param: String ) : String;
begin
if DirExists( DefaultDrive ) then begin
Result := DefaultDrive + AppFolder;
end else begin
Result := ExpandConstant('{pf}\') + AppFolder;
end;
end;
function DefaultDirValid( Param: String ) : Boolean;
begin
Result := DirExists( DefaultDrive );
end;
[Setup]
; Works as expected
DefaultDirName={code:GetDefaultDir}
...
; Compiler Error - Value of [Setup] section directive "DisableDirPage" is invalid.
DisableDirPage={code:DefaultDirValid}
I have tried using functions for DisableDirPage that return Strings of 'yes' and 'no', as well as Integers of 0 and 1. I have also tried inlining the call to DirExists. All have produced the same compiler error.
My best guess is that it has something to do with the fact that DisableDirPage takes a tri-state yes, no, or auto. Is there a specific type associated with the tri-state logic that needs to be returned? The Inno Help on Scripted Constants only says:
The called function must have 1 String parameter named Param, and must return a String or a Boolean value depending on where the constant is used.
Using the ShouldSkipPage event handler you can skip the directory selection page when the DefaultDrive constant path exists with the following script:
[Setup]
AppName=My Program
AppVersion=1.5
DefaultDirName={code:GetDefaultDir}
[Code]
const
DefaultDrive = 'D:\';
AppFolder = 'Some Folder';
function GetDefaultDir(Param: string): string;
begin
Result := DefaultDrive + AppFolder;
if not DirExists(DefaultDrive) then
Result := ExpandConstant('{pf}\') + AppFolder;
end;
function ShouldSkipPage(PageID: Integer): Boolean;
begin
Result := (PageID = wpSelectDir) and DirExists(DefaultDrive);
end;