Inno Setup: Invalid Prototype - inno-setup

I am getting an "Invalid prototype for 'CheckForFile'". After hours and hours of trying to make setup download and install file (download part works, but I cannot find a way to run downloaded file), I am out of ideas. Why I am getting that error on this?
[Run]
Filename: "{tmp}\AcroRdrDC1800920044_en_US.exe"; Description: "Install Adobe Reader"; Flags: shellexec skipifsilent; BeforeInstall: CheckForFile('{tmp}\AcroRdrDC1800920044_en_US.exe');
[Code]
function CheckForFile(Param: String): Boolean;
begin
Result := FileExists(Param)
end;

While there already is some truth within the comments, I'd like to share what I've learned so far anyway, just in case anyone needs it.
My observations are
If I use the Check parameter with a function that returns a boolean, there is no Invalid Prototype error
If I use the BeforeInstall or AfterInstall parameter with a procedure there is no error either
Any other combination will cause the error
This led me to the following conclusion:
When using a procedure or function within the parameters of [Files] entry, Inno Setup creates a prototype for this function or procedure.
A procedure prototype for BeforeInstall and AfterInstall, since these do not expect a return value
A function : boolean protoype for Check, because this one expects a return value
After processing the [Files] section, the [Code] section is processed. Since a prototype for CheckForFile has already been declared as procedure CheckFile(...); the declaration function CheckFile(...) : boolean does not match the prototype and the error is shown.
Therefor changing the function to a procedure would work techically, but using Check would be the way to go in your case. In cases when we want to execute something before the installation, BeforeInstall is the way to go, but it does not allow returning values.

Related

Inno Setup: how to call custom functions from the InstallDelete section

I would need Inno Setup generated installer to delete certain files prior installation if the software is already installed with an older version.
I tried to do this by comparing version numbers (custom function below) but when compiling, Inno Setup generates an error:
[ISPP] Undeclared identifier: "GetInstalledVersion".
The Inno Setup script relevant extract is:
(...)
[Code]
function GetInstalledVersion(MandatoryButNotUsedParam: String): String;
var Version: String;
begin
if RegValueExists(HKEY_LOCAL_MACHINE,'Software\Microsoft\Windows\CurrentVersion\Uninstall\'+ExpandConstant('AppId')+'_is1', 'DisplayVersion') then
begin
RegQueryStringValue(HKEY_LOCAL_MACHINE,'Software\Microsoft\Windows\CurrentVersion\Uninstall\'+ExpandConstant('AppId')+'_is1', 'DisplayVersion', Version);
MsgBox(ExpandConstant('Existing version:'+Version+' New version:'+ExpandConstant('AppVersion')), mbInformation, MB_OK);
Result := Version;
end
else
begin
Result := '';
end
end;
(...)
[InstallDelete]
#define InstalledAppVersion GetInstalledVersion('')
#if "1.013" > InstalledAppVersion
Type: files; Name: {userappdata}\xxx\*.hhd
#endif
Being new to Inno Setup, this is certainly a trivial question but no answer found on forums. The question is thus: how can I properly call the function GetInstalledVersion from the [InstallDelete] section?
Is there an issue because [InstallDelete] section might be called before [code] section is read?
Many thanks for any help / hint!
Do you want to check for currently installed version and if it's below 1.013,
then remove user files from {userappdata}\xxx\*.hhd ?
then what you need is parameter Check http://www.jrsoftware.org/ishelp/index.php?topic=scriptcheck
[Code]
function isOldVersionInstalled: Boolean;
begin
// Result := <True|False>;
end;
[InstallDelete]
Type: files; Name: {userappdata}\xxx\*.hhd; Check:isOldVersionInstalled;
What is wrong with your example:
You are calling a Pascal function from the pre-processor.
Those are two different things.
You can define a macro in pre-processor - that's kind of like a function,
but that's not what you want because Pre-processor only runs on compile time and so it can't be used to check on state of User's files/environment.

Can you define a function prototype in Inno Setup

I would like to be able to structure my code for my Inno Setup project but I am forced to move code around because you can't call a function unless it is defined first.
Is there a way to declare a prototype at the top so that I don't get the "Unknown identifier" error and so that I can structure my code in logical blocks.
In Pascal (including a Pascal Script used in Inno Setup), you can define a function prototype (aka forward declaration) using a forward keyword:
procedure ProcA(ParamA: Integer); forward;
procedure ProcB;
begin
ProcA(1);
end;
procedure ProcA(ParamA: Integer);
begin
{ some code }
end;
See Forward declared functions.

How to use AObject in the AddCheckBox function when using the componentslist?

I am trying to understand the AddCheckBox function in inno pascal script. The documentation is limited:
http://www.jrsoftware.org/ishelp/index.php?topic=scriptclasses
function AddCheckBox(const ACaption, ASubItem: String; ALevel: Byte; AChecked, AEnabled, AHasInternalChildren, ACheckWhenParentChecked: Boolean; AObject: TObject): Integer;
How to use the "AObject" argument? Of course I can just use "nil" but this causes an error message about a memory once the user clicks on the added checkbox.
It may be relevant that I want to add a checkbox to the componentslist (dynamically) of the WizardForm. So it is something like:
WizardForm.ComponentsList.AddCheckbox(..please help me with the correct arguments).
The function seems useful but to use it, I need to know what arguments to use and what they mean.

Calling Two Procedures in [code] from [Run] Afterinstall

I have two Procedures in my code section Pro1 and Pro2, the pro1 takes value from user and pro2 uses that value so i want these procedures to be executed one after another in same order.
I know that we can call procedure from [Run] section using Afetrinstall. Can i call these two procedures Pro1 and Pro2 using single Afterinstall in the same order?
One more thing, how can i call a particular Filename in the run section based on condition written in the code? is that even possible? can i call the same File name more than once .I'm new to inno can anyone help me.
Is it possible to assign more than one function to the "AfterInstall" parameter ?
No, this is not possible, but you can simply call one function from the other. So, you will assign a function to the AfterInstall parameter and the other function call from the assigned one. In script it may look like this:
[Files]
Source: "MyProg.exe"; DestDir: "{app}"; AfterInstall: AfterInstallProc
[Code]
procedure AfterInstallProc;
begin
// do something here
AnotherProcedure;
end;
procedure AnotherProcedure;
begin
// do something else here
end;
Is it possible to conditionally assign value to the "Filename" parameter of a [Run] section entry ?
Yes, it is. You can declare so called scripted constant which is a constant with assigned function in which you can return the value to the parameter. In a script example like this:
[Run]
Filename: "{code:GetRunEntryFileName}";
[Code]
function GetRunEntryFileName(Value: string): string;
begin
// the "SomeCondition" is meant to be a certain variable or statement which
// evaluates upon your needs; to the Result you'll return the same as you'd
// write in the script including constants, like e.g. '{app}\MyProg.exe'
if SomeCondition then
Result := 'calc.exe'
else
Result := 'charmap.exe';
end;
The similar you can apply for all the parameters of the [Run] section except to the Flags parameter, which must be known at compilation time.
Can I execute the same application from [Run] section ?
Yes, you can. This section doesn't care of what you're executing, so there can be even exactly the same entries, or just entries for the same application multiple times. So even this is possible:
[Run]
Filename: "{app}\MyProg.exe";
Filename: "{app}\MyProg.exe";
Filename: "{app}\MyProg.exe"; Parameters: "/x"
But this may have practical sense only if you are running e.g. a certain external installer where you need to call it more than once with different command line parameters. I can't think of a reason to execute the same application the very same way more than once.

Is it possible to test Pascal Script functions without compiling the installer?

I am wondering if it is somehow possible to test the functions in my [Code] section without compiling the whole installer each time and run it. This would make the development and testing of the functions much easier.
Many thanks!
Sören
The direct answer to the question "Is it possible to test Pascal Script functions without compiling the installer?" is "no." Compilation is required to run the code. The real issue, I think, is not that compilation is required but rather that large projects can be time-consuming to recompile when you are performing code testing.
One workaround for time-consuming recompiles is to create a "stub" setup for code testing. Simple example:
[Setup]
AppName=TestCode
ArchitecturesInstallIn64BitMode=x64
AppVerName=TestCode
UsePreviousAppDir=false
DefaultDirName={commonpf}\TestCode
Uninstallable=false
OutputDir=.
OutputBaseFilename=TestCode
PrivilegesRequired=none
[Messages]
SetupAppTitle=TestCode
[Code]
function BoolToStr(const B: Boolean): string;
begin
if B then
result := 'true'
else
result := 'false';
end;
procedure Test();
begin
MsgBox(BoolToStr(true), mbInformation, MB_OK);
end;
function InitializeSetup(): Boolean;
begin
result := false;
Test();
end;
In the InitializeSetup event function we set result to false so nothing actually gets "installed"; the whole purpose is simply to run the Test procedure and then terminate. The Test procedure tests the sample BoolToStr function to make sure it works as expected.
When you are certain your code works as expected, you can copy it to your main project. (Don't forget to copy all dependencies such as global variables, DLL import statements, etc.)
I think yes
For compiling:
Use 'Ctrl+F9'
For testing
use only 'F9' (_without '' in inno setup).
Thanks.
EDIT:
Sorry You cant use this Processes.Look into Tlama comment.

Resources