Inno Setup - Do not install DirectX when already installed - inno-setup

I'm using this code in [Run] section:
Filename: "{src}\DirectX\DXSETUP.exe"; StatusMsg: "Wait for install DirectX package..."; \
Flags: waituntilterminated skipifsilent skipifdoesntexist
And when I try to reinstall program, every time I get pop-up with DirectX installation. How to prevent reinstalling DirectX, when it's installed already?

See ISXKB for DirectX - How to detect DirectX version article.
It has useful functions, which you can use to detect, if required version of DirectX is already installed on the machine.
Using these functions, you can easily implement a check function:
[Run]
Filename: "{src}\DirectX\DXSETUP.exe";
StatusMsg: "Wait for install DirectX package..."; \
Flags: waituntilterminated skipifsilent skipifdoesntexist; Check: InstallDirectX
[Code]
function InstallDirectX: Boolean;
begin
Result := (CompareVersion(GetDirectXVersion(), '4.8.0') < 0);
end;

Related

Inno Setup - Run programs after ssPostInstall code that processes installed files

I am installing DirectX and vc_2013_x64 from components section (and from Run section) and I am using this code too: How to add .arc decompression to Inno Setup? (answer of Martin Prikryl). How to move the installation of DirectX and vc_2013_x64 (if it is possible) to after the decompressing page (and before the finish page)? (Because with this code the installation is in the middle between installing page and decompressing page).
I am using this script to execute the sub-installers:
[Run]
Filename: {src}\_Redist\dxwebsetup.exe; StatusMsg: Installing DirectX...
Filename: {src}\_Redist\vcredist_x64.exe; StatusMsg: Installing vcredist_x64...
There are many ways, e.g.:
Run the ExtractArc from the AfterInstall parameter of the archive Run entry, instead of the CurStepChanged event function:
Source: {#ArcArchive}; DestDir: "{tmp}"; Flags: nocompression deleteafterinstall; \
AfterInstall: ExtractArc
Or execute the dxwebsetup.exe and vcredist_x64.exe from the CurStepChanged before the ExtractArc, using the Exec function.

Kill process before (re)install using "taskkill /f /im" in Inno Setup

I install a service/daemon, which needs to be killed before uninstall and reinstall.
I already found out how to do it for uninstall:
[UninstallRun]
Filename: "taskkill"; Parameters: "/im ""My Service.exe"" /f"; Flags: runhidden
The [Run] section, however, runs after install, so I can't use it for that. What is the best way to kill the process using taskkill before install?
Please note that I specifically want to kill the process. A more complex solution using IPC offers no benefits in my case, I just want to execute taskkill before installing a particular file.
I found a way using the BeforeInstall parameter and a simple Pascal Script function in the code section. I added a string parameter so it can be reused for multiple processes.
[Files]
Source: "My Service 1.exe"; DestDir: "{app}"; Flags: ignoreversion; \
BeforeInstall: TaskKill('My Service 1.exe')
Source: "My Service 2.exe"; DestDir: "{app}"; Flags: ignoreversion; \
BeforeInstall: TaskKill('My Service 2.exe')
[Code]
procedure TaskKill(FileName: String);
var
ResultCode: Integer;
begin
Exec('taskkill.exe', '/f /im ' + '"' + FileName + '"', '', SW_HIDE,
ewWaitUntilTerminated, ResultCode);
end;
Unless the installer needs to run on a Windows XP machine, or you have set CloseApplications directive to no (the default is yes), the installer should close the application automatically:
The functionality is available since Inno Setup 5.5 on Windows Vista and newer.
Though sometimes yes is not enough, you need to use force:
Installer created via Inno Setup, can't close applications during installation on Windows 10

Execute script once before installing a directory tree

I am trying to write an Inno Setup installer to install and then run other installers. The problem I have is when trying to install Cygwin. I have downloaded Cygwin and all packages I need so I can perform a local install. Then I want to add extra files and directories to the Cygwin installation.
My first attempt was like this:
[Files]
Source: "{#Cygwin}\Cygwin\*"; DestDir: {tmp}\cygwin; Flags: recursesubdirs;
Source: "{#Cygwin}\additional\*"; DestDir: {tmp}\cygwin\additional; Flags: recursesubdirs
[Run]
Filename: "{tmp}\cygwin\setup-x86_64.exe"; Parameters: "-q -L"; WorkingDir: "{tmp}";
But this means that I must have a script to add the additional files because there is nowhere to put them until Cygwin is actually installed by the command in the [Run] section.
I have tried using a BeforeInstall script in the [Files] section to run the Cygwin installer before adding the additional files, but because I have to use a wildcard with Source: "{#Cygwin}\additional\*"; the script is called once for every file in the directory tree.
The [Files] section of Inno Setup seems to only accept source files, and not a source directory, unless the directory has a wildcard.
Is there a way I can make it install everything from a directory tree without using a wildcard, or is there a way I can make the BeforeInstall script run just once, regardless of how many files are copied?
Install the Cygwin on the first call to BeforeInstall function only.
var
CygwinInstalled: Boolean;
procedure MyBeforeInstall;
begin
if CygwinInstalled then
begin
Log('Cygwin installed already');
end
else
begin
Log('Installing Cygwin');
{ install Cygwin here }
CygwinInstalled := true;
end;
end;

Custom setup on operating system and architecture

I have been asked to have a setup procedure running in the following operating systems:
Windows Vista (only x86) and higher (both x86 and x64)
In order to restrict whole setup from running in older operating systems I added into [Setup] section the Minversion=0,6.0.6000 that corresponds to Windows Vista.
I wonder if in Pascal scripting it is possible to apply a conditional installation like the following:
[Run]
Filename: "{tmp}\mysetup.exe"; Components: Install; MinVersion: 0,6.0.6000; Check: not Iswin64;
Filename: "{tmp}\mysetup.exe"; Components: Install; MinVersion: 0,6.1.7600;
This way mysetup.exe should run only on Vista x86 and on all higher operating systems.
Use GetWindowsVersion and IsWin64 support functions:
if ((GetWindowsVersion >= $06000000) {Vista} and (not IsWin64)) or
(GetWindowsVersion >= $06010000) {7} then
begin
// Install
end;
I believe what you are looking for is MinVersion
It's one of the optional parameters that are supported on all sections that support parameters.
Documentation can be found here: http://www.jrsoftware.org/ishelp/index.php?topic=commonparams&anchor=MinVersion

Inno Setup - How to execute MSI between 32 and 64 architectures

im trying to run 2 msi files for 32 and 64 bits from a third party and i am having a little trouble with the msi for 32bits windows architectures.
It seems the program extracts quite well the file but it doesn´t execute the installer. In the other hand for 64bits windows architectures the installer works. I don´t know where is the problem. Is there anything wrong with my code that im not seeing?Thank you!
[Setup]
...
ArchitecturesInstallIn64BitMode=x64
[Files]
; NOTE: Don't use "Flags: ignoreversion" on any shared system files
Source: "filex64.msi"; DestName: "file.msi"; DestDir: "{app}"; Flags: deleteafterinstall; Check: Is64BitInstallMode
Source: "filex32.msi"; DestName: "file.msi"; DestDir: "{app}"; Flags: deleteafterinstall; Check: not Is64BitInstallMode;
Source: "manual.pdf"; DestDir: "{userdesktop}"; DestName: "Manual.pdf"
[Run]
Filename: "{sys}\msiexec.exe"; Parameters: "/package ""{app}\file.msi"" /qn /norestart /passive"; Flags: shellexec waituntilterminated; StatusMsg: "A instalar software {#MyAppVersion}";
Filename: "{userdesktop}\Manual.pdf"; Flags: postinstall;
I figure it out.
Flags
32bit
Causes the {sys} constant to map to the 32-bit System directory when used in the Filename and WorkingDir parameters. This is the default behavior in a 32-bit mode install.
This flag cannot be combined with the shellexec flag.
64bit
Causes the {sys} constant to map to the 64-bit System directory when used in the Filename and WorkingDir parameters. This is the default behavior in a 64-bit mode install.
This flag can only be used when Setup is running on 64-bit Windows, otherwise an error will occur. On an installation supporting both 32- and 64-bit architectures, it is possible to avoid the error by adding a Check: IsWin64 parameter, which will cause the entry to be silently skipped when running on 32-bit Windows.
This flag cannot be combined with the shellexec flag.
Source:
http://www.jrsoftware.org/ishelp/index.php?topic=isxfunc_iswin64
Based on this, i changed my script ir order to pinpoint correctly the "msiexec.exe" file for both architectures. Thank you guys!
[Run]
Filename: "{sys}\msiexec.exe"; Parameters: "/package ""{userdesktop}\Classic_Client_{#MyAppVersion}_64.msi"" /qn /norestart /passive"; Flags: 64bit skipifdoesntexist waituntilterminated; Check:IsWin64; StatusMsg: "A instalar Classic Client {#MyAppVersion} - 64bit";
Filename: "{sys}\msiexec.exe"; Parameters: "/package ""{userdesktop}\Classic_Client_{#MyAppVersion}_32.msi"" /qn /norestart /passive"; Flags: 32bit skipifdoesntexist waituntilterminated; StatusMsg: "A instalar Classic Client {#MyAppVersion} - 32bit";
the {sys} constant is the issue.
{sys} The system's System32 directory. For example: If you used
{sys}\CTL3D32.DLL on an entry and the system's Windows System
directory is "C:\WINDOWS\SYSTEM", Setup or Uninstall will translate it
to "C:\WINDOWS\SYSTEM\CTL3D32.DLL".
On 64-bit Windows, by default, the System32 path returned by this
constant maps to the directory containing 32-bit system files, just
like on 32-bit Windows. (This can be overridden by enabling 64-bit
mode.)

Resources