Inno Setup customize FinishedLabel with Pascal Script - inno-setup

My goal with Inno Setup 6.x is to customize the FinishedLabel text in code, i.e., Pascal Script. The reason why I'm using Pascal Script is that I want to only customize/change the label if IsAdminMode() is true. How can I do that?
The following two approaches do not work:
Use a scripted constant:
[Messages]
FinishedLabel={code:GetFinishedLabel}
[Code]
function GetFinishedLabel(Param: String): String;
begin
Result := 'BLA';
end;
This shows "{code:GetFinishedLabel}" rather than "BLA".
Customize the wizard in InitializeWizard.
Complete (failing) example:
[Code]
procedure InitializeWizard();
begin
WizardForm.FinishedLabel.Caption := 'BLA';
end;
The FinishLabel still shows the original text from Default.isl
Any ideas?

The FinishedLabel is updated at the end of the installation according to various factors. So your value set in InitializeWizard is overridden. You have to set your custom message later, such as in CurPageChanged(wpFinished):
procedure CurPageChanged(CurPageID: Integer);
begin
if CurPageID = wpFinished then
begin
WizardForm.FinishedLabel.Caption := 'BLA';
end;
end;
You might consider to improve the code to do what Inno Setup would do, like:
Taking into account, if restart is needed (FinishedRestartLabel);
Taking into account, if icons were created (FinishedLabel vs. FinishedLabelNoIcons);
Adjusting the label height to fit the message;
Shifting RunList position according to the message height.

Related

Adding registry value at the beginning of installation with Inno Setup

how can I add a new user environment variable before inno-setup installation begins? the new variable is needed just during the installation process not after!
If you need to write to the registry before the installation starts you can use the CurStepChanged event function. It would be something like this:
procedure CurStepChanged(CurrentStep: TSetupStep);
begin
if CurrentStep = ssInstall then
begin
RegWriteStringValue(...)
end;
end;
There are different RegWrite functions you could use: RegWriteStringValue, RegWriteExpandStringValue, RegWriteMultiStringValue, and others.

How to delete or disable Organization box from UserInfoPage?

Well, as the question says, is there any way to delete or disable organization box?
Here a screenshot:
You can hide both Label and Edit box with CurPageChanged procedure in [Code] section.
[Code]
procedure CurPageChanged(CurPageID: Integer);
begin
if CurPageID = wpUserInfo then begin
WizardForm.UserInfoOrgLabel.Hide();
WizardForm.UserInfoOrgEdit.Hide();
end;
end;

Inno Setup Change AppName based on component(s) selected

I need the installer to show different AppName based on (un)selected components. I tried this:
[Setup]
AppName={code:GetAppName}
AppVersion=1.0
AppVerName=Dagon Video Tools
AppId=Dagon Video Tools
DefaultDirName={sd}\Games\Dagon Video Tools
[Code]
function GetAppName(Value: string): string;
var
CurPageID: Integer;
Begin
Result := 'Dagon Video Tools'
if (CurPageID=wpSelectComponents) and IsComponentSelected('Slasher') and not IsComponentSelected('Frankenstein') then
begin
Result := 'Dagon Slasher';
end;
if (CurPageID=wpSelectComponents) and IsComponentSelected('Frankenstein') and not IsComponentSelected('Slasher') then
begin
Result := 'Dagon Frankenstein';
end;
if (CurPageID=wpSelectComponents) and IsComponentSelected('Slasher') and IsComponentSelected('Frankenstein') then
begin
Result := 'Dagon Video Tools';
end;
End;
But, as you can guess, this doesn't work. Is this script incomplete or should it be done in a different way altogether?
The AppName directive value is resolved (= your GetAppName is called) immediately after the InitializeSetup (if any) finishes. That is a long before the user is able to change the components.
So you cannot make AppName depend on the selected components.
Some uses of the AppName could be overridden with a custom value though, but not all. See below.
Though, as I know that your question is actually about a setup type, you can do this:
Create custom "type" page (like a menu) as the very first one.
Once the user selects the "type", restart the installer with a custom switch (e.g. /APPTYPE=slasher) and exit.
Once the installer is (re-)run with the /APPTYPE, you know from the beginning, what component/type you are installing and hence you can set the AppName normally.
Of course, you skip the custom "type" page.
This is actually a way simpler to implement. The only drawback is that the setup window is "recreated" after the user selects the "type".
This is the original response in case you do not want to use the above solution.
First, your implementation of the GetAppName is wrong. You are using an uninitialized variable CurPageID. And anyway, as mentioned already, the GetAppName is called even before the wizard window is created, so "current page" is irrelevant here.
The correct implementation would be like:
function GetAppName(Value: string): string;
begin
if IsComponentSelected('Slasher') and not IsComponentSelected('Frankenstein') then
begin
Result := 'Dagon Slasher';
end
else
if IsComponentSelected('Frankenstein') and not IsComponentSelected('Slasher') then
begin
Result := 'Dagon Frankenstein';
end
else
begin
Result := 'Dagon Video Tools';
end;
end;
But this still won't make it working in the AppName directive. We will use it in other contexts though later.
Also note that for your specific installer, you should better use the WizardSetupType(false) function instead of the IsComponentSelected.
FinishedLabel
Just override the Inno Setup default text in CurPageChanged(wpFinished):
procedure CurPageChanged(CurPageID: Integer);
var
S: string;
begin
if CurPageID = wpFinished then
begin
S := SetupMessage(msgFinishedHeadingLabel);
StringChange(S, '[name]', GetAppName(''));
WizardForm.FinishedHeadingLabel.Caption := S;
WizardForm.AdjustLabelHeight(WizardForm.FinishedHeadingLabel);
{ Ideally we should shift the FinishedLabel up or down here, }
{ if the height of the header changed. }
{ Note that other messages (msgFinishedLabelNoIcons or msgFinishedRestartLabel) }
{ are used in special situations, so this is not a complete solution. }
S := SetupMessage(msgFinishedLabel);
StringChange(S, '[name]', GetAppName(''));
WizardForm.FinishedLabel.Caption := S;
WizardForm.AdjustLabelHeight(WizardForm.FinishedLabel);
end;
end;
Add/Remove Programs
That's easy. There's the UninstallDisplayName directive for this, which is resolved only during the actual installation, when we already know the selected components. So we can use your (fixed) GetAppName here:
[Setup]
UninstallDisplayName={code:GetAppName}
Are you sure you want to completely remove AppName and all of its components?
You cannot change that. You better use some generic name in the AppName so that this message works for any component.
Or make the message not mention the application name at all:
[Messages]
ConfirmUninstall=Are you sure you want to completely remove this game?
Alternatively remove the message completely:
Replace or customize modal uninstallation windows in Inno Setup
Please wait while AppName is removed from your computer
The same solution as for the WizardForm.FinishedLabel. Just use the UninstallProgressForm.PageDescriptionLabel from the InitializeUninstallProgressForm.
AppName was successfully removed from your computer
Similar as with the "Are you sure you want to completely remove AppName and all of its components?"
Either make the AppName generic. Or disable the message with "silent" mode and implement your own message in the CurUninstallStepChanged(usPostUninstall).
Again, see Replace or customize modal uninstallation windows in Inno Setup.
For a similar discussion, see also Changing AppName and AppDir depending on language in Inno Setup.

Programmatically set Inno Setup Uninstall window caption

How to change the title of the window at the uninstall?
We need to do this using code, similarly to this code for install window caption:
procedure InitializeWizard();
begin
WizardForm.Caption := 'Setup Application';
end;
Use UninstallProgressForm global variable from InitializeUninstallProgressForm event function to access uninstall form.
[Code]
procedure InitializeUninstallProgressForm();
begin
UninstallProgressForm.Caption := 'Uninstalling';
end;

Inno Setup: Create simplified ComponentsList

I have only two components for a user to choose from when installing. Neither depends on each other, and none has any constraints. I’d like to present two simple checkboxes with no extra layout, instead of the complexity of TNewCheckListBox (i.e. ComponentsList). Is there a way to do this?
Here's an image of what I'm after:
Thanks for any help!
Not sure what you mean by "complexity". If it's just about the list looking as a list box, what about styling it not to look like a list?
procedure InitializeWizard();
begin
WizardForm.ComponentsList.BorderStyle := bsNone;
WizardForm.ComponentsList.ParentColor := True;
WizardForm.ComponentsList.Top := WizardForm.SelectComponentsLabel.Top;
WizardForm.ComponentsDiskSpaceLabel.Visible := False;
WizardForm.SelectComponentsLabel.Visible := False;
end;

Resources