Project Description


What is inno setup?

Inno setup is a free installer. You can review about inno setup here.

In this article, i'll share how to:

  • Detect and install .NET 3.5
  • Detect and install SQL Server 2008 Express R2 both in x86 and x64
  • Detect and Installing Windows Installer 4.5
  • Detect and installing Crystal Report 2008 Redist x86 and x64


Here is my code.

Files
Source: "E:\Inno Setup\Prerequisites\WindowsInstaller4_5\WindowsXP-KB942288-v3-x86.exe"; DestDir: "{app}"; DestName:"wi.exe"; Flags: ignoreversion deleteafterinstall;Check: checkwixp86; AfterInstall: InstallWindowsInstaller
Source: "E:\Inno Setup\Prerequisites\WindowsInstaller4_5\WindowsXP-KB942288-v3-x86.exe"; DestDir: "{app}"; DestName:"wi.exe"; Flags: ignoreversion deleteafterinstall;Check: checkwi86; AfterInstall: InstallWindowsInstaller
Source: "E:\Inno Setup\Prerequisites\WindowsInstaller4_5\WindowsXP-KB942288-v3-x86.exe"; DestDir: "{app}"; DestName:"wi.exe"; Flags: ignoreversion deleteafterinstall;Check: checkwi64; AfterInstall: InstallWindowsInstaller

Source: "E:\Inno Setup\Prerequisites\dotnetfx35\dotnetfx35.exe"; DestDir: "{app}"; DestName:"dotnetfx35.exe"; Flags: ignoreversion deleteafterinstall;Check: Checkdotnet; AfterInstall: InstallDotNet;

Source: "E:\Inno Setup\Prerequisites\CrystalReports105\CRRedist2008x86.msi"; DestDir: "{app}"; DestName:"cr.exe"; Check: ShouldInstallCR86; Flags: ignoreversion deleteafterinstall; AfterInstall: InstallCrystalReports
Source: "E:\Inno Setup\Prerequisites\CrystalReports105\CRRedist2008x64.msi"; DestDir: "{app}"; DestName:"cr.exe"; Check: ShouldInstallCR64; Flags: ignoreversion deleteafterinstall; AfterInstall: InstallCrystalReports

Source: "E:\Inno Setup\Prerequisites\SQLServer2008R2SP2\SQLEXPRx86ENU.exe"; Components:sqlserver; DestDir: "{app}"; DestName:"sql.exe"; Flags: ignoreversion; Check: CheckSQLServer86; AfterInstall: InstallSQLServer
Source: "E:\Inno Setup\Prerequisites\SQLServer2008R2SP2\SQLEXPRx64ENU.exe"; Components:sqlserver; DestDir: "{app}"; DestName:"sql.exe"; Flags: ignoreversion; Check: CheckSQLServer64; AfterInstall: InstallSQLServer

Source: "E:\Project\Inno Setup\Project\BIS\Files\BIS.exe"; Check: InstallThisFile; DestDir: "{app}"; Flags: ignoreversion

Icons
Name: "{group}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"
Name: "{group}\{cm:ProgramOnTheWeb,{#MyAppName}}"; Filename: "{#MyAppURL}"
Name: "{group}\{cm:UninstallProgram,{#MyAppName}}"; Filename: "{uninstallexe}"
Name: "{commondesktop}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; Tasks: desktopicon
Name: "{userappdata}\Microsoft\Internet Explorer\Quick Launch\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; Tasks: quicklaunchicon

Run
Filename: "{app}\{#MyAppExeName}"; Description: "{cm:LaunchProgram,{#StringChange(MyAppName, '&', '&&')}}"; Flags: nowait postinstall skipifsilent

Registry
Root: HKLM; Subkey: "Software\MyApp"; Flags: uninsdeletekey
Root: HKLM; Subkey: "Software\MyApp"; ValueType: string; ValueName: "Path"; ValueData: "{app}"

UninstallDelete
Type: files; Name: "{app}\sql.exe"; AfterInstall: RemoveSQLServer



Code
const
RunOnceName = 'setup Restart';
var
//dotnetRedistPath: string;
//downloadNeeded: boolean;
//ProcessorArchitecture = paIA64
//paX64
lastcaption: string;
dotNetNeeded: boolean;
wineeded: boolean;
sqlserverneeded: boolean;
memoDependenciesNeeded: string;
Version: TWindowsVersion;
msipath: string;
versionMS, versionLS: cardinal;
HasRestarted: boolean;
IsRestartNeeded: boolean;
SkipOtherPage: boolean;
SQLDependency: string;
filename: string;

Function WindowsInstallerVersionBelow31(): Boolean;
begin
//intToStr(word(VersionMS shr 16))
Result:=false;
if ((VersionMS shr 16) < 3) then
result:=true;

if ((((VersionMS shr 16)) = 3) and (((VersionLS shr 16)) < 1)) then
result:=true;

end;

Function WindowsInstallerVersionBelow45(): Boolean;
begin
//intToStr(word(VersionMS shr 16))
Result:=false;
if ((VersionMS shr 16) < 4) then
result:=true;

if ((((VersionMS shr 16)) = 4) and (((VersionLS shr 16)) < 5)) then
result:=true;

end;

Function WindowsInstallerVersionBelow50(): Boolean;
begin
//intToStr(word(VersionMS shr 16))
Result:=false;
if ((VersionMS shr 16) < 5) then
result:=true;

end;

function Is64(): boolean;
begin

Result:=IsWin64;
end;

function Is86(): boolean;
begin

Result:= not IsWin64;
end;

function ShouldInstallCR64(): boolean;
begin
result:=false;

if ((is64) and (not IsRestartNeeded)) then
result:=true;
end;

function ShouldInstallCR86(): boolean;
begin
result:=false;

if ((is86) and (not IsRestartNeeded)) then
result:=true;
end;

function IsXP():boolean;
begin

Result:=false;


// Windows 2003 version is 5.2 (server)
if (Version.Major = 5) then begin
Result:=true;

end;
end;

function IsWindows7():boolean;
begin

Result:=false;

// Windows 2003 version is 5.2 (server)
if (Version.Major = 6) then begin
Result:=true;

end;
end;

function IsWindows7OrLater():boolean;
begin

Result:=false;

// Windows 2003 version is 5.2 (server)
if (Version.Major >= 6) then begin
Result:=true;

end;
end;

function InstallThisFile(): boolean;
begin
result:=not IsRestartNeeded;
end;

function CheckWI86(): boolean;
begin
Result:=false;

if ((wineeded) and (ProcessorArchitecture = paX86) and IsWindows7OrLater()) then begin

Result:=true;
end;
end;

function CheckWI64(): boolean;
begin
Result:=false;
if (( wineeded) and (ProcessorArchitecture = paX64) and IsWindows7OrLater()) then begin
Result:=true;
end;

end;

function CheckWIXP86(): boolean;
begin
Result:=false;
if ((wineeded) and (ProcessorArchitecture = paX86) and IsXP()) then begin

Result:=true;

end;
end;

function Checkdotnet(): boolean;
begin
Result:=false;

if (dotNetNeeded and not IsRestartNeeded ) then begin
Result:=true;
end;
end;

function CheckSQLServer86(): boolean;
begin
Result:=false;
if (ProcessorArchitecture = paX86) and (not IsRestartNeeded) then begin

Result:=true;

end;

end;

function CheckSQLServer64(): boolean;
begin
Result:=false;
if (ProcessorArchitecture = paX64) and (not IsRestartNeeded) then begin

Result:=true;

end;
end;


//if Exec(ExpandConstant('{win}\notepad.exe'), '', '', SW_SHOW,
// ewWaitUntilTerminated, ResultCode) then


Procedure InstallCrystalReports() ;
var
path: string;
kode: integer;
Begin
path:= ExpandConstant('{app}\cr.exe');
//msgbox (path, mbInformation, MB_OK);
lastcaption:=WizardForm.StatusLabel.Caption;
WizardForm.StatusLabel.Caption := 'Installing Crystal Report 2008 Runtime... (This may take a few minutes)'
Exec(path,'', '', SW_Show, ewWaitUntilTerminated,kode);
WizardForm.StatusLabel.Caption := lastcaption;
End;

Procedure InstallWindowsInstaller() ;
var
path: string;
kode: integer;
Begin
path:= ExpandConstant('{app}\wi.exe');
//msgbox (path, mbInformation, MB_OK);

lastcaption:=WizardForm.StatusLabel.Caption;
WizardForm.StatusLabel.Caption := 'Installing Windows Installer 4.5... (This may take a few minutes)'
Exec(path,'/Q', '', SW_hide, ewWaitUntilTerminated,kode);
WizardForm.StatusLabel.Caption := lastcaption;

//msgbox('This install need to reboot the computer. Please close all the application', mbInformation, MB_OK);
if IsComponentSelected('sqlserver') then begin
IsRestartNeeded:=true;
RegWriteStringValue(HKLM, 'Software\Microsoft\Windows\CurrentVersion\RunOnce',RunOnceName, ExpandConstant('{src}\' + filename ));
RegWriteStringValue(HKEYCURRENTUSER, 'Software\MyApp','MyApp', '1' );
end;
End;

Procedure InstallDotNet() ;
var
path: string;
kode: integer;
Begin
path:= ExpandConstant('{app}\dotnetfx35.exe');
//msgbox (path, mbInformation, MB_OK);
lastcaption:=WizardForm.StatusLabel.Caption;
WizardForm.StatusLabel.Caption := 'Installing .NET Framework 3.5 SP1... (This may take a few minutes) '
Exec(path,'/Q /Norestart', '', SW_hide, ewWaitUntilTerminated,kode);
WizardForm.StatusLabel.Caption := lastcaption;
End;

Procedure InstallSQLServer();
var
path: string;
kode: integer;
Begin
if sqlserverneeded then
begin
path:= ExpandConstant('{app}\sql.exe');
lastcaption:=WizardForm.StatusLabel.Caption;
WizardForm.StatusLabel.Caption := 'Installing SQL Server 2008 Express R2 SP2... (This may take a few minutes) '
Exec(path,'/Q /Action=install /FEATURES=SQL /INSTANCENAME=MSSQLSERVER /SQLSVCACCOUNT="NT AUTHORITY\NETWORK SERVICE" /SQLSYSADMINACCOUNTS="BUILTIN\ADMINISTRATORS" /AGTSVCACCOUNT="NT AUTHORITY \Network Service" /SECURITYMODE=SQL /SAPWD=@pass /IACCEPTSQLSERVERLICENSETERMS /TCPENABLED=1', '', SW_hide, ewWaitUntilTerminated,kode);
WizardForm.StatusLabel.Caption := lastcaption;
end;
End;

Procedure RemoveSQLServer() ;
var
path: string;
kode: integer;
Begin

if (RegKeyExists(HKLM, 'SOFTWARE\Microsoft\Microsoft SQL Server\100\10.50')) then begin
path:= ExpandConstant('{app}\sql.exe');
lastcaption:=WizardForm.StatusLabel.Caption;
WizardForm.StatusLabel.Caption := 'Removing SQL Server 2008 Express R2 SP2... (This may take a few minutes) '
Exec(path,'/Q /Action=uninstall /FEATURES=SQL /INSTANCENAME=MSSQLSERVER ', '', SW_hide, ewWaitUntilTerminated,kode);
WizardForm.StatusLabel.Caption := lastcaption;

end;

End;

function IsNeedRestart(): boolean;
begin
result:= IsRestartNeeded;
end;

function InitializeSetup(): Boolean;

begin
msipath:=ExpandConstant('{sys}\msi.dll');
IsRestartNeeded:=false;
dotNetNeeded := false;
filename:='BIS 1.0 Setup Full';
GetWindowsVersionEx(Version);
GetVersionNumbers(msipath, versionMS, versionLS)

SkipOtherPage:=true;

if ((RegValueExists(HKLM, 'Software\Microsoft\Windows\CurrentVersion\RunOnce',RunOnceName)) and (RegValueExists(HKEYCURRENTUSER,'Software\MyApp', 'MyApp'))) then
begin
MsgBox('Setup needs to reboot your computer before continue installing', mbError, mb_Ok);
result:=false;
end else
begin
if RegValueExists(HKEYCURRENTUSER,'Software\MyApp', 'MyApp') then
begin
RegDeleteKeyIncludingSubkeys(HKEYCURRENTUSER,'Software\MyApp');
HasRestarted:=true;
end else
begin


if (WindowsInstallerVersionBelow45 and not HasRestarted) then begin
wineeded := true;
memoDependenciesNeeded := memoDependenciesNeeded + ' Windows Installer 4.5' #13;
end;



end;

Result := true;

// Check for required netfx installation
if (not RegKeyExists(HKLM, 'Software\Microsoft\.NETFramework\AssemblyFolders\v3.5')) then begin
dotNetNeeded := true;
if (not IsAdminLoggedOn()) then begin
MsgBox('This Appliacation needs the Microsoft .NET Framework 3.5 to be installed by an Administrator', mbInformation, MB_OK);
Result := false;
end else begin
memoDependenciesNeeded := memoDependenciesNeeded + ' .NET Framework 3.5 SP 1' #13;

end;
end;




end;
end;

function UpdateReadyMemo(Space, NewLine, MemoUserInfoInfo, MemoDirInfo, MemoTypeInfo, MemoComponentsInfo, MemoGroupInfo, MemoTasksInfo: String): String;
var
s: string;

begin
if memoDependenciesNeeded <> '' then s := s 'Dependencies to install:' NewLine + memoDependenciesNeeded;

s:= s SQLDependency NewLine;

s := s MemoDirInfo NewLine + NewLine;

Result := s
end;

function PrepareToInstall(var NeedsRestart: Boolean): String;
begin
if IsComponentSelected('sqlserver') then begin
if (not RegKeyExists(HKLM, 'SOFTWARE\Microsoft\Microsoft SQL Server\100\10.50')) then begin
sqlserverneeded := true;

end;
end;
end;


function ShouldSkipPage(PageID: Integer): Boolean;
begin
if HasRestarted then begin
//or (pageid=wpInfoAfter) or (pageid=wpFinished)
if ((pageid=wpReady) and (SkipOtherPage=true)) then begin
WizardForm.ComponentsList.ItemEnabled1;
SkipOtherPage:=false;
result:=true;
end
else
begin
result:=true;
end;
end;
end;

Function NeedRestart(): Boolean;
begin
result:= IsRestartNeeded;
end;

procedure CurPageChanged(CurPageID: Integer);
begin
if curpageid = wpSelectTasks then begin
if IsComponentSelected('sqlserver') then begin
SQLDependency := ' SQL Server 2008 Express R2 SP2' #13;

end else
begin
SQLDependency:='' ;
end;
end;

if HasRestarted then begin
if curpageid = wpSelectTasks then begin
SQLDependency := ' SQL Server 2008 Express R2 SP2' #13;
end else begin
SQLDependency:='';
end;
end;
end;
procedure DeinitializeSetup();
begin

if (IsRestartNeeded and sqlserverneeded) then begin

end;

end;

Additional information on starting a new project is available here: Project Startup Guide.

Last edited Oct 9, 2012 at 12:51 PM by Sirsteven, version 6