Script for copying Files at the end of install : Inno Setup - inno-setup

I explain my project : my setup will be delivered with 2 licence files beside him who they must not be include inside the concerned setup. Like this :
Folder/
----Setup.exe
----CanBTL.dat
----CanBTP.dat
And i want, if that's sure they are here, to copy this files in a folder who will be build with Setup.exe. So i'm trying to make this code :
I edit my script :
EDIT :
[Code]
function CheckForFile(CurPageID: Integer): Boolean;
begin
if (CurPageID = wpFinished) and (FileExists('CanBTL.dat' + 'CanBTP.dat')) then
begin
FileCopy(ExpandConstant('CanBTL.dat' + 'CanBTP.dat'), ExpandConstant('{cf}\Folder\'), false);
end;
end;
The goal is to copy the two .dat file next to the setup in a folder created by the setup.exe
It compile, but seems to make nothing. My files are not copied.
I'm still a beginner to the section code in Inno Setup so if anyone can help me?
Thanks

Ok. No need of code section, that's working fine using external flags and the
{src} constant to say current directory :
Source: "{src}\CanBTL.dat"; DestDir: "{cf}\Folder"; Flags: external;
Source: "{src}\CanBTP.dat"; DestDir: "{cf}\Folder"; Flags: external;
Thanks TLama

Related

Setup is "unresponsive" at startup if I compile it with compression [duplicate]

My Installer created with Inno Setup is about 850 MB in size containing about 7000 files and 890 Folders to an uncompressed size of 1.98 GB.
When starting the install process, after the Windows UAC Dialog shows up, the Installer is sitting with an empty icon in the Taskbar for approx. 45 seconds before the Welcome Dialog is being shown.
I'm assuming that this is happening during the process of unpacking the installer? Running the installer with just a dummy file entry has the Welcome Dialog show up immediately.
In the [Files] section, I only specify a single relative folder:
Source: "{#Source}\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs
Compression in the [Setup] section is set to:
Compression=lzma
SolidCompression=yes
Is there a dialog I can show during that time that gives the user visual feedback that something is being prepared?
To append to this question:
The last entry in the Log file before the 45 second hang is:
Extracting temporary file: C:\Users\Markus\AppData\Local\Temp\is-CBETM.tmp\license.rtf
I'm using a custom License Page on which I extract the file and load it as RTFText:
procedure LicensePage_Create;
var
LicenseFileName: string;
LicenseFilePath: string;
LicenseText: AnsiString;
begin
LicensePage := CreateOutputMsgMemoPage(wpSelectDir, SetupMessage(msgWizardLicense), SetupMessage(msgLicenseLabel), SetupMessage(msgLicenseLabel3), '');
LicensePage.RichEditViewer.Height := WizardForm.LicenseMemo.Height;
LicenseFileName := 'license.rtf';
ExtractTemporaryFile(LicenseFileName);
LicenseFilePath := ExpandConstant('{tmp}\license.rtf');
LoadStringFromFile(LicenseFilePath, LicenseText);
LicensePage.RichEditViewer.RTFText := LicenseText;
DeleteFile(LicenseFilePath);
LicensePage.OnActivate := #LicensePageActivate;
LicenseAcceptedRadio := CloneLicenseRadioButton(WizardForm.LicenseAcceptedRadio);
LicenseNotAcceptedRadio := CloneLicenseRadioButton(WizardForm.LicenseNotAcceptedRadio);
LicenseNotAcceptedRadio.Checked := True;
LicensePageID := LicensePage.ID;
end;
When you want to use SolidCompression (is it really worth it?), you have to put all files that are needed for the installer to start (like "license" file) before the big files.
Otherwise the installer has to decompress all the big files while starting.

inno setup to browse and extract zip file at sepcific location

I want to enable users to browse and extract zip files at a specific location.
Requirements/steps:
Display welcome page
Next display browse button to select installation directory(DisableDirPage=no)
Next display browse button to select zip file(JDK)
Extract JDK zip file selected in step 3 at location selected in step 2, that means JDK should be extracted in installation directory that user selects in step 2
Problems with my code:
After the first step my code directly jump into 3rd step and then it goes to 2nd.
The code to extract zip is not working if I pass method name as the parameter. If I pass the hardcoded value of the location it works. I don't know pascal and it basically seems to be a syntax related issue.
[SETUP]
AppName=My Program
AppVersion=1.5
DefaultDirName={pf}\My Program
DefaultGroupName=My Program
UninstallDisplayIcon={app}\MyProg.exe
DisableProgramGroupPage=no
DisableWelcomePage=no
DisableDirPage=no
Compression=lzma2
SolidCompression=yes
OutputDir=userdocs:Inno Setup Examples Output
[Files]
Source: "{code:GetLicensePath}"; DestDir: "{app}"; Flags: external
Source: "7za.exe"; DestDir: "D:\authorized\Builds\Solo\"; Flags: deleteafterinstall;
[Icons]
Name: "{group}\My Program"; Filename: "{app}\MyProg.exe"
[Run]
Filename: D:\authorized\Builds\Solo\7za.exe; Parameters: "x ""{{Code:GetZipPath}}"" -o""{app}\"" * -r -aoa"; Flags: runhidden runascurrentuser;
[Code]
var
Page: TInputFileWizardPage;
DataDir:String;
procedure InitializeWizard();
begin
Page :=
CreateInputFilePage(
wpWelcome,
'Select Zip File Location',
'Where is your Zip file located?',
'Select where Zip file is located, then click Next.');
Page.Add(
'Location of Zip file:',
'*.7z|*.rar|All files|*.*',
'.zip');
// Set initial value (optional)
Page.Values[0] := ExpandConstant('{%USERPROFILE}\Downloads\setup.7z');
;
end;
function GetZipPath(Param: string): string;
begin
DataDir := Page.Values[0];
end;
Could you help me, please?
The order of your custom page is determined by the first argument of the Create* function. So change wpWelcome to wpSelectDir.
Why double {{...}} - That’s likely the problem. Also code: should be lowercase.
Your scripted constant function does not really return anything. It should be:
Result := Page.Values[0];

How to reference the files in the Files section from Code/Pascal section?

In my code section I need to modify an existing configuration file (Apache httpd.conf) to include one of the files I'm installing in the Files section.
How can I reference my .conf file, so I can insert into the httpd.conf something like this:
Include "C:/Program Files (x86)/Apache Software Foundation/Apache2.4/conf/myinclude.conf"
I think I can do something like:
ExtractFilePath( {app} ) + '\conf\myinclude.conf'
to get the full path of the file.
However that means I have to hard code the partial path in my script code. If we later change the path then I have to change it in the files section and remember to change it in the script code too.
Is there a way to reference the file just by name and get the full installed path?
Secondary question:
What's the best place to do this kind of thing (modifying a file)?
In the AfterInstall of the file I'm going to modify it for?
In NextButtonClick on wpFinished?
Other?
Use a preprocessor constant/variable.
The best place to update the httpd.conf is CurStepChanged(ssPostInstall). The AfterInstall will do too.
#define MyIncludeName "myinclude.conf"
#define MyIncludeRelPath "conf\" + MyIncludeName
[Files]
Source: "{#MyIncludeName}"; DestDir: "{app}\..\{#MyIncludeRelPath}"
[Code]
procedure CurStepChanged(CurStep: TSetupStep);
var
Path: string;
begin
if CurStep = ssPostInstall then
begin
Path := ExtractFilePath(ExpandConstant('{app}')) + '{#MyIncludeRelPath}';
...
end;
end;

Inno Setup Runtime error while accessing CurrentFileName when installing an empty folder

I tried to access all files inside a folder through Pascal code. When I iterate through an empty folder I am getting the following error:
Exception: Internal error; An attempt was made to call the "CurrentFileName" function from outside a "Check", "BeforeInstall" or "AfterInstall" event function belonging to a "[Files]" entry
The code I used:
[Files]
Source: ".\3D_Dlls\*"; DestDir: {app}\3D_Dlls; \
Flags: ignoreversion recursesubdirs createallsubdirs skipifsourcedoesntexist; \
Check: FileBackup
[Code]
function FileBackup(): Boolean;
var FileName,Source,Target,TargetDir: String;
begin
Result := True;
Source := ExpandConstant(CurrentFileName);
end
Say for example my folder structure is like that:
3D_Dlls
- Folder 1
- Folder 2 // Empty folder and it invokes the problem
- Folder 3
I believe this is a bug in Inno Setup triggered by the createallsubdirs flag.
When the flag is specified, Inno Setup collects a separate list of empty directories that need to be explicitly created during an installation. When "installing" the empty folder, the call to the CurrentFileName simply fails.
Workarounds:
Remove the createallsubdirs flag, if possible.
Instead, you can explicitly create empty directories using the [Dirs] section.
Catch the exception:
function FileBackup: Boolean;
begin
Result := True;
try
Source := ExpandConstant(CurrentFileName);
except
Log(GetExceptionMessage);
end;
end;
I have reported this on Inno Setup newsgroup, but the newsgroup was reset since.

How to get Inno Setup to unzip a file it installed (all as part of the one installation process)

To save bandwidth/space as well as prevent accidental meddling, the installation files for a database product (call it Ajax), have been zipped up (call that file "AJAX_Install_Files.ZIP). I would like to have Inno-Setup "install" (i.e., copy) the AJAX_Install_Files.ZIP file to the destination, and then Unzip the files into the same folder where the .ZIP file is located. A subsequent program would be fired off by Inno Setup to actually run the install of product "Ajax".
I've looked through the documentation, FAQ, and KB at the Inno Setup website, and this does not seem possible other than writing a Pascal script (code) - would that be correct, or are there are any alternative solutions?
You can use an external command line tool for unzipping your archive, see here for example. Put it in your [Files] section:
[Files]
Source: "UNZIP.EXE"; DestDir: "{tmp}"; Flags: deleteafterinstall
Then call it in your [Run] section, like this:
[Run]
Filename: "{tmp}\UNZIP.EXE"; Parameters: "{tmp}\ZipFile.ZIP -d C:\TargetDir"
(You'll probably want to take your target directory from a script variable, so there is some more work that needs to be done)
You can use the shell Folder.CopyHere method to extract a ZIP.
const
SHCONTCH_NOPROGRESSBOX = 4;
SHCONTCH_RESPONDYESTOALL = 16;
procedure UnZip(ZipPath, TargetPath: string);
var
Shell: Variant;
ZipFile: Variant;
TargetFolder: Variant;
begin
Shell := CreateOleObject('Shell.Application');
ZipFile := Shell.NameSpace(ZipPath);
if VarIsClear(ZipFile) then
RaiseException(
Format('ZIP file "%s" does not exist or cannot be opened', [ZipPath]));
TargetFolder := Shell.NameSpace(TargetPath);
if VarIsClear(TargetFolder) then
RaiseException(Format('Target path "%s" does not exist', [TargetPath]));
TargetFolder.CopyHere(
ZipFile.Items, SHCONTCH_NOPROGRESSBOX or SHCONTCH_RESPONDYESTOALL);
end;
Note that the flags SHCONTCH_NOPROGRESSBOX and SHCONTCH_RESPONDYESTOALL work on Windows Vista and newer.
For an example of extracting some files only, see:
How to get Inno Setup to unzip a single file?
I answered a very similar question and some of the details apply.
I would question why you need a ZIP file of the contents? I personally would place the uncompressed files into the setup. I would then have two [category] entries one for the application and one for the data. Default both the be checked.
This would allow the users to install a fresh set of the data if needed at a later date.
If you really want a ZIP file and want to keep it easy you could, ship both the zip files and the uncompressed files in the same setup.
Update:
By default files that get placed in your setup.exe are compressed.
You can also have the files extracted to a temporary location so you can run your
installation application, then have them deleted.
[Files]
Source: "Install1.SQL"; DestDir: "{tmp}"; Flags:deleteafterinstall;
Source: "Install2.SQL"; DestDir: "{tmp}"; Flags:deleteafterinstall;
You can just create silent self-extracting archive (SFX) archive, example described here how to create SFX archive for stuff you need, and write Pascal code to just run it like this (script for Inno Setup 6.0.2):
[Tasks]
Name: "intallSenselockDriver"; Description: "Install Senselock driver."; GroupDescription: "Install the necessary software:";
[Code]
function ExecTmpFile(FileName: String): Boolean;
var
ResultCode: Integer;
begin
if not Exec(ExpandConstant('{tmp}\' + FileName), '', '', SW_SHOWNORMAL, ewWaitUntilTerminated, ResultCode)
then
begin
MsgBox('Other installer failed to run!' + #13#10 + SysErrorMessage(ResultCode), mbError, MB_OK);
Result := False;
end
else
Result := True;
end;
procedure RunOtherInstallerSFX(ArchiveName: String; ExePath: String);
begin
ExtractTemporaryFile(ArchiveName);
ExecTmpFile(ArchiveName);
ExecTmpFile(ExePath);
end;
function PrepareToInstall(var NeedsRestart: Boolean): String;
begin
if WizardIsTaskSelected('intallSenselockDriver') then
RunOtherInstallerSFX('1_senselock_windows_3.1.0.0.exe', '1_senselock_windows_3.1.0.0\InstWiz3.exe');
Result := '';
end;
It worked perfectly for me.
Using Double quotes worked for me.
Single quotes were not working.
[Files]
Source: "unzip.exe"; DestDir: "{userappdata}\{#MyAppName}\{#InputFolderName}"; Flags: ignoreversion
[Run]
Filename: "{userappdata}\{#MyAppName}\{#InputFolderName}\unzip.exe"; Parameters: " ""{userappdata}\{#MyAppName}\{#InputFolderName}\ZIPFILENAME.zip"" -d ""{userappdata}\{#MyAppName}\{#InputFolderName}"" "; Flags: runascurrentuser

Resources