that was simple, and it shows what a great scripting engine Inno setup is:
Create a file called prerequisites.iss in the same folder as YourApp.iss, isxdl.iss and isxdl.dll:
<br />
#include "isxdl.iss"<br />
<br />
[CustomMessages]<br />
;configurations<br />
AppName=MyProgram<br />
DependenciesDir=MyProgramDependencies<br />
<br />
MSI20Title=Windows Installer 2.0<br />
MSI31Title=Windows Installer 3.1<br />
IE6Title=Internet Explorer 6<br />
MDACTitle=MDAC 2.8<br />
JETTitle=JET 4<br />
DOTNET20Title=Microsoft .NET Framework 2.0<br />
<br />
;memos<br />
en.DependenciesDownloadTitle=Download Dependencies<br />
de.DependenciesDownloadTitle=Abhängigkeiten herunterladen<br />
<br />
en.DependenciesInstallTitle=Install Dependencies<br />
de.DependenciesInstallTitle=Abhängigkeiten installieren<br />
<br />
;messages<br />
en.Win2000Sp3Msg=Windows 2000 Service Pack 3 must be installed before setup can continue. Please install Windows 2000 Service Pack 3 and run Setup again.<br />
de.Win2000Sp3Msg=Windows 2000 Service Pack 3 muss installiert werden bevor das Setup fortfahren kann. Bitte installieren Sie Windows 2000 Service Pack 3 und starten Sie das Setup erneut.<br />
<br />
en.WinXPSp2Msg=Windows XP Service Pack 2 must be installed before setup can continue. Please install Windows XP Service Pack 2 and run Setup again.<br />
de.WinXPSp2Msg=Windows XP Service Pack 2 muss installiert werden bevor das Setup fortfahren kann. Bitte installieren Sie Windows XP Service Pack 2 und starten Sie das Setup erneut.<br />
<br />
;en.IISMsg=Microsoft IIS must be installed before setup can continue. Please install Microsoft IIS and run Setup again.<br />
;de.IISMsg=Microsoft IIS muss installiert werden bevor das Setup fortfahren kann. Bitte installieren Sie Microsoft ISS und starten Sie das Setup erneut.<br />
<br />
en.DownloadMsg1=The following applications are required before setup can continue:<br />
de.DownloadMsg1=Die folgenden Programme werden benötigt bevor das Setup fortfahren kann:<br />
<br />
en.DownloadMsg2=Download and install now?<br />
de.DownloadMsg2=Jetzt downloaden und installieren?<br />
<br />
;install text<br />
en.MSI20DownloadSize=~1.7 MB<br />
en.MSI31DownloadSize=~2.5 MB<br />
en.IE6DownloadSize=~46 MB<br />
en.MDACDownloadSize=~5.4 MB<br />
en.JETDownloadSize=~3.7 MB<br />
en.DOTNET20DownloadSize=~23 MB<br />
<br />
de.MSI20DownloadSize=~1,7 MB<br />
de.MSI31DownloadSize=~2,5 MB<br />
de.IE6DownloadSize=~46 MB<br />
de.MDACDownloadSize=~5,4 MB<br />
de.JETDownloadSize=~3,7 MB<br />
de.DOTNET20DownloadSize=~23 MB<br />
<br />
<br />
en.MSI20InstallMsg=Installing Windows Installer 2.0... (May take a few minutes)<br />
de.MSI20InstallMsg=Installiere Windows Installer 2.0... (Kann einige Minuten dauern)<br />
<br />
en.MSI31InstallMsg=Installing Windows Installer 3.1... (This may take a few minutes)<br />
de.MSI31InstallMsg=Installiere Windows Installer 3.1... (Kann einige Minuten dauern)<br />
<br />
en.IE6InstallMsg=Installing Internet Explorer 6... (May take a few minutes)<br />
de.IE6InstallMsg=Installiere Internet Explorer 6... (Kann einige Minuten dauern)<br />
<br />
en.MDACInstallMsg=Installing MDAC 2.8... (May take a few minutes)<br />
de.MDACInstallMsg=Installiere MDAC 2.8... (Kann einige Minuten dauern)<br />
<br />
en.JETInstallMsg=Installing JET 4... (May take a few minutes)<br />
de.JETInstallMsg=Installiere JET 4... (Kann einige Minuten dauern)<br />
<br />
en.DOTNET20InstallMsg=Installing Microsoft .NET Framework 2.0... (May take a few minutes)<br />
de.DOTNET20InstallMsg=Installiere Microsoft .NET Framework 2.0... (Kann einige Minuten dauern)<br />
<br />
<br />
[Run]<br />
Filename: {ini:{tmp}\dep.ini,install,msi20}; Description: {cm:MSI20Title}; StatusMsg: {cm:MSI20InstallMsg}; Parameters: "/q"; Flags: skipifdoesntexist<br />
Filename: {ini:{tmp}\dep.ini,install,msi31}; Description: {cm:MSI31Title}; StatusMsg: {cm:MSI31InstallMsg}; Parameters: "/quiet"; Flags: skipifdoesntexist<br />
<br />
Filename: {ini:{tmp}\dep.ini,install,ie}; Description: {cm:IE6Title}; StatusMsg: {cm:IE6InstallMsg}; Parameters: "/Q /C:""ie6wzd /QU /R:N /S:#e"""; Flags: skipifdoesntexist<br />
<br />
Filename: {ini:{tmp}\dep.ini,install,mdac}; Description: {cm:MDACTitle}; StatusMsg: {cm:MDACInstallMsg}; Parameters: "/Q /C:""setup /QNT"""; Flags: skipifdoesntexist<br />
Filename: {ini:{tmp}\dep.ini,install,jet}; Description: {cm:JETTitle}; StatusMsg: {cm:JETInstallMsg}; Parameters: /Q; Flags: skipifdoesntexist<br />
<br />
Filename: {ini:{tmp}\dep.ini,install,dotnet20}; Description: {cm:DOTNET20Title}; StatusMsg: {cm:DOTNET20InstallMsg}; Parameters: "/Q /T:{tmp}\dotnetfx /C:""install /q"""; Flags: skipifdoesntexist<br />
<br />
<br />
[Code]<br />
var<br />
iePath, mdacPath, jetPath, dotnet20Path, msi31Path, msi20Path: string;<br />
downloadNeeded: boolean;<br />
neededDependenciesDownloadMemo: string;<br />
neededDependenciesInstallMemo: string;<br />
neededDependenciesDownloadMsg: string;<br />
<br />
const<br />
msi20URL = 'http://download.microsoft.com/download/WindowsInstaller/Install/2.0/W9XMe/EN-US/InstMsiA.exe';<br />
msi31URL = 'http://download.microsoft.com/download/1/4/7/147ded26-931c-4daf-9095-ec7baf996f46/WindowsInstaller-KB893803-v2-x86.exe';<br />
mdacURL = 'http://download.microsoft.com/download/c/d/f/cdfd58f1-3973-4c51-8851-49ae3777586f/MDAC_TYP.EXE';<br />
jetURL = 'http://download.microsoft.com/download/4/3/9/4393c9ac-e69e-458d-9f6d-2fe191c51469/Jet40SP8_9xNT.exe';<br />
ieURL = 'http://download.microsoft.com/download/ie6sp1/finrel/6_sp1/W98NT42KMeXP/EN-US/ie6setup.exe';<br />
dotnet20URL = 'http://download.microsoft.com/download/5/6/7/567758a3-759e-473e-bf8f-52154438565a/dotnetfx.exe';<br />
<br />
procedure DecodeVersion(const Version: cardinal; var a, b : word);<br />
begin<br />
a := word(Version shr 16);<br />
b := word(Version and not $ffff0000);<br />
end;<br />
<br />
function IsMinMSIAvailable(HV:Integer; NV:Integer ): boolean;<br />
var Version, dummy : cardinal;<br />
MsiHiVer, MsiLoVer : word;<br />
<br />
begin<br />
Result:=(FileExists(ExpandConstant('{sys}\msi.dll'))) and<br />
(GetVersionNumbers(ExpandConstant('{sys}\msi.dll'), Version, dummy));<br />
DecodeVersion(Version, MsiHiVer, MsiLoVer);<br />
Result:= (Result) and (MsiHiVer >= HV) and (MsiLoVer >= NV);<br />
end;<br />
<br />
function InitializeSetup(): Boolean;<br />
var<br />
SoftwareVersion: string;<br />
WindowsVersion: TWindowsVersion;<br />
<br />
begin<br />
GetWindowsVersionEx(WindowsVersion);<br />
Result := true;<br />
<br />
if WindowsVersion.NTPlatform and<br />
(WindowsVersion.Major = 5) and<br />
(WindowsVersion.Minor = 0) and<br />
(WindowsVersion.ServicePackMajor < 3) then<br />
begin<br />
MsgBox(CustomMessage('Win2000Sp3Msg'), mbError, MB_OK);<br />
Result := false;<br />
exit;<br />
end;<br />
<br />
if WindowsVersion.NTPlatform and<br />
(WindowsVersion.Major = 5) and<br />
(WindowsVersion.Minor = 1) and<br />
(WindowsVersion.ServicePackMajor < 2) then<br />
begin<br />
MsgBox(CustomMessage('WinXPSp2Msg'), mbError, MB_OK);<br />
Result := false;<br />
exit;<br />
end;<br />
<br />
<br />
if (not WindowsVersion.NTPlatform) and<br />
(WindowsVersion.Major >= 4) and<br />
(WindowsVersion.Minor >= 1) and<br />
(not IsMinMSIAvailable(2,0)) then<br />
begin<br />
neededDependenciesInstallMemo := neededDependenciesInstallMemo + ' ' + CustomMessage('MSI20Title') + #13;<br />
msi20Path := ExpandConstant('{src}') + '\' + CustomMessage('DependenciesDir') + '\instmsia.exe';<br />
if not FileExists(msi20Path) then begin<br />
msi20Path := ExpandConstant('{tmp}\msi20.exe');<br />
if not FileExists(msi20Path) then begin<br />
neededDependenciesDownloadMemo := neededDependenciesDownloadMemo + ' ' + CustomMessage('MSI20Title') + #13;<br />
neededDependenciesDownloadMsg := neededDependenciesDownloadMsg + CustomMessage('MSI20Title') + ' (' + CustomMessage('MSI20DownloadSize') + ')' + #13;<br />
isxdl_AddFile(msi20URL, msi20Path);<br />
downloadNeeded := true;<br />
end;<br />
end;<br />
SetIniString('install', 'msi20', msi20Path, ExpandConstant('{tmp}\dep.ini'));<br />
end;<br />
<br />
// Check for required Windows Installer 3.0 on Windows 2000, XP, Server 2003, Vista or higher<br />
if WindowsVersion.NTPlatform and<br />
(WindowsVersion.Major >= 5) and<br />
(not IsMinMSIAvailable(3,0)) then<br />
begin<br />
neededDependenciesInstallMemo := neededDependenciesInstallMemo + ' ' + CustomMessage('MSI31Title') + #13;<br />
msi31Path := ExpandConstant('{src}') + '\' + CustomMessage('DependenciesDir') + '\WindowsInstaller-KB893803-v2-x86.exe';<br />
if not FileExists(msi31Path) then begin<br />
msi31Path := ExpandConstant('{tmp}\msi31.exe');<br />
if not FileExists(msi31Path) then begin<br />
neededDependenciesDownloadMemo := neededDependenciesDownloadMemo + ' ' + CustomMessage('MSI31Title') + #13;<br />
neededDependenciesDownloadMsg := neededDependenciesDownloadMsg + CustomMessage('MSI31Title') + ' (' + CustomMessage('MSI31DownloadSize') + ')' + #13;<br />
isxdl_AddFile(msi31URL, msi31Path);<br />
downloadNeeded := true;<br />
end;<br />
end;<br />
SetIniString('install', 'msi31', msi31Path, ExpandConstant('{tmp}\dep.ini'));<br />
end;<br />
<br />
// Check for required Internet Explorer installation<br />
// Note that if Internet Explorer 6 is downloaded, the express setup will be downloaded, however it is the same<br />
// ie6setup.exe that would be available in the ie6 folder. The only difference is that the<br />
// user will be presented with an option as to where to download Internet Explorer 6 and a progress dialog.<br />
// Most common components will still be installed automatically.<br />
SoftwareVersion := '';<br />
RegQueryStringValue(HKLM, 'Software\Microsoft\Internet Explorer', 'Version', SoftwareVersion);<br />
if (SoftwareVersion < '5') then begin<br />
neededDependenciesInstallMemo := neededDependenciesInstallMemo + ' ' + CustomMessage('IE6Title') + #13;<br />
iePath := ExpandConstant('{src}') + '\' + CustomMessage('DependenciesDir') + '\ie6\ie6setup.exe';<br />
if not FileExists(iePath) then begin<br />
iePath := ExpandConstant('{tmp}\ie6setup.exe');<br />
if not FileExists(iePath) then begin<br />
neededDependenciesDownloadMemo := neededDependenciesDownloadMemo + ' ' + CustomMessage('IE6Title') + #13;<br />
neededDependenciesDownloadMsg := neededDependenciesDownloadMsg + CustomMessage('IE6Title') + ' (' + CustomMessage('IE6DownloadSize') + ')' + #13;<br />
isxdl_AddFile(ieURL, iePath);<br />
downloadNeeded := true;<br />
end;<br />
end;<br />
SetIniString('install', 'ie', iePath, ExpandConstant('{tmp}\dep.ini'));<br />
end;<br />
<br />
// Check for required MDAC installation<br />
SoftwareVersion := '';<br />
RegQueryStringValue(HKLM, 'Software\Microsoft\DataAccess', 'FullInstallVer', SoftwareVersion);<br />
if (SoftwareVersion < '2.7') then begin<br />
neededDependenciesInstallMemo := neededDependenciesInstallMemo + ' ' + CustomMessage('MDACTitle') + #13;<br />
mdacPath := ExpandConstant('{src}') + '\' + CustomMessage('DependenciesDir') + '\MDAC_TYP.EXE';<br />
if not FileExists(mdacPath) then begin<br />
mdacPath := ExpandConstant('{tmp}\MDAC_TYP.EXE');<br />
if not FileExists(mdacPath) then begin<br />
neededDependenciesDownloadMemo := neededDependenciesDownloadMemo + ' ' + CustomMessage('MDACTitle') + #13;<br />
neededDependenciesDownloadMsg := neededDependenciesDownloadMsg + CustomMessage('MDACTitle') + ' (' + CustomMessage('MDACDownloadSize') + ')' + #13;<br />
isxdl_AddFile(mdacURL, mdacPath);<br />
downloadNeeded := true;<br />
end;<br />
end;<br />
SetIniString('install', 'mdac', mdacPath, ExpandConstant('{tmp}\dep.ini'));<br />
end;<br />
<br />
// Check for required Jet installation<br />
if (not RegKeyExists(HKLM, 'Software\Microsoft\Jet\4.0')) then begin<br />
neededDependenciesInstallMemo := neededDependenciesInstallMemo + ' ' + CustomMessage('JETTitle') + #13;<br />
jetPath := ExpandConstant('{src}') + '\' + CustomMessage('DependenciesDir') + '\Jet40SP8_9xNT.exe';<br />
if not FileExists(jetPath) then begin<br />
jetPath := ExpandConstant('{tmp}\Jet40SP8_9xNT.exe');<br />
if not FileExists(jetPath) then begin<br />
neededDependenciesDownloadMemo := neededDependenciesDownloadMemo + ' ' + CustomMessage('JETTitle') + #13;<br />
neededDependenciesDownloadMsg := neededDependenciesDownloadMsg + CustomMessage('JETTitle') + ' (' + CustomMessage('JETDownloadSize') + ')' + #13;<br />
isxdl_AddFile(jetURL, jetPath);<br />
downloadNeeded := true;<br />
end;<br />
end;<br />
SetIniString('install', 'jet', jetPath, ExpandConstant('{tmp}\dep.ini'));<br />
end;<br />
<br />
// Check for required dotnetfx 2.0 installation<br />
if (not RegKeyExists(HKLM, 'SOFTWARE\Microsoft\NET Framework Setup\NDP\v2.0.50727')) then begin<br />
neededDependenciesInstallMemo := neededDependenciesInstallMemo + ' ' + CustomMessage('DOTNET20Title') + #13;<br />
dotnet20Path := ExpandConstant('{src}') + '\' + CustomMessage('DependenciesDir') + '\dotnetfx.exe';<br />
if not FileExists(dotnet20Path) then begin<br />
dotnet20Path := ExpandConstant('{tmp}\dotnetfx.exe');<br />
if not FileExists(dotnet20Path) then begin<br />
neededDependenciesDownloadMemo := neededDependenciesDownloadMemo + ' ' + CustomMessage('DOTNET20Title') + #13;<br />
neededDependenciesDownloadMsg := neededDependenciesDownloadMsg + CustomMessage('DOTNET20Title') + ' (' + CustomMessage('DOTNET20DownloadSize') + ')' + #13;<br />
isxdl_AddFile(dotnet20URL, dotnet20Path);<br />
downloadNeeded := true;<br />
end;<br />
end;<br />
SetIniString('install', 'dotnet20', dotnet20Path, ExpandConstant('{tmp}\dep.ini'));<br />
end;<br />
end;<br />
<br />
<br />
function NextButtonClick(CurPage: Integer): Boolean;<br />
var<br />
hWnd: Integer;<br />
<br />
begin<br />
Result := true;<br />
<br />
if CurPage = wpReady then begin<br />
<br />
hWnd := StrToInt(ExpandConstant('{wizardhwnd}'));<br />
<br />
if downloadNeeded then<br />
if MsgBox(CustomMessage('DownloadMsg1') + #13 + neededDependenciesDownloadMsg + #13 + CustomMessage('DownloadMsg2'), mbConfirmation, MB_YESNO) = IDNO then Result := false<br />
else if isxdl_DownloadFiles(hWnd) = 0 then Result := false;<br />
end;<br />
end;<br />
<br />
function UpdateReadyMemo(Space, NewLine, MemoUserInfoInfo, MemoDirInfo, MemoTypeInfo, MemoComponentsInfo, MemoGroupInfo, MemoTasksInfo: String): String;<br />
var<br />
s: string;<br />
<br />
begin<br />
if neededDependenciesDownloadMemo <> '' then s := s + CustomMessage('DependenciesDownloadTitle') + ':' + NewLine + neededDependenciesDownloadMemo + NewLine;<br />
if neededDependenciesInstallMemo <> '' then s := s + CustomMessage('DependenciesInstallTitle') + ':' + NewLine + neededDependenciesInstallMemo + NewLine;<br />
<br />
s := s + MemoDirInfo + NewLine + NewLine + MemoGroupInfo<br />
if MemoTasksInfo <> '' then s := s + NewLine + NewLine + MemoTasksInfo;<br />
<br />
Result := s<br />
end;<br />
in YourApp.iss, add the following after your #define statements:
<br />
#define MyAppName "YourApp"<br />
...<br />
#include "prerequisites.iss"<br />
<br />
[Setup]<br />
...<br />
Finally, make sure your variable names are in sync. For instance, if your use
[Languages]<br />
Name: english; MessagesFile: compiler:Default.isl
in YourApp.iss, you need to change
en.DependenciesDownloadTitle=Download Dependencies
to
english.DependenciesDownloadTitle=Download Dependencies
in prerequisites.iss
Lemme know if you find any bugs
Thanks
Pierre
|