Using INI file to fill setup section values on inno setup - inno-setup

I'm trying fill setup section values with {param} and {ini} like this:
VersionInfoProductName={param:NAME|My Product}
VersionInfoTextVersion={ini:ExpandConstant({src})\config.ini,setupValues,version|unknow}
But it is not working, in EXE properties is showing {param:NAME|My Product}
I also tried with GetIniString but same result.
How can I put ini values in Setup section?

You cannot use any of the constants you have used, because both directives you're trying to fill need to be filled at compilation time. You will need to use the preprocessor function equivalent, because only the preprocessor can fill the directive values before the compilation starts.
The preprocessor's equivalent for reading from INI files is the ReadIni function, which you can use the way which follows. Assuming you have a config.ini file stored in the same location as the script with this content:
[setupValues]
version=1.2.3.0
You can fill the value of the VersionInfoVersion directive this way. I have used this directive, since the value of the VersionInfoTextVersion directive is displayed only on Windows 98 below systems and I believe you're not running such an old system to ever verify this:
[Setup]
VersionInfoVersion={#ReadIni(SourcePath + "config.ini", "setupValues", "version", "")}
Note, that the SourcePath variable used in the above code is a predefined variable that can be evaluated from preprocessor. The result you can then verify by checking the setup binary file properties and you will see e.g. this:

Related

How to read command line parameter in InstallShield script

Suppose I run my installer like this:
setup.exe /v"PARAMETER=Value"
How can I read PARAMETER? The documentation proposes to use GetProfString and GetProfInt, but which folder should I use?
For me the folders for setup.ini were I thought parameters would go are as follows:
ENGINECOMMONDIR
ENGINEDIR
C:\Users\user_name\AppData\Local\Temp\{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}
SRCDIR
C:\Users\user_name\AppData\Local\Temp\{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}\Disk1
But instead one needs to use system string variable CMDLINE.
Your reference to CMDLINE suggests you are using an InstallScript or InstallScript MSI project, which is populated through the /z notation to its setup.exe.
The /v"PARAMETER=Value" notation applies to the setup.exe used for Windows Installer projects, passing PARAMETER=Value to Windows Installer, which in turns sets the Windows Installer property PARAMETER to Value. The way to read it depends on the context in which you need it, but typically involves either a formatted text field including a reference to the property (e.g. [PARAMETER]), or code that retrieves a property through e.g. MsiGetProperty(hInstall, L"PARAMETER", buf, bufsize) (C++) or Session.Property("PARAMETER") (VB).

Why doesn't Inno Setup constant {userdesktop} work in OutputDir directive and how to fix it?

I created Inno Setup script, which works perfectly, but I wanted to change OutputDir to create the output file on my desktop. But instead of creating output file on desktop it was creating subfolder {userdesktop} at the same directory, where script is and output was inside.
I found solution so far, but I believe there should be better way. What am I missing?
; these attempts didn't work
[Setup]
OutputDir={userdesktop}
; some more attampts:
OutputDir=userdesktop
OutputDir=userdesktop:
OutputDir="{userdesktop}"
; this workaround worked for me
[Setup]
OutputDir=userdocs:..\Desktop
Constants like {userdesktop} are resolved on install time (on the target user's machine), not on compile time (on your development machine). So it makes no sense to use constants in compile-time only directive like OutputDir. And actually it's not possible to use them at all (as it's useless).
With the default user profile directory layout, use you can use the userdocs: prefix, as you did:
[Setup]
OutputDir=userdocs:..\Desktop
Though it's not a perfect solution, as the "Documents" folder can be moved by the user and then the userdocs:..\Desktop will not point to the desktop.
A more reliable solution is to use USERPROFILE environment variable using GetEnv preprocessor function:
[Setup]
OutputDir={#GetEnv('USERPROFILE')}\Desktop

How to get the file name of the current Inno Setup script file?

I want to obtain the name of the current Inno Setup script file in order to name the generated setup package after it. For example if the current Inno Setup script file is "MyAppSetup.iss", I want the generated setup file to be "MyAppSetup.exe".
The name of the generated setup file is controlled by the OutputBaseFilename declaration in the [Setup] section of Inno Setup, so if there's an Inno Setup preprocessor variable that returns the name of the current script file that would be great. Something like:
OutputBaseFilename={#SourceFileName}.exe
Unfortunately, there isn't an Inno Setup preprocessor variable {#SourceFileName}. I know about the {#SourcePath} variable, but it returns the directory path of the script file without it's file name. Here's a list with some predefined Inno Setup preprocessor variables, but none of them seems to return the name of the current script file. I hoped the __FILE__ variable would work after reading the descriptions of the variables in the list, but it returns an empty string.
It's not possible. There's the __FILE__, but it has a value for #included files only.
If you never have more than one .iss file in a directory, you can use the FindFirst to find its name.
#define ScriptFindHandle = FindFirst(SourcePath + "\*.iss", 0)
#if !ScriptFindHandle
#error "No script found"
#endif
#define SourceFileName = FindGetFileName(ScriptFindHandle)
#if FindNext(ScriptFindHandle)
#error "More than one script found"
#endif
#expr FindClose(ScriptFindHandle)
#define SourceBaseName = RemoveFileExt(SourceFileName)
Then to name the setup file after the current script file in the [Setup] section you should use:
[Setup]
OutputBaseFilename={#SourceBaseName}
But if you are automating compilation of a large number of installers, I assume you use a command-line compilation. So then you can simply pass a script name in a parent batch file (or a similar script):
set SCRIPT=MyAppSetup
"C:\Program Files (x86)\Inno Setup 5\ISCC.exe" %SCRIPT%.iss /DBaseName=%SCRIPT%
Use the BaseName like:
[Setup]
OutputBaseFilename={#BaseName}
I know this is not exactly what you want, but why can't you do this:
[ISPP]
#define ScriptFileName "MyAppSetup"
[Setup]
AppPublisher={#AppPublisher}
OutputBaseFilename={#ScriptFileName}Setup
Then all you need to do it edit the one reference at the top of your file.
Update
I came across this link where it states:
You can use:
#expr SetSetupSetting("OutputBaseFilename", sFileName)
However, the difficult part is automatically finding the file name.
You could use the following ISPP functions to do additional
compile-time tasks that can't be done by ISPP built-in functions:
Exec function: Executes an external program to do the additional
functionality, and writes the result to an INI file. By default Exec
waits for the process to finish.
ReadIni function: Reads the result
from the INI file, and incorporates it into the script.
How do you determine the file name is up to you. Perhaps you could
enumerate the windows and extract the file name from Inno Setup
window title, but because you may be having multiple Inno Setup
copies open, you must find a reliable way to do it. Inno adds
[Compiling] to the title during compilation which makes it easier to
find which copy is being used, but there could be multiple copies in
compiling state. You can be absolutely sure about which copy is
running your program by checking the process ID of the parent
process, you can get that by using Process32First/Process32Next and
checking the 32ParentProcessID for your process. Too much work, I
know..
But there was another comment:
(If you're doing an automated build, though, you can set the output
filename from the command line -- that might be sufficient for what
you actually want.)
So have you considered using a batch file and the command line? Then you can use the benefits of batch lines with your compiling. Information is provided here about using the current file name in batch files.
I personally think that the batch file compilation is the way to go.

Read file contents to variable in grub.cfg file

Q1. Wanted to know how do you read the contents of a file to a variable at boot time in grub.cfg?
Q2. Could that be extended to read an .ini type file where you can read the values for various name entries?
[section]
nothisone=whatever
thisone=this is what I want to get
TIA!!
In order to do exactly what you are asking for, you would probably need to write your own GRUB module.
However, you should be able to achieve what you're after either using the configfile command, or with some clever application of the environment block feature.
Use "source" command to include another config file but unlike "configfile" which will change context.
Source is like an online macro while configfile likes a function - environment changes in configfile will not be preserved but source is expanding whatever in the source file and put in the main block, environment variable can be changed in this way.
https://www.gnu.org/software/grub/manual/grub/grub.html#source
https://www.gnu.org/software/grub/manual/grub/grub.html#configfile

Get the path specified in the source of file section

Is there any way by which we can get the path of the source file in [file] section be made available in [code] section. I need to have the full path as been given in the source. I need to check it with the content of a file and if the path is present in the file, then only i need to copy that particular file. I am using Check: in the file section and need to have the whole path of file made available in code section for comparison.
To get the chosen install folder from pascal script, you can use either ExpandConstant('{app}') or WizardDirValue(). Note that I don't think the returned path contains a trailing backslash.
This would simply check a file existence:
function IsMyFilePresent: Boolean;
begin
Result:=FileExists(ExpandConstant('{app}\filename.ext'));
end;
If it's an ini file, you can use this code to retrieve the data of certain keys inside it:
(example using WizardDirValue())
inifile:=WizardDirValue()+'\filename.ext';
MyString:=GetIniString('SectionName', 'KeyName', 'DefaultValue', inifile);
Probably the CurrentFileName() function that:
Returns the destination name of the [Files] entry that is currently being processed.
You can probably work out the source from this. I'm not sure how it handles wildcards though (but I suspect it just returns "blah/*"

Resources