Read text file line by line in Inno Setup - inno-setup

I'm trying to read a text file line by line using Inno Setup.
I have tried this one that mentioned here: https://jrsoftware.org/ispphelp/index.php?topic=fileread
function ShowLines(): Boolean;
var
list: Integer;
begin
list := FileOpen(ExpandConstant('{tmp}\file.txt'));
if !FileEof(list) then begin
try
repeat
MsgBox(FileRead(list), mbInformation, MB_OK);
until !FileEof(list);
finally
FileClose(list);
end;
end;
Result := True;
end;
But it will give error, on FileOpen (and maybe on other File functions) that it is an unknown identifier. Where is the problem?
The file is less than 50kb.

All the functions you are trying to call from Pascal Script are actually preprocessor functions. The Pascal Script does not have built-in function that can read file by line (or any kind of chunk).
You can implement that using WinAPI file functions, like CreateFile and ReadFile.
But if the file is not too big, you can simply use built-in function LoadStringsFromFile. For an example, see Read strings from file and give option to choose installation.
Similar question: "Unknown Identifier 'FileOpen'" when trying to detect locked file in Inno Setup code.
Seeing that you are reading the file from {tmp}, chances are that you are actually reading a temporary file extracted from the installer itself. If that's the case, it means that you have the file available on compile time already. In such case, you can indeed use the preprocessor function to read the file on compile-time.
But that needs code in completely different language/syntax. Some examples:
How to use wildcards in [CustomMessages] section of Inno Setup?
Can I use .isl files for the messages with preprocessor directives in Inno Setup?

Related

Read contents of a file from within Inno Setup installer

I am using Inno Setup. I read from file with
LoadStringsFromFile(My_file, Lines)
but the file is outside installation file defined with
OutputBaseFilename={#MySetupExeName}
Can I open a file inside iss code, and this file to be in installation file (OutputBaseFilename)?
Use ExtractTemporaryFile:
[Files]
Source: myfile.txt; Flags: dontcopy
[Code]
...
ExtractTemporaryFile('myfile.txt');
LoadStringsFromFile(ExpandConstant('{tmp}\myfile.txt'), Lines);
...
Though as the contents is fixed, you can as well hard-code it.
Or read it from the file on compile-time, instead of having to extract the file on install-time. You can use preprocessor FileRead function for that. Though it's more complicated than the straightforward code above. We would have to know more about that you need the contents for and how it looks like to offer an efficient solution.

Inno Setup - How to copy the created setup file

I want to copy the created setup file to a network directory. I think the [Run] section will be the best position to do this, but I cannot not found any possibility to call my copy function. Any idea to this issue?
Also, is it possible to use variables declared in the [setup] section for the copy path?
My procedure will be like this (trying to use the variables):
[Code]
procedure CopyFile();
begin
FileCopy('{OutputDir}/{OutputBaseFilename}',
'V:/Service/Software/ASCDeploy/Prod/Asc.Tools.FileCopy/{OutputBaseFilename}', False);
end;
There's no way to run any code after Inno Setup finishes compiling - At least not in the original Inno Setup.
See also Inno Setup - Post Processing.

Inno Setup: Download setup .bin slice files before installation starts

I am trying to create a distributable .exe file with Inno Setup tools and Inno Download Plugin. The resulting file is ~3GB in size, split in 6 parts (1 for the executable, 5 bins containing all the files).
Would it be possible to keep the 5 bins uploaded on some server and download them during installation with the remaining executable file?
My code is here :
procedure InitializeWizard();
var
ResultCode: integer;
TempAddress: String;
FinalSavePath: String;
UserName, UserCompany: String;
begin
idpSetOption('DetailedMode', '1');
idpSetOption('AllowContinue', '1');
idpSetLogin('aaa', 'aaa');
idpAddFile('https://...', target_path);
idpAddFile('https://...', target_path);
idpAddFile('https://...', target_path);
idpAddFile('https://...', target_path);
idpDownloadAfter(wpWelcome);
end;
With idpDownloadAfter(wpWelcome) the installer starts downloading right after accepting to run the executable, if .bin files are already present. If not, the installer just keeps asking for the .bin to be present.
Inno Setup 6.1 has a built-in support for file downloads, which does not need any support files. So the solution below is obsolete now. See Inno Setup: Install file from Internet.
Inno Download Plugin uses idp.dll, which itself is stored in the mysetup-*.bin files. That's why you get prompted for the .bin files, even before anything starts. You need the idp.dll so that the download itself can start.
With some hacking you can have the idp.dll be stored in the [Code], hence directly in the mysetup.exe.
See Inno Setup: Reading a file from installer during uninstallation.
You will need to modify the idp.iss as follows:
Remove the [Files] section with its reference to idp.dll.
In all the external functions declarations:
change #files:idp.dll cdecl to #{tmp}\idp.dll cdecl delayload.
To the front of your .iss script, copy the long code block from my answer to the previously mentioned question.
And now you can do:
procedure InitializeWizard();
begin
SaveBinaryStringToFile(
ExpandConstant('{tmp}\idp.dll'), {#FileToBinaryString("unicode\idp.dll")});
idpAddFile(
'https://www.example.com/mysetup-1.bin', ExpandConstant('{src}\mysetup-1.bin'));
idpDownloadAfter( {whatever} );
end;
Make sure you update the path to the idp.dll to the correct location on your development machine in the call to FileToBinaryString.
The code is for Unicode version of Inno Setup (the only version as of Inno Setup 6).

Checking existence of a file in Inno Setup Internal Temporary folder

I want my Inno Setup Script to search for my setup's .TMP file which usually creates in currently logged user's Local Application Data folder and give user a message box saying "Your Setup's Temporary Source seems to be created successfully."
I wrote a code to do so:
if CurPageID = wpLicence then begin
if FileExists((ExpandConstant('{localappdata}\Temp\is-*****.tmp\MySetup.tmp'))) then begin
MsgBox('Your Setup''s Temporary Source seems to be created successfully.', mbInformation, MB_OK);
MsgBox('It is located in: <<I WANT TO GET THE FOUND FILE''S FULL PATH HERE>>', mbWarning, MB_OK);
end;
end;
But, even my setup's temporary file (MySetup.tmp) exists when the setup starts, I'm not getting those message boxes.
What is the problem in this code?
Is the is-***** ignored when searching?
UPDATED QUESTION
I mean The Temporary Directory shown in below image. It contains the internal Temporary File of the Setup Wizard. This is usually named like {#SetupName}.tmp...... Not the other Temporary Directory which Inno Setup extracts Files of the Setup. such as ISSKin.dll or any externally used files.
Any help would be greatly appreciated.
The FileExists function does not support wildcards, not even in a file name, let alone in a name of a parent folder.
See How to test using wildcards whether a file exists in Inno Setup.
Though in your case, just use the ParamStr(0).
FileExists(ParamStr(0))

Can I put setup command line parameters in a file which is called during installation instead?

After creating my setup.exe I have to pack it for various software deployment tools. Therefore I can't call the setup.exe with parameters, instead I have placed my own parameters in a setup.ini file next to the setup.exe
[Code]
var
MyIniFile: String;
function InitializeSetup(): Boolean;
var
LoadFromIniFile: String;
begin
Result := true;
MyIniFile := ExpandConstant('{srcexe}'); //writes the full path of the setup.exe in "MyIniFile"
MyIniFile := Copy(MyIniFile, 1, Length(MyIniFile) - Length(ExtractFileExt(MyIniFile))) + '.ini'; //changes the ".exe" into ".ini"
if FileExists(MyIniFile) then LoadFromIniFile := MyIniFile; //checks wether there is a ini-file
if LoadFromIniFile <> '' then begin
MyLogFile := GetIniString('Setup', 'Log', MyLogFile , LoadFromIniFile);
ProductName := GetIniString('Setup', 'ProductName', ProductName, LoadFromIniFile);
end;
end;
Now I want to also place the so called "Setup Command Line Parameters" (listed on the Inno Setup Help site) in my ini-file. I think that there is a way for the /Dir="x:\dirname parameter, which I did not figure out yet. But I also want to have the /SILENT parameter in there, do you think there is a way to do this? If yes, how would you do this? If not, can you please give me a hint why not?
So customize your installer for different products, I'd recommend you to use a pre-processor and automatically build the installer for each product (with different "defines"), instead of using an external INI file.
For example to be able to change application name and resulting executable when building the installer, use a script like:
[Setup]
AppName={#AppName}
OutputBaseFilename={#BaseFilename}
Now you can create two different installers automatically using command-line:
ISCC.exe Example1.iss /dAppName=App1 /dBaseFilename=SetupApp1
ISCC.exe Example1.iss /dAppName=App2 /dBaseFilename=SetupApp2
Regarding the implicit silent installation:
There's no API other than the command-line /SILENT switch to trigger silent installation.
But you can create a near-silent installation by disabling most installer pages:
[Setup]
DisableWelcomePage=true
DisableDirPage=true
DisableProgramGroupPage=true
DisableReadyPage=true
DisableFinishedPage=true
Actually the above example disables all default pages. But Inno Setup compiler will ignore the DisableReadyPage=true, if all other previous pages are disabled.
You may want to choose a different page to show instead. For example a Welcome page (by omitting DisableWelcomePage=true, but keeping the DisableReadyPage=true).
If you do not mind about using external files (as you already use an external INI file), you can of course wrap the installer to a batch file and call the installer with the /SILENT switch.

Resources