Inno Setup - How to copy the created setup file - inno-setup

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.

Related

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).

Inno Setup Call AfterInstall for each external File

I am really struggling with this one. I have an entry in the files section of an Inno Setup (5.5.9) configuration file, that is something like the following:
[Code]
procedure showMsgBoxOfFile;
begin
MsgBox(ExpandConstant(CurrentFilename), mbInformation, MB_OK);
end;
[Files]
Source: {src}\Some\Path\myFile*Pattern.ext; DestDir: {app}; Flags: external; \
AfterInstall: showMsgBoxOfFile;
When I run the installer generated by running the above script, I get a single message box with the {app} directory, even though four files are copied. This seems to be in direct contradiction of the Inno Setup documentation on BeforeInstall/AfterInstall, which states:
A BeforeInstall or AfterInstall function for a [Files] section entry using a wildcard is called once per file matching the wildcard. Use CurrentFileName to check for which file the function is called.
Further, another question on Stack Overflow is from a user who wanted to do the exact opposite (get only one notification when multiple files were changed). The accepted answer to that question indicates that:
there is no way to call [AfterInstall] once after all the files are installed
I noticed that if I remove the "external" flag from my file copy, I DO get one message box per file. Is there a way to get a one notification per copied file when the "external" flag is specified? Does anyone know if there is a plan to document this difference in the Inno Setup help files?
Indeed, for entries with the external flag, the BeforeInstall and AnswerInstall functions are called only once.
What you can do, is to copy the files programmatically. It would give you a full control over, what you do for each file.
See Inno Setup: copy folder, subfolders and files recursively in Code section

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.

Innosetup, best practice custom installation pass variables to external application

I've got an installation task using InnoSetup which I'm not quite sure how to do properly.
Situation is as follows:
1 innosetup custom page with some textboxes and checkboxes. Basically containing targeturl, and a windows servicename. Might be more later.
This custom information needs to be passed on to two different app.config files.
Question is now, how to do this?
My first intention was to use the [Run] segment with a bunch of parameters such as:
[Run]
Filename: {app}\MyApp.exe; Parameters: /install; Flags: runminimized
But I don't know how to pass the custom data to the application.
Perhaps one can create some environment variables and pass the data that way?
Perhaps one can create a temporary file with necessary values?
Perhaps one should do this in a loaded dll during the installation and not post install?
Any suggestions would be very much appreciated.
and thankyou. For "#DenverCoder9":
Basically what I ended up doing, which is almost line for line in the bundled examples from Inno-setup. Missed the fact that Inno-setup allows for XML manipuation (via MSXML), which allowed me to to:
include a sample configuration file (app.config.sample).
load the sample configuration file
modify it using the collected data from the custom form.
save it to the correct location.
[Files]
...
Source: ..\UpdateService\UpdateService\Server\bin\Release\UpdateService.exe.config; DestDir: {app}; Permissions: users-modify; Flags: comparetimestamp onlyifdoesntexist; AfterInstall: MyAfterInstall;
[Code]
procedure MyAfterInstall();
var XMLDoc : Variant;
var RootNode : Variant;
begin
// if(FLAG_UPDATE_SERVICE_CONFIG) then begin
XMLDoc := CreateOleObject('MSXML2.DOMDocument');
XMLDoc.async := False;
XMLDoc.resolveExternals := False;
XMLDoc.load(ExpandConstant(CurrentFilename));
RootNode := XMLDoc.documentElement;
...
end;
end;
This has the added benefit that I have a sample file to provide for anyone who needs to modify the application by hand.
Can you not use command-line arguments to pass values entered in your Inno Setup installer to an external application?
The external application (which I assume is .NET) can handle writing the values from the command-line to configuration files (i.e. 'App.config'). The Main(string[] args) method of the .NET application can examine the command-line argument values. Use the [Run] section as you suggested and pass these values as parameters (using Parameters).

Is it possible to change the window title bar of your installer using Inno Setup?

Is it possible to change the title bar of your installer using Inno Setup?
By default is:
AppName=My Program
and when you run the setup in the title bar appears:
Setup - My Program
Is it possible to hide the word "Setup"?
Add the following lines to your InnoSetup script file:
[Messages]
// define wizard title and tray status msg
// both are normally defined in innosetup's default.isl (install folder)
SetupAppTitle = Setup YourApplicationShortName
SetupWindowTitle = Setup - YourApplicationName YourApplicationVersion
This will modify the "title bar" and the "app title" in the tray.
I would suggest not modifying the default configuration in /innosetup/default.isl,
like Sertac Akyuz pointed out. Think of this file as fallback config.
If you don't define a setting, then the setting is taken from default.isl.
Just modify your file; not the default settings!
In the InnoSetup installation folder there's a default.isl file, open that file in a text editor, find the SetupWindowTitle entry and change the right side from Setup - %1 to only %1. Also repeat the process for additional languages you use in the setup, you'll find the matching '.isl' files in the 'Languages' folder.
If you want to change the caption of the main form, try this:
[code]
procedure CurPageChanged(CurPageID: Integer);
begin
if CurPageID = wpWelcome then
WizardForm.Caption := 'Welcome to My Program';
end;
It, unfortunately, will not change the "Setup" caption on the taskbar. Since this is a delphi application, you would need access to the Application global variable to change this effortless, but this object is not exposed to pascal script, and I don't know any way to do it directly. I think you can follow the #satuon advice to change it using windows messages.
A better solution (also if you want to make your iss setup file be correctly compilable on any computer) is to redefine the certain language string in Messages section after the definition of the Languages file.
For example:
[Languages]
Name: de; MessagesFile: compiler:Languages\German.isl
;Name: en; MessagesFile: compiler:Default.isl
[Messages]
WizardReady=I am ready.
Simple no Codes
[Messages]
SetupWindowTitle=Your Programme Name
You should be able to do that using Pascal scripting. Inno Setup allows you to call SendMessage and PostMessage from your Pascal section. Try to use that to send a WM_SETTEXT message to your window.

Resources