Update products.iss

Update products.iss

#include "isxdl\isxdl.iss"

[CustomMessages]
DependenciesDir=MyProgramDependencies

depdownload_msg=The following applications are required before setup can continue:%n%n%1%nDownload and install now?
pl.depdownload_msg=Do kontynuowania instalacji wymagane są następujące aplikacje:%n%n%1%nPobrać i zainstalować teraz?
fr.depdownload_msg=The following applications are required before setup can continue:%n%n%1%nDownload and install now?
de.depdownload_msg=The following applications are required before setup can continue:%n%n%1%nDownload and install now?
hu.depdownload_msg=Ezekre az alkalmazásokra szükség van a telepítés folytatása elõtt:%n%n%1%nLetölti és telepíti õket?
sl.depdownload_msg=Naslednje aplikacije so potrebne, preden se lahko nadaljuje namestitev:%n%n%1%nNaj jih zdaj prenesem in namestim?
nl.depdownload_msg=De volgende programma's zijn vereist, alvorens de setup kan voortgaan:%n%n%1%nDownloaden en nu installeren?
es.depdownload_msg=Las siguientes aplicaciones son necesarias antes que la instalación pueda continuar:%n%n%1%n¿Deseas Descargar e instalar ahora?

depdownload_memo_title=Download dependencies
pl.depdownload_memo_title=Pobierz zależności
fr.depdownload_memo_title=Télécharger dépendances
de.depdownload_memo_title=Download Abhängigkeiten
hu.depdownload_memo_title=Függõségek letöltése
sl.depdownload_memo_title=Prenesi odvisnosti
nl.depdownload_memo_title=Downloaden afhankelijkheden
es.depdownload_memo_title=Descargar dependencias

depinstall_memo_title=Install dependencies
pl.depinstall_memo_title=Zainstaluj zależności
fr.depinstall_memo_title=Installer les dépendances
de.depinstall_memo_title=Installieren Sie Abhängigkeiten
hu.depinstall_memo_title=Függõségek telepítése
sl.depinstall_memo_title=Namesti odvisnosti
nl.depinstall_memo_title=Installeren afhankelijkheden
es.depinstall_memo_title=Instalar dependencias

depinstall_title=Installing dependencies
pl.depinstall_title=Instalacja zależności
fr.depinstall_title=Installation des dépendances
de.depinstall_title=Installation von Abhängigkeiten
hu.depinstall_title=Függõségek telepítése
sl.depinstall_title=Namestitev odvisnosti
nl.depinstall_title=Installeren afhankelijkheden
es.depinstall_title=Instalando dependencias

depinstall_description=Please wait while Setup installs dependencies on your computer.
pl.depinstall_description=Poczekaj aż instalator instaluje zależności na twoim komputerze.
fr.depinstall_description=Please wait while Setup installs dependencies on your computer.
de.depinstall_description=Please wait while Setup installs dependencies on your computer.
hu.depinstall_description=Kérem várjon, amíg a függõségek telepítésre kerülnek a gépére.
sl.depinstall_description=Poèakajte, da Setup namesti odvisnosti v vaš raèunalnik.
nl.depinstall_description=Even wachten a.u.b. Setup installeerd de afhankelijkheden op uw computer.
es.depinstall_description=Espere mientras el programa de instalación instala las dependencias en su equipo.

depinstall_status=Installing %1...
pl.depinstall_status=Instalacja %1...
fr.depinstall_status=Installation %1...
de.depinstall_status=Installieren %1...
hu.depinstall_status=%1 telepítése...
sl.depinstall_status=Namestitev %1...
nl.depinstall_status=Installeren %1...
es.depinstall_status=Instalando %1...

depinstall_missing=%1 must be installed before setup can continue. Please install %1 and run Setup again.
pl.depinstall_missing=%1 musi być zainstalowany zanim instalacja może być kontynuowana. Zainstaluj %1 i ponownie uruchom program instalacyjny.
fr.depinstall_missing=%1 must be installed before setup can continue. Please install %1 and run Setup again.
de.depinstall_missing=%1 must be installed before setup can continue. Please install %1 and run Setup again.
hu.depinstall_missing=A(z) %1 -t telepíteni kell a folytatás elõtt. Telepítse a(z) %1 -t, majd a telepítõt.
sl.depinstall_missing=%1 mora biti namešèen, preden se lahko namestitev nadaljuje. Prosimo namestite %1 in znova zaženite Setup.
nl.depinstall_missing=%1 moet worden geïnstalleerd voor dat setup verder kan gaan. Installeer %1 en voer setup opnieuw uit.
es.depinstall_missing=%1 debe ser instalado antes de que la instalación pueda continuar. Instalar %1 y vuelva a ejecutar el programa de instalación.

depinstall_error=An error occured while installing the dependencies. Please restart the computer and run the setup again or install the following dependencies manually:%n
pl.depinstall_error=Wystąpił błąd podczas instalowania zależności. Uruchom ponownie komputer i ponownie uruchom instalację lub ręcznie zainstaluj następujące zależności:%n
fr.depinstall_error=An error occured while installing the dependencies. Please restart the computer and run the setup again or install the following dependencies manually:%n
de.depinstall_error=An error occured while installing the dependencies. Please restart the computer and run the setup again or install the following dependencies manually:%n
hu.depinstall_error=Egy hiba történt a függõségek telepítése közben. Kérem, hogy indítsa újra a gépét, majd kézzel telepítse újra a következõ függõségeket:%n
sl.depinstall_error=Pri namestitvi odvisnosti je prišlo do napake. Znova zaženite raèunalnik in znova zaženite Setup ali roèno namestite naslednje odvisnosti:%n
nl.depinstall_error=Er trad een fout op tijdens het installeren van de afhankelijkheden. Herstart de computer en voer de setup opnieuw uit of installeer de volgende afhankelijkheden handmatig:%n
es.depinstall_error=Se produjo un error al instalar las dependencias. Reinicie el equipo y vuelva a ejecutar la instalación o instale las siguientes dependencias manualmente:%n

isxdl_langfile=

[Files]
Source: "scripts\isxdl\english.ini"; Flags: dontcopy; Languages: en
Source: "scripts\isxdl\polish.ini"; Flags: dontcopy; Languages: pl
Source: "scripts\isxdl\german2.ini"; Flags: dontcopy; Languages: de
Source: "scripts\isxdl\french2.ini"; Flags: dontcopy; Languages: fr
Source: "scripts\isxdl\spanish.ini"; Flags: dontcopy; Languages: es

[Code]
type
	TProduct = record
		File: String;
		Title: String;
		Parameters: String;
		InstallClean : boolean;
		MustRebootAfter : boolean;
	end;

	InstallResult = (InstallSuccessful, InstallRebootRequired, InstallError);

var
	installMemo, downloadMemo, downloadMessage: string;
	products: array of TProduct;
	delayedReboot: boolean;
	DependencyPage: TOutputProgressWizardPage;

procedure AddProduct(FileName, Parameters, Title, Size, URL: string; InstallClean : boolean; MustRebootAfter : boolean);
var
	path: string;
	i: Integer;
begin
	installMemo := installMemo + '%1' + Title + #13;

	path := ExpandConstant('{src}{\}') + CustomMessage('DependenciesDir') + '\' + FileName;
	if not FileExists(path) then begin
		path := ExpandConstant('{tmp}{\}') + FileName;

		isxdl_AddFile(URL, path);

		downloadMemo := downloadMemo + '%1' + Title + #13;
		downloadMessage := downloadMessage + '	' + Title + ' (' + Size + ')' + #13;
	end;

	i := GetArrayLength(products);
	SetArrayLength(products, i + 1);
	products[i].File := path;
	products[i].Title := Title;
	products[i].Parameters := Parameters;
	products[i].InstallClean := InstallClean;
	products[i].MustRebootAfter := MustRebootAfter;
end;

function SmartExec(prod : TProduct; var ResultCode : Integer) : boolean;
begin
	if (LowerCase(Copy(prod.File,Length(prod.File)-2,3)) = 'exe') then begin
		Result := Exec(prod.File, prod.Parameters, '', SW_SHOWNORMAL, ewWaitUntilTerminated, ResultCode);
	end else begin
		Result := ShellExec('', prod.File, prod.Parameters, '', SW_SHOWNORMAL, ewWaitUntilTerminated, ResultCode);
	end;
end;

function PendingReboot : boolean;
var	names: String;
begin
	if (RegQueryMultiStringValue(HKEY_LOCAL_MACHINE, 'SYSTEM\CurrentControlSet\Control\Session Manager', 'PendingFileRenameOperations', names)) then begin
		Result := true;
	end else if ((RegQueryMultiStringValue(HKEY_LOCAL_MACHINE, 'SYSTEM\CurrentControlSet\Control\Session Manager', 'SetupExecute', names)) and (names <> ''))  then begin
		Result := true;
	end else begin
		Result := false;
	end;
end;

function InstallProducts: InstallResult;
var
	ResultCode, i, productCount, finishCount: Integer;
begin
	Result := InstallSuccessful;
	productCount := GetArrayLength(products);

	if productCount > 0 then begin
		DependencyPage := CreateOutputProgressPage(CustomMessage('depinstall_title'), CustomMessage('depinstall_description'));
		DependencyPage.Show;

		for i := 0 to productCount - 1 do begin
			if (products[i].InstallClean and (delayedReboot or PendingReboot())) then begin
				Result := InstallRebootRequired;
				break;
			end;

			DependencyPage.SetText(FmtMessage(CustomMessage('depinstall_status'), [products[i].Title]), '');
			DependencyPage.SetProgress(i, productCount);

			if SmartExec(products[i], ResultCode) then begin
				//setup executed; ResultCode contains the exit code
				//MsgBox(products[i].Title + ' install executed. Result Code: ' + IntToStr(ResultCode), mbInformation, MB_OK);
				if (products[i].MustRebootAfter) then begin
					//delay reboot after install if we installed the last dependency anyways
					if (i = productCount - 1) then begin
						delayedReboot := true;
					end else begin
						Result := InstallRebootRequired;
					end;
					break;
				end else if (ResultCode = 0) then begin
					finishCount := finishCount + 1;
				end else if (ResultCode = 3010) then begin
					//ResultCode 3010: A restart is required to complete the installation. This message indicates success.
					delayedReboot := true;
					finishCount := finishCount + 1;
				end else begin
					Result := InstallError;
					break;
				end;
			end else begin
				//MsgBox(products[i].Title + ' install failed. Result Code: ' + IntToStr(ResultCode), mbInformation, MB_OK);
				Result := InstallError;
				break;
			end;
		end;

		//only leave not installed products for error message
		for i := 0 to productCount - finishCount - 1 do begin
			products[i] := products[i+finishCount];
		end;
		SetArrayLength(products, productCount - finishCount);

		DependencyPage.Hide;
	end;
end;

function PrepareToInstall(var NeedsRestart: boolean): String;
var
	i: Integer;
	s: string;
begin
	delayedReboot := false;

	case InstallProducts() of
		InstallError: begin
			s := CustomMessage('depinstall_error');

			for i := 0 to GetArrayLength(products) - 1 do begin
				s := s + #13 + '	' + products[i].Title;
			end;

			Result := s;
			end;
		InstallRebootRequired: begin
			Result := products[0].Title;
			NeedsRestart := true;

			//write into the registry that the installer needs to be executed again after restart
			RegWriteStringValue(HKEY_CURRENT_USER, 'SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce', 'InstallBootstrap', ExpandConstant('{srcexe}'));
			end;
	end;
end;

function NeedRestart : boolean;
begin
	if (delayedReboot) then
		Result := true;
end;

function UpdateReadyMemo(Space, NewLine, MemoUserInfoInfo, MemoDirInfo, MemoTypeInfo, MemoComponentsInfo, MemoGroupInfo, MemoTasksInfo: String): String;
var
	s: string;
begin
	if downloadMemo <> '' then
		s := s + CustomMessage('depdownload_memo_title') + ':' + NewLine + FmtMessage(downloadMemo, [Space]) + NewLine;
	if installMemo <> '' then
		s := s + CustomMessage('depinstall_memo_title') + ':' + NewLine + FmtMessage(installMemo, [Space]) + NewLine;

	s := s + MemoDirInfo + NewLine + NewLine + MemoGroupInfo

	if MemoTasksInfo <> '' then
		s := s + NewLine + NewLine + MemoTasksInfo;

	Result := s
end;

function NextButtonClick(CurPageID: Integer): boolean;
begin
	Result := true;

	if CurPageID = wpReady then begin
		if downloadMemo <> '' then begin
			//change isxdl language only if it is not english because isxdl default language is already english
			if (ActiveLanguage() <> 'en') then begin
				ExtractTemporaryFile(CustomMessage('isxdl_langfile'));
				isxdl_SetOption('language', ExpandConstant('{tmp}{\}') + CustomMessage('isxdl_langfile'));
			end;
			//isxdl_SetOption('title', FmtMessage(SetupMessage(msgSetupWindowTitle), [CustomMessage('appname')]));

			if SuppressibleMsgBox(FmtMessage(CustomMessage('depdownload_msg'), [downloadMessage]), mbConfirmation, MB_YESNO, IDYES) = IDNO then
				Result := false
			else if isxdl_DownloadFiles(StrToInt(ExpandConstant('{wizardhwnd}'))) = 0 then
				Result := false;
		end;
	end;
end;

function IsX86: boolean;
begin
	Result := (ProcessorArchitecture = paX86) or (ProcessorArchitecture = paUnknown);
end;

function IsX64: boolean;
begin
	Result := Is64BitInstallMode and (ProcessorArchitecture = paX64);
end;

function IsIA64: boolean;
begin
	Result := Is64BitInstallMode and (ProcessorArchitecture = paIA64);
end;

function GetString(x86, x64, ia64: String): String;
begin
	if IsX64() and (x64 <> '') then begin
		Result := x64;
	end else if IsIA64() and (ia64 <> '') then begin
		Result := ia64;
	end else begin
		Result := x86;
	end;
end;

function GetArchitectureString(): String;
begin
	if IsX64() then begin
		Result := '_x64';
	end else if IsIA64() then begin
		Result := '_ia64';
	end else begin
		Result := '';
	end;
end;

#include "isxdl\isxdl.iss"

[CustomMessages]
DependenciesDir=MyProgramDependencies

depdownload_msg=The following applications are required before setup can continue:%n%n%1%nDownload and install now?
pl.depdownload_msg=Do kontynuowania instalacji wymagane są następujące aplikacje:%n%n%1%nPobrać i zainstalować teraz?
fr.depdownload_msg=The following applications are required before setup can continue:%n%n%1%nDownload and install now?
de.depdownload_msg=The following applications are required before setup can continue:%n%n%1%nDownload and install now?
hu.depdownload_msg=Ezekre az alkalmazásokra szükség van a telepítés folytatása elõtt:%n%n%1%nLetölti és telepíti õket?
sl.depdownload_msg=Naslednje aplikacije so potrebne, preden se lahko nadaljuje namestitev:%n%n%1%nNaj jih zdaj prenesem in namestim?
nl.depdownload_msg=De volgende programma's zijn vereist, alvorens de setup kan voortgaan:%n%n%1%nDownloaden en nu installeren?

depdownload_memo_title=Download dependencies
pl.depdownload_memo_title=Pobierz zależności
fr.depdownload_memo_title=Télécharger dépendances
de.depdownload_memo_title=Download Abhängigkeiten
hu.depdownload_memo_title=Függõségek letöltése
sl.depdownload_memo_title=Prenesi odvisnosti
nl.depdownload_memo_title=Downloaden afhankelijkheden

depinstall_memo_title=Install dependencies
pl.depinstall_memo_title=Zainstaluj zależności
fr.depinstall_memo_title=Installer les dépendances
de.depinstall_memo_title=Installieren Sie Abhängigkeiten
hu.depinstall_memo_title=Függõségek telepítése
sl.depinstall_memo_title=Namesti odvisnosti
nl.depinstall_memo_title=Installeren afhankelijkheden

depinstall_title=Installing dependencies
pl.depinstall_title=Instalacja zależności
fr.depinstall_title=Installation des dépendances
de.depinstall_title=Installation von Abhängigkeiten
hu.depinstall_title=Függõségek telepítése
sl.depinstall_title=Namestitev odvisnosti
nl.depinstall_title=Installeren afhankelijkheden

depinstall_description=Please wait while Setup installs dependencies on your computer.
pl.depinstall_description=Poczekaj aż instalator instaluje zależności na twoim komputerze.
fr.depinstall_description=Please wait while Setup installs dependencies on your computer.
de.depinstall_description=Please wait while Setup installs dependencies on your computer.
hu.depinstall_description=Kérem várjon, amíg a függõségek telepítésre kerülnek a gépére.
sl.depinstall_description=Poèakajte, da Setup namesti odvisnosti v vaš raèunalnik.
nl.depinstall_description=Even wachten a.u.b. Setup installeerd de afhankelijkheden op uw computer.

depinstall_status=Installing %1...
pl.depinstall_status=Instalacja %1...
fr.depinstall_status=Installation %1...
de.depinstall_status=Installieren %1...
hu.depinstall_status=%1 telepítése...
sl.depinstall_status=Namestitev %1...
nl.depinstall_status=Installeren %1...

depinstall_missing=%1 must be installed before setup can continue. Please install %1 and run Setup again.
pl.depinstall_missing=%1 musi być zainstalowany zanim instalacja może być kontynuowana. Zainstaluj %1 i ponownie uruchom program instalacyjny.
fr.depinstall_missing=%1 must be installed before setup can continue. Please install %1 and run Setup again.
de.depinstall_missing=%1 must be installed before setup can continue. Please install %1 and run Setup again.
hu.depinstall_missing=A(z) %1 -t telepíteni kell a folytatás elõtt. Telepítse a(z) %1 -t, majd a telepítõt.
sl.depinstall_missing=%1 mora biti namešèen, preden se lahko namestitev nadaljuje. Prosimo namestite %1 in znova zaženite Setup.
nl.depinstall_missing=%1 moet worden geïnstalleerd voor dat setup verder kan gaan. Installeer %1 en voer setup opnieuw uit.

depinstall_error=An error occured while installing the dependencies. Please restart the computer and run the setup again or install the following dependencies manually:%n
pl.depinstall_error=Wystąpił błąd podczas instalowania zależności. Uruchom ponownie komputer i ponownie uruchom instalację lub ręcznie zainstaluj następujące zależności:%n
fr.depinstall_error=An error occured while installing the dependencies. Please restart the computer and run the setup again or install the following dependencies manually:%n
de.depinstall_error=An error occured while installing the dependencies. Please restart the computer and run the setup again or install the following dependencies manually:%n
hu.depinstall_error=Egy hiba történt a függõségek telepítése közben. Kérem, hogy indítsa újra a gépét, majd kézzel telepítse újra a következõ függõségeket:%n
sl.depinstall_error=Pri namestitvi odvisnosti je prišlo do napake. Znova zaženite raèunalnik in znova zaženite Setup ali roèno namestite naslednje odvisnosti:%n
nl.depinstall_error=Er trad een fout op tijdens het installeren van de afhankelijkheden. Herstart de computer en voer de setup opnieuw uit of installeer de volgende afhankelijkheden handmatig:%n

isxdl_langfile=

[Files]
Source: "scripts\isxdl\english.ini"; Flags: dontcopy; Languages: en
Source: "scripts\isxdl\polish.ini"; Flags: dontcopy; Languages: pl
Source: "scripts\isxdl\german2.ini"; Flags: dontcopy; Languages: de
Source: "scripts\isxdl\french2.ini"; Flags: dontcopy; Languages: fr

[Code]
type
	TProduct = record
		File: String;
		Title: String;
		Parameters: String;
		InstallClean : boolean;
		MustRebootAfter : boolean;
	end;

	InstallResult = (InstallSuccessful, InstallRebootRequired, InstallError);

var
	installMemo, downloadMemo, downloadMessage: string;
	products: array of TProduct;
	delayedReboot: boolean;
	DependencyPage: TOutputProgressWizardPage;

procedure AddProduct(FileName, Parameters, Title, Size, URL: string; InstallClean : boolean; MustRebootAfter : boolean);
var
	path: string;
	i: Integer;
begin
	installMemo := installMemo + '%1' + Title + #13;

	path := ExpandConstant('{src}{\}') + CustomMessage('DependenciesDir') + '\' + FileName;
	if not FileExists(path) then begin
		path := ExpandConstant('{tmp}{\}') + FileName;

		isxdl_AddFile(URL, path);

		downloadMemo := downloadMemo + '%1' + Title + #13;
		downloadMessage := downloadMessage + '	' + Title + ' (' + Size + ')' + #13;
	end;

	i := GetArrayLength(products);
	SetArrayLength(products, i + 1);
	products[i].File := path;
	products[i].Title := Title;
	products[i].Parameters := Parameters;
	products[i].InstallClean := InstallClean;
	products[i].MustRebootAfter := MustRebootAfter;
end;

function SmartExec(prod : TProduct; var ResultCode : Integer) : boolean;
begin
	if (LowerCase(Copy(prod.File,Length(prod.File)-2,3)) = 'exe') then begin
		Result := Exec(prod.File, prod.Parameters, '', SW_SHOWNORMAL, ewWaitUntilTerminated, ResultCode);
	end else begin
		Result := ShellExec('', prod.File, prod.Parameters, '', SW_SHOWNORMAL, ewWaitUntilTerminated, ResultCode);
	end;
end;

function PendingReboot : boolean;
var	names: String;
begin
	if (RegQueryMultiStringValue(HKEY_LOCAL_MACHINE, 'SYSTEM\CurrentControlSet\Control\Session Manager', 'PendingFileRenameOperations', names)) then begin
		Result := true;
	end else if ((RegQueryMultiStringValue(HKEY_LOCAL_MACHINE, 'SYSTEM\CurrentControlSet\Control\Session Manager', 'SetupExecute', names)) and (names <> ''))  then begin
		Result := true;
	end else begin
		Result := false;
	end;
end;

function InstallProducts: InstallResult;
var
	ResultCode, i, productCount, finishCount: Integer;
begin
	Result := InstallSuccessful;
	productCount := GetArrayLength(products);

	if productCount > 0 then begin
		DependencyPage := CreateOutputProgressPage(CustomMessage('depinstall_title'), CustomMessage('depinstall_description'));
		DependencyPage.Show;

		for i := 0 to productCount - 1 do begin
			if (products[i].InstallClean and (delayedReboot or PendingReboot())) then begin
				Result := InstallRebootRequired;
				break;
			end;

			DependencyPage.SetText(FmtMessage(CustomMessage('depinstall_status'), [products[i].Title]), '');
			DependencyPage.SetProgress(i, productCount);

			if SmartExec(products[i], ResultCode) then begin
				//setup executed; ResultCode contains the exit code
				//MsgBox(products[i].Title + ' install executed. Result Code: ' + IntToStr(ResultCode), mbInformation, MB_OK);
				if (products[i].MustRebootAfter) then begin
					//delay reboot after install if we installed the last dependency anyways
					if (i = productCount - 1) then begin
						delayedReboot := true;
					end else begin
						Result := InstallRebootRequired;
					end;
					break;
				end else if (ResultCode = 0) then begin
					finishCount := finishCount + 1;
				end else if (ResultCode = 3010) then begin
					//ResultCode 3010: A restart is required to complete the installation. This message indicates success.
					delayedReboot := true;
					finishCount := finishCount + 1;
				end else begin
					Result := InstallError;
					break;
				end;
			end else begin
				//MsgBox(products[i].Title + ' install failed. Result Code: ' + IntToStr(ResultCode), mbInformation, MB_OK);
				Result := InstallError;
				break;
			end;
		end;

		//only leave not installed products for error message
		for i := 0 to productCount - finishCount - 1 do begin
			products[i] := products[i+finishCount];
		end;
		SetArrayLength(products, productCount - finishCount);

		DependencyPage.Hide;
	end;
end;

function PrepareToInstall(var NeedsRestart: boolean): String;
var
	i: Integer;
	s: string;
begin
	delayedReboot := false;

	case InstallProducts() of
		InstallError: begin
			s := CustomMessage('depinstall_error');

			for i := 0 to GetArrayLength(products) - 1 do begin
				s := s + #13 + '	' + products[i].Title;
			end;

			Result := s;
			end;
		InstallRebootRequired: begin
			Result := products[0].Title;
			NeedsRestart := true;

			//write into the registry that the installer needs to be executed again after restart
			RegWriteStringValue(HKEY_CURRENT_USER, 'SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce', 'InstallBootstrap', ExpandConstant('{srcexe}'));
			end;
	end;
end;

function NeedRestart : boolean;
begin
	if (delayedReboot) then
		Result := true;
end;

function UpdateReadyMemo(Space, NewLine, MemoUserInfoInfo, MemoDirInfo, MemoTypeInfo, MemoComponentsInfo, MemoGroupInfo, MemoTasksInfo: String): String;
var
	s: string;
begin
	if downloadMemo <> '' then
		s := s + CustomMessage('depdownload_memo_title') + ':' + NewLine + FmtMessage(downloadMemo, [Space]) + NewLine;
	if installMemo <> '' then
		s := s + CustomMessage('depinstall_memo_title') + ':' + NewLine + FmtMessage(installMemo, [Space]) + NewLine;

	s := s + MemoDirInfo + NewLine + NewLine + MemoGroupInfo

	if MemoTasksInfo <> '' then
		s := s + NewLine + NewLine + MemoTasksInfo;

	Result := s
end;

function NextButtonClick(CurPageID: Integer): boolean;
begin
	Result := true;

	if CurPageID = wpReady then begin
		if downloadMemo <> '' then begin
			//change isxdl language only if it is not english because isxdl default language is already english
			if (ActiveLanguage() <> 'en') then begin
				ExtractTemporaryFile(CustomMessage('isxdl_langfile'));
				isxdl_SetOption('language', ExpandConstant('{tmp}{\}') + CustomMessage('isxdl_langfile'));
			end;
			//isxdl_SetOption('title', FmtMessage(SetupMessage(msgSetupWindowTitle), [CustomMessage('appname')]));

			if SuppressibleMsgBox(FmtMessage(CustomMessage('depdownload_msg'), [downloadMessage]), mbConfirmation, MB_YESNO, IDYES) = IDNO then
				Result := false
			else if isxdl_DownloadFiles(StrToInt(ExpandConstant('{wizardhwnd}'))) = 0 then
				Result := false;
		end;
	end;
end;

function IsX86: boolean;
begin
	Result := (ProcessorArchitecture = paX86) or (ProcessorArchitecture = paUnknown);
end;

function IsX64: boolean;
begin
	Result := Is64BitInstallMode and (ProcessorArchitecture = paX64);
end;

function IsIA64: boolean;
begin
	Result := Is64BitInstallMode and (ProcessorArchitecture = paIA64);
end;

function GetString(x86, x64, ia64: String): String;
begin
	if IsX64() and (x64 <> '') then begin
		Result := x64;
	end else if IsIA64() and (ia64 <> '') then begin
		Result := ia64;
	end else begin
		Result := x86;
	end;
end;

function GetArchitectureString(): String;
begin
	if IsX64() then begin
		Result := '_x64';
	end else if IsIA64() then begin
		Result := '_ia64';
	end else begin
		Result := '';
	end;
end;


Updated IE tweaks for the installer.

Updated IE tweaks for the installer.

Enabled "Allow Active Content to run in files in my computer"
Enabled "Reset zoom level for new windows and tabs"

#define ASSEMBLY_PATH ".\Selenium\bin\Release\Selenium.dll"
#define ASSEMBLY_VERSION GetFileVersion(ASSEMBLY_PATH)

#define AppName "Selenium"
#define AppID "{{0277FC34-FD1B-4616-BB19-1FDB7381B291}"
#define AppLongName "Selenium Basic"
#define AppPublisher "Florent BREHERET"
#define AppURL "https://github.com/florentbr/SeleniumBasic"
#define AppFolder "SeleniumBasic"
#define AppSetupFilename "SeleniumBasic-" + ASSEMBLY_VERSION

[Setup]

AppId={#AppID}
PrivilegesRequired=lowest
AppName={#AppLongName}
AppVersion={#ASSEMBLY_VERSION}
AppVerName={#AppLongName}
VersionInfoVersion={#ASSEMBLY_VERSION}
VersionInfoTextVersion={#ASSEMBLY_VERSION}
AppPublisher={#AppPublisher}
AppPublisherURL={#AppURL}
AppSupportURL={#AppURL}
AppUpdatesURL={#AppURL}
DisableDirPage=yes
DefaultDirName={code:GetRootDir}
UsePreviousAppDir=no
UsePreviousSetupType=yes
DefaultGroupName={#AppLongName}
DisableProgramGroupPage=yes
LicenseFile=.\LICENSE.txt
OutputDir="."
OutputBaseFilename={#AppSetupFilename}
;Compression=zip
Compression=lzma2
SolidCompression=yes
DirExistsWarning=no
ArchitecturesInstallIn64BitMode=x64

[Languages]
Name: "english"; MessagesFile: "compiler:Default.isl"

[CustomMessages]
MsgNETFrameworkNotInstalled=Microsoft .NET Framework 3.5 installation was Not detected.
MsgRegistryWriteFailure=Failed to register the library due to insufficient privileges.
MsgFileNotFound=File Not found: %1.
MsgCOMInvokeFailed=Installation failed. The installer was unable to call the registered library.

[Components]
Name: "pkg_core"; Description: ".Net core libraries";                         Types: full compact custom; Flags: fixed;
Name: "pkg_doc";  Description: "Templates and examples";                      Types: full compact custom;
Name: "pkg_cons"; Description: "Enhanced console runner for VBScript files";  Types: full compact custom;
Name: "pkg_ff";   Description: "WebDriver for Firefox";                       Types: full custom;
Name: "pkg_cr";   Description: "WebDriver for Chrome";                        Types: full custom;
Name: "pkg_op";   Description: "WebDriver for Opera";                         Types: full custom;
Name: "pkg_ie";   Description: "WebDriver for Internet Explorer";             Types: full custom;
Name: "pkg_edg";  Description: "WebDriver for Microsoft Edge";                Types: full custom;
Name: "pkg_pjs";  Description: "WebDriver for PhantomJS (headless browser)";  Types: full custom;
Name: "pkg_ide";  Description: "SeleniumIDE plugin for Firefox";              Types: full custom;

[Files]
Source: "Selenium\bin\Release\Selenium.dll";   DestDir: "{app}"; Flags: ignoreversion; Components: pkg_core;
Source: "Selenium\bin\Release\Selenium.pdb";   DestDir: "{app}"; Flags: ignoreversion; Components: pkg_core;
Source: "Selenium\bin\Release\Selenium32.tlb"; DestDir: "{app}"; Flags: ignoreversion; Components: pkg_core;
Source: "Selenium\bin\Release\Selenium64.tlb"; DestDir: "{app}"; Flags: ignoreversion; Components: pkg_core; Check: IsWin64;

Source: "Selenium\bin\Help\Selenium.chm"; DestDir: "{app}"; Flags: ignoreversion; Components: pkg_core;

Source: "LICENSE.txt";   DestDir: "{app}"; Flags: ignoreversion overwritereadonly ; Attribs:readonly;
Source: "CHANGELOG.txt"; DestDir: "{app}"; Flags: ignoreversion overwritereadonly ; Attribs:readonly;

Source: "VbsConsole\bin\Release\vbsc.exe"; DestDir: "{app}"; Flags: ignoreversion; Components: pkg_cons;

;drivers
Source: "References\firefoxdriver.xpi"; DestDir: "{app}"; Flags: ignoreversion; Components: pkg_ff;
Source: "References\chromedriver.exe";  DestDir: "{app}"; Flags: ignoreversion; Components: pkg_cr;
Source: "References\operadriver.exe";   DestDir: "{app}"; Flags: ignoreversion; Components: pkg_op;
Source: "References\phantomjs.exe";     DestDir: "{app}"; Flags: ignoreversion; Components: pkg_pjs;
Source: "References\iedriver.exe";      DestDir: "{app}"; Flags: ignoreversion; Components: pkg_ie;
;Source: "References\iedriver64.exe";    DestDir: "{app}"; Flags: ignoreversion; Components: pkg_ie;  Check: IsWin64;
Source: "References\edgedriver.exe";    DestDir: "{app}"; Flags: ignoreversion; Components: pkg_edg;

;Firefox extensions
Source: "FirefoxAddons\bin\extensions.xpi"; DestDir: "{app}"; Flags: ignoreversion; Components: pkg_ide;

;examples
Source: "Scripts\*.*" ;               DestDir: "{app}\Scripts";             Flags: ignoreversion overwritereadonly; Attribs:readonly; Components: pkg_core;
Source: "Templates\*.vbs" ;           DestDir: "{app}\Templates";           Flags: ignoreversion overwritereadonly; Attribs:readonly; Components: pkg_doc;
Source: "Templates\Xlbin\*.xlt";      DestDir: "{app}\Templates";           Flags: ignoreversion overwritereadonly; Attribs:readonly; Components: pkg_doc; Check: HasOldExcel
Source: "Templates\*.xltm" ;          DestDir: "{app}\Templates";           Flags: ignoreversion overwritereadonly; Attribs:readonly; Components: pkg_doc; Check: HasNewExcel
Source: "Templates\*.au3" ;           DestDir: "{app}\Templates";           Flags: ignoreversion overwritereadonly; Attribs:readonly; Components: pkg_doc; Check: HasAutoIt
Source: "Examples\VBScript\*.vbs";    DestDir: "{app}\Examples\VBScript";   Flags: ignoreversion overwritereadonly; Attribs:readonly; Components: pkg_doc;
Source: "Examples\JavaScript\*.js";   DestDir: "{app}\Examples\JavaScript"; Flags: ignoreversion overwritereadonly; Attribs:readonly; Components: pkg_doc;
Source: "Examples\Excel\Xlbin\*.xls"; DestDir: "{app}\Examples\Excel";      Flags: ignoreversion overwritereadonly; Attribs:readonly; Components: pkg_doc; Check: HasOldExcel
Source: "Examples\Excel\*.xlsm";      DestDir: "{app}\Examples\Excel";      Flags: ignoreversion overwritereadonly; Attribs:readonly; Components: pkg_doc; Check: HasNewExcel
Source: "Examples\AutoIt\*.au3";      DestDir: "{app}\Examples\AutoIt";     Flags: ignoreversion overwritereadonly; Attribs:readonly; Components: pkg_doc; Check: HasAutoIt

;copy config file
Source: "References\exe.config" ; DestDir: "{sys}";      DestName: "wscript.exe.config"; Flags: ignoreversion uninsneveruninstall; Check: HasPrivileges;
Source: "References\exe.config" ; DestDir: "{sys}";      DestName: "cscript.exe.config"; Flags: ignoreversion uninsneveruninstall; Check: HasPrivileges;
Source: "References\exe.config" ; DestDir: "{syswow64}"; DestName: "wscript.exe.config"; Flags: ignoreversion uninsneveruninstall; Check: IsWin64 And HasPrivileges;
Source: "References\exe.config" ; DestDir: "{syswow64}"; DestName: "cscript.exe.config"; Flags: ignoreversion uninsneveruninstall; Check: IsWin64 And HasPrivileges;
Source: "References\exe.config" ; DestDir: "{code:GetAppFolder|excel.exe}";    DestName: "EXCEL.EXE.CONFIG";    Flags: ignoreversion uninsneveruninstall; Check: HasPrivileges And HasApp('excel.exe');
Source: "References\exe.config" ; DestDir: "{code:GetAppFolder|winword.exe}";  DestName: "WINWORD.EXE.CONFIG";  Flags: ignoreversion uninsneveruninstall; Check: HasPrivileges And HasApp('winword.exe');
Source: "References\exe.config" ; DestDir: "{code:GetAppFolder|msaccess.exe}"; DestName: "MSACCESS.EXE.CONFIG"; Flags: ignoreversion uninsneveruninstall; Check: HasPrivileges And HasApp('msaccess.exe');
Source: "References\exe.config" ; DestDir: "{code:GetAppFolder|outlook.exe}";  DestName: "OUTLOOK.EXE.CONFIG";  Flags: ignoreversion uninsneveruninstall; Check: HasPrivileges And HasApp('outlook.exe');

[Icons]
Name: "{group}\Project Home Page";  Filename: {#AppURL};                      WorkingDir: "{app}";
Name: "{group}\Vbs Console";        Filename: "{app}\vbsc.exe";               Components: pkg_cons;
Name: "{group}\Examples";           Filename: "{app}\Examples";
Name: "{group}\Templates";          Filename: "{app}\Templates";
Name: "{group}\RunCleaner";         Filename: "{app}\Scripts\RunCleaner.vbs";
Name: "{group}\API documentation";  Filename: "{app}\Selenium.chm";
Name: "{group}\ChangeLog";          Filename: "{app}\CHANGELOG.txt";
Name: "{group}\Uninstall";          Filename: "{uninstallexe}"

Name: "{group}\Start Firefox";      Filename: "{app}\Scripts\StartFirefox.vbs";          Components: pkg_ff;
Name: "{group}\Start Chrome";       Filename: "{app}\Scripts\StartChrome.vbs";           Components: pkg_cr;
Name: "{group}\Start Chrome Debug"; Filename: "{app}\Scripts\StartChromeDebug.vbs";      Components: pkg_cr;
Name: "{group}\Start IE";           Filename: "{app}\Scripts\StartInternetExplorer.vbs"; Components: pkg_ie;
Name: "{group}\Start Opera";        Filename: "{app}\Scripts\StartOpera.vbs";            Components: pkg_op;
Name: "{group}\Start PhantomJS";    Filename: "{app}\Scripts\StartPhantomJS.vbs";        Components: pkg_pjs;

[Registry]

;Firefox plugins
;Root: HKCU; Subkey: "Software\Mozilla\Firefox\Extensions"; ValueName: "{{a6fd85ed-e919-4a43-a5af-8da18bda539f}"; ValueType: string; ValueData:"{app}\selenium-ide.xpi"; Flags: uninsdeletevalue; Components: pkg_ide;
;Root: HKCU; Subkey: "Software\Mozilla\Firefox\Extensions"; ValueName: "vbformatters@florent.breheret"; ValueType: string; ValueData:"{app}\vbformatters.xpi"; Flags: uninsdeletevalue; Components: pkg_ide;
;Root: HKCU; Subkey: "Software\Mozilla\Firefox\Extensions"; ValueName: "implicit-wait@florent.breheret"; ValueType: string; ValueData:"{app}\implicit-wait.xpi"; Flags: uninsdeletevalue; Components: pkg_ide;

;IE tweaks: Force the tabs to run in the same process as the manager process
;Root: HKCU; Subkey: "Software\Microsoft\Internet Explorer\Main"; ValueName: "TabProcGrowth"; ValueType: dword; ValueData: 0; Flags: uninsdeletevalue; Components: pkg_ie;

;IE tweaks: Allow file navigation
Root: HKCU; Subkey: "Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_LOCALMACHINE_LOCKDOWN"; ValueName: "iexplore.exe"; ValueType: dword; ValueData: 0; Components: pkg_ie;

;IE tweaks: Maintain a connection to the instance (for IE11)
Root: HKCU; Subkey: "SOFTWARE\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_BFCACHE"; ValueName: "iexplore.exe"; ValueType: dword; ValueData: 0; Components: pkg_ie;

;IE tweaks: Restore default zoom level
Root: HKCU; Subkey: "Software\Microsoft\Internet Explorer\Zoom"; ValueName: "ZoomFactor"; Flags: dontcreatekey deletevalue; Components: pkg_ie;
Root: HKCU; Subkey: "Software\Microsoft\Internet Explorer\Zoom"; ValueName: "ResetTextSizeOnStartup"; ValueType: dword; ValueData: 1       ; Components: pkg_ie;
Root: HKCU; Subkey: "Software\Microsoft\Internet Explorer\Zoom"; ValueName: "ResetZoomOnStartup";     ValueType: dword; ValueData: 1       ; Components: pkg_ie;
Root: HKCU; Subkey: "Software\Microsoft\Internet Explorer\Zoom"; ValueName: "ResetZoomOnStartup2";    ValueType: dword; ValueData: 1       ; Components: pkg_ie;

;IE tweaks: Disable enhanced protected mode
Root: HKCU; Subkey: "Software\Microsoft\Internet Explorer\Main"; ValueName: "Isolation";      Flags: dontcreatekey deletevalue; Components: pkg_ie;
Root: HKCU; Subkey: "Software\Microsoft\Internet Explorer\Main"; ValueName: "Isolation64Bit"; Flags: dontcreatekey deletevalue; Components: pkg_ie;

;IE tweaks: Disable autocomplete
Root: HKCU; Subkey: "Software\Microsoft\Windows\CurrentVersion\Explorer\AutoComplete"; ValueName: "AutoSuggest"; ValueType: string; ValueData: "no"; Components: pkg_ie;
Root: HKCU; Subkey: "Software\Microsoft\Internet Explorer\Main"; ValueName: "Use FormSuggest";       ValueType: string; ValueData: "no"; Components: pkg_ie;
Root: HKCU; Subkey: "Software\Microsoft\Internet Explorer\Main"; ValueName: "FormSuggest Passwords"; ValueType: string; ValueData: "no"; Components: pkg_ie;
Root: HKCU; Subkey: "Software\Microsoft\Internet Explorer\Main"; ValueName: "FormSuggest PW Ask";    ValueType: string; ValueData: "no"; Components: pkg_ie;

;IE tweaks: Disable warn
Root: HKCU; Subkey: "Software\Microsoft\Windows\CurrentVersion\Internet Settings"; ValueName: "WarnonBadCertRecving"; ValueType: dword; ValueData: 0; Components: pkg_ie;
Root: HKCU; Subkey: "Software\Microsoft\Windows\CurrentVersion\Internet Settings"; ValueName: "WarnonZoneCrossing";   ValueType: dword; ValueData: 0; Components: pkg_ie;
Root: HKCU; Subkey: "Software\Microsoft\Windows\CurrentVersion\Internet Settings"; ValueName: "WarnOnPostRedirect";   ValueType: dword; ValueData: 0; Components: pkg_ie;

;IE tweaks: Disable Check for publisher's certificate revocation
Root: HKCU; Subkey: "Software\Microsoft\Windows\CurrentVersion\WinTrust\Trust Providers\Software Publishing"; ValueName: "State"; ValueType: dword; ValueData: 146944; Components: pkg_ie;
;IE tweaks: Disable Check for server certificate revocation
Root: HKCU; Subkey: "Software\Microsoft\Windows\CurrentVersion\Internet Settings"; ValueName: "CertificateRevocation"; ValueType: dword; ValueData: 0; Components: pkg_ie;
;IE tweaks: Disable Check for signatures on downloaded programs
Root: HKCU; Subkey: "Software\Microsoft\Internet Explorer\Download"; ValueName: "CheckExeSignatures"; ValueType: string; ValueData: "no"; Components: pkg_ie;

;IE tweaks: Disable Check default browser
Root: HKCU; Subkey: "Software\Microsoft\Internet Explorer\Main"; ValueName: "Check_Associations"; ValueType: string; ValueData: "no"; Components: pkg_ie;

;IE tweaks: Disable accelerator button
Root: HKCU; Subkey: "Software\Microsoft\Internet Explorer\Activities"; ValueName: "NoActivities"; ValueType: dword; ValueData: 1; Components: pkg_ie;

;IE tweaks: Set the same protected mode for all zones  Disable=3 Enable=0
Root: HKCU; Subkey: "Software\Microsoft\Internet Explorer\Main"; ValueName: "NoProtectedModeBanner"; ValueType: dword; ValueData: 1; Components: pkg_ie;
Root: HKCU; Subkey: "Software\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\0"; ValueName: "2500"; ValueType: dword; ValueData: 3; Components: pkg_ie;
Root: HKCU; Subkey: "Software\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\1"; ValueName: "2500"; ValueType: dword; ValueData: 3; Components: pkg_ie;
Root: HKCU; Subkey: "Software\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\2"; ValueName: "2500"; ValueType: dword; ValueData: 3; Components: pkg_ie;
Root: HKCU; Subkey: "Software\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3"; ValueName: "2500"; ValueType: dword; ValueData: 3; Components: pkg_ie;
Root: HKCU; Subkey: "Software\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4"; ValueName: "2500"; ValueType: dword; ValueData: 3; Components: pkg_ie;

;IE tweaks: Enable all cookies
Root: HKCU; Subkey: "Software\Microsoft\Windows\CurrentVersion\Internet Settings";         ValueName: "PrivacyAdvanced"; ValueType: dword; ValueData: 1; Components: pkg_ie;
Root: HKCU; Subkey: "Software\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3"; ValueName: "1A10";            ValueType: dword; ValueData: 1; Components: pkg_ie;

;IE tweak: Allow HTTP Basic Authentication in url
Root: HKCU; Subkey: "Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_HTTP_USERNAME_PASSWORD_DISABLE"; ValueName: "iexplore.exe"; ValueType: dword; ValueData: 0; Components: pkg_ie;

;IE tweak: Turn off popup blocker
Root: HKCU; Subkey: "Software\Microsoft\Internet Explorer\New Windows"; ValueName: "PopupMgr"; ValueType: dword; ValueData: 0; Components: pkg_ie;

;IE tweak: Delete browsing history on exit
Root: HKCU; Subkey: "Software\Microsoft\Internet Explorer\Privacy"; ValueName: "ClearBrowsingHistoryOnExit"; ValueType: dword; ValueData: 1; Components: pkg_ie;

;IE tweak: Disable cache
Root: HKCU; Subkey: "Software\Microsoft\Windows\CurrentVersion\Internet Settings\CACHE";             ValueName: "Persistent";  ValueType: dword; ValueData: 0;    Components: pkg_ie;
Root: HKCU; Subkey: "Software\Microsoft\Windows\CurrentVersion\Internet Settings";                   ValueName: "SyncMode5";   ValueType: dword; ValueData: 3;    Components: pkg_ie;
Root: HKCU; Subkey: "Software\Microsoft\Windows\CurrentVersion\Internet Settings\Url History";       ValueName: "DaysToKeep";  ValueType: dword; ValueData: 0;    Components: pkg_ie;
Root: HKCU; Subkey: "Software\Microsoft\Windows\CurrentVersion\Internet Settings\5.0\Cache\Content"; ValueName: "CacheLimit";  ValueType: dword; ValueData: 2000; Components: pkg_ie;
Root: HKCU; Subkey: "Software\Microsoft\Windows\CurrentVersion\Internet Settings\Cache\Content";     ValueName: "CacheLimit";  ValueType: dword; ValueData: 2000; Components: pkg_ie;

;File association for the console
Root: HKCU; Subkey: "Software\Microsoft\Windows\CurrentVersion\App Paths\vbsc.exe"; ValueType: string; ValueData: "{app}\vbsc.exe"; Flags: deletekey uninsdeletekey; Components: pkg_cons;

Root: HKCU; Subkey: "Software\Classes\VBSFile\Shell\Debug"; ValueType: string; ValueData: "Debug"; Flags: deletekey uninsdeletekey;
Root: HKCU; Subkey: "Software\Classes\VBSFile\Shell\Debug\Command"; ValueType: expandsz; ValueData: """%SystemRoot%\System32\wscript.exe"" //D //X ""%1"" %*"; Components: pkg_cons;

Root: HKCU; Subkey: "Software\Classes\VBSFile\shell\runas"; ValueType: string; ValueName: "HasLUAShield"; ValueData: ""; Flags: deletekey uninsdeletekey;
Root: HKCU; Subkey: "Software\Classes\VBSFile\shell\runas\Command"; ValueType: expandsz; ValueData: """%SystemRoot%\System32\wscript.exe"" ""%1"" %*";

Root: HKCU; Subkey: "Software\Classes\VBSFile\Shell\RunExt"; ValueType: string; ValueData: "Run VBScript"; Flags: deletekey uninsdeletekey; Components: pkg_cons;
Root: HKCU; Subkey: "Software\Classes\VBSFile\Shell\RunExt\Command"; ValueType: string; ValueData: """{app}\vbsc.exe"" -i ""%1"" %*"; Components: pkg_cons;

Root: HKCU; Subkey: "Software\Classes\Directory\shell\RunExt"; ValueType: string; ValueData: "Run VBScripts"; Flags: deletekey uninsdeletekey; Components: pkg_cons;
Root: HKCU; Subkey: "Software\Classes\Directory\shell\RunExt\Command"; ValueType: string; ValueData: """{app}\vbsc.exe"" -i ""%1\*.vbs"""; Components: pkg_cons;

;Add excel trusted location for templates and examples
Root: HKCU; Subkey: "Software\Microsoft\Office\{code:GetOfficeVersion|Excel}.0\Excel\Security\Trusted Locations\Selenium1"; ValueName: "Path"; ValueType: String; ValueData: "{app}\Templates"; Flags: uninsdeletekey; Check: HasExcel;
Root: HKCU; Subkey: "Software\Microsoft\Office\{code:GetOfficeVersion|Excel}.0\Excel\Security\Trusted Locations\Selenium2"; ValueName: "Path"; ValueType: String; ValueData: "{app}\Examples";  Flags: uninsdeletekey; Check: HasExcel;
Root: HKCU; Subkey: "Software\Microsoft\Office\{code:GetOfficeVersion|Word}.0\Word\Security\Trusted Locations\Selenium1";   ValueName: "Path"; ValueType: String; ValueData: "{app}\Templates"; Flags: uninsdeletekey; Check: HasWord;
Root: HKCU; Subkey: "Software\Microsoft\Office\{code:GetOfficeVersion|Word}.0\Word\Security\Trusted Locations\Selenium2";   ValueName: "Path"; ValueType: String; ValueData: "{app}\Examples";  Flags: uninsdeletekey; Check: HasWord;

;Enable WScript host in case it's been disabled
Root: HKCU; Subkey: "Software\Microsoft\Windows Script Host\Settings"; ValueName: "Enabled"; ValueType: dword; ValueData: 1;

[Run]
;Filename: "{app}\RegNet.exe"; Parameters: "-r"; WorkingDir: {app}; Flags: waituntilterminated runascurrentuser runhidden; StatusMsg: "Register for COM interoperability";
Filename: "{code:GetAppPath|firefox.exe}"; Parameters: "-url ""{app}\extensions.xpi"""; WorkingDir: {app}; Flags: shellexec postinstall skipifsilent runascurrentuser; Components: pkg_ide; Check: HasFirefox; Description: "Install the Selenium IDE Addon for Firefox";

[UninstallRun]
;Filename: "{app}\RegNet.exe"; Parameters: "-u"; WorkingDir: {app}; Flags: waituntilterminated runascurrentuser runhidden; StatusMsg: "Unregister for COM interoperability";

[InstallDelete]
Type: filesandordirs; Name: "{localappdata}\Temp\Selenium"

[UninstallDelete]
Type: filesandordirs; Name: "{app}"
Type: filesandordirs; Name: "{localappdata}\Temp\Selenium"

[Code]
var
  ALL_USERS : Boolean;
  HK : Integer;
  HK32 : Integer;

Function HasPrivileges(): Boolean;
  Begin
    Result := IsAdminLoggedOn Or IsPowerUserLoggedOn
  End;

Function GetRootDir(Param: String): String;
  Begin
    If ALL_USERS Then
      Result := ExpandConstant('{pf}\{#AppFolder}')
    Else
      Result := ExpandConstant('{localappdata}\{#AppFolder}');
  End;

Procedure InitRootKeys();
  Begin
    If ALL_USERS Then Begin
      HK := HKLM;
      HK32 := HKLM32;
    End Else Begin
      HK := HKCU;
      HK32 := HKCU32;
    End
  End;

Function GetAppPath(app: String): string;
  Begin
    RegQueryStringValue(HKLM, 'SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\' + app, '', Result);
  End;

Function HasFirefox(): Boolean;
  Begin
    Result := FileExists(GetAppPath('firefox.exe'));
  End;

Function GetAppFolder(app: String): string;
  Begin
    Result := ExtractFileDir(GetAppPath(app));
  End;

Function HasApp(app: String): Boolean;
  Begin
    Result := GetAppPath(app) <> '';
  End;

Function GetOfficeVersion(app: String): String;
  Var ver: String; i: Integer;
  Begin
    If RegQueryStringValue(HKCR, app + '.Application\CurVer', '', ver) Then Begin
      For i := 1 To Length(ver) Do Begin
        If (ver[i] >= '0') And (ver[i] <= '9') Then
          Result := Result + ver[i];
      End;
    End;
  End;

Function HasExcel(): Boolean;
  Begin
    Result := RegKeyExists(HKCR, 'Excel.Application');
  End;

Function HasWord(): Boolean;
  Begin
    Result := RegKeyExists(HKCR, 'Word.Application');
  End;

Function HasNewExcel(): Boolean;
  Begin
    Result := RegKeyExists(HKCR, '.xlsm');
  End;

Function HasOldExcel(): Boolean;
  Begin
    Result := RegKeyExists(HKCR, '.xls') And Not RegKeyExists(HKCR, '.xlsm');
  End;

Function HasAutoIt(): Boolean;
  Begin
    Result := RegKeyExists(HKCR, '.au3');
  End;

Procedure _PatchOfficeFileVersion(Const subkey: String);
  Var name, value: String;
  Begin
    name := 'Maximum File Version Number';
    If RegQueryStringValue(HKLM, subkey, name, value) Then Begin
        RegWriteStringValue(HKLM, subkey, 'Maximum File Version', value);
        RegDeleteValue(HKLM, subkey, name);
    End
  End;

Procedure PatchOfficeFileVersion();
  Begin
    If Not HasPrivileges() Then Exit;
    //Excel 11
    _PatchOfficeFileVersion('SOFTWARE\Microsoft\.NETFramework\Policy\AppPatch\v4.0.30319.00000\excel.exe\{2CCAA9FE-6884-4AF2-99DD-5217B94115DF}');
    _PatchOfficeFileVersion('SOFTWARE\Microsoft\.NETFramework\Policy\AppPatch\v2.0.50727.00000\excel.exe\{2CCAA9FE-6884-4AF2-99DD-5217B94115DF}');
    //Word 11
    _PatchOfficeFileVersion('SOFTWARE\Microsoft\.NETFramework\Policy\AppPatch\v4.0.30319.00000\winword.exe\{2CCAA9FE-6884-4AF2-99DD-5217B94115DF}');
    _PatchOfficeFileVersion('SOFTWARE\Microsoft\.NETFramework\Policy\AppPatch\v2.0.50727.00000\winword.exe\{2CCAA9FE-6884-4AF2-99DD-5217B94115DF}');
  End;

Procedure AssertFrameworkPresent(Const version: String);
  Begin
    If Not RegKeyExists(HKLM,'SOFTWARE\Microsoft\NET Framework Setup\NDP\v' + version) Then
        RaiseException(ExpandConstant('{cm:MsgNETFrameworkNotInstalled}'));
  End;

Procedure AssertFilePresent(Const path: String);
  Begin
      If Not FileExists(path) Then
          RaiseException(ExpandConstant('{cm:MsgFileNotFound,' + path +'}'));
  End;

Function UninstallPrevious(const appid: String): Boolean;
  Var key, name, out_cmd: String; retcode: Integer;
  Begin
    key := 'SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\' + ExpandConstant(appid) + '_is1';
    name := 'UninstallString';
    If Not RegQueryStringValue(HKLM, key, name, out_cmd) Then
      If Not RegQueryStringValue(HKLM32, key, name, out_cmd) Then
        If Not RegQueryStringValue(HKCU, key, name, out_cmd) Then
          RegQueryStringValue(HKCU32, key, name, out_cmd);
    If out_cmd <> '' Then
        Exec('>', out_cmd + ' /SILENT /NORESTART /SUPPRESSMSGBOXES', '', SW_SHOW, ewWaitUntilTerminated, retcode);
    Result := retcode = 0;
  End;

Function BoolToStr(const value: Boolean): String;
  Begin
    If value Then Result := '1' Else Result := '0';
  End;

//---------------------------------------------------------------------------------------
// Registration
//---------------------------------------------------------------------------------------

type
  TNetLib = record
    Guid: String;
    FullName: String;
    Description: String;
    TypeVersion: String;
    Directory: String;
    PathDll: String;
    PathTlb32: String;
    PathTlb64: String;
    Runtime: String;
  end;

Procedure RegString(Const root: Integer; Const subkey, name, value: String);
  Begin
      //Log('REG [' + subkey + '] "' + name + '"="' + value + '"');
      If Not RegWriteStringValue(root, subkey, name, value) Then
         RaiseException(ExpandConstant('{cm:MsgRegistryWriteFailure}'));
  End;

// Interface registration (32/64bits Independent) :
//
// HKCU\Software\Classes\Interface\{ interface guid }
//   ""=" interface name "
//   \ProxyStubClsid32
//     ""=" interface short name "
//   \TypeLib
//     ""="{ assembly guid }"
//   \Version
//     ""=" assembly type version "
//
Procedure RegInterface_(Const lib : TNetLib; Const root: Integer; Const guid, typename, proxyStub: String);
  Var key: String;
  Begin
    key := 'Software\Classes\Interface\' + guid;
    RegDeleteKeyIncludingSubkeys(root, key);
    If Not IsUninstaller Then Begin
      RegString(root, key                        , ''         , typename         );
      RegString(root, key + '\ProxyStubClsid32'  , ''         , proxyStub        );
      RegString(root, key + '\TypeLib'           , ''         , lib.Guid         );
      RegString(root, key + '\TypeLib'           , 'Version'  , lib.TypeVersion  );
    End
  End;

Procedure RegInterface(Const lib : TNetLib; Const guid, name, proxystub: String);
  Begin
    RegInterface_(lib, HK, guid, name, proxystub);
    If IsWin64 Then
      RegInterface_(lib, HK32, guid, name, proxystub);
  End;

// Enumeration registration (32/64bits Shared) :
//
// HKCU\Software\Classes\Record\{ record guid }]
//   ""="mscoree.dll"
//   "Class"="Selenium.Structures.Point"
//   "Assembly"="Selenium, Version=2.0.1.2, Culture=neutral, PublicKeyToken=null"
//   "RuntimeVersion"="v2.0.50727"
//   "CodeBase"="C:\...\SeleniumBasic\Selenium.dll"
//
Procedure RegRecord(Const lib : TNetLib; Const guid, typename: String);
  Var key: String;
  Begin
    key := 'Software\Classes\Record\' + guid;
    RegDeleteKeyIncludingSubkeys(HK, key);
    If Not IsUninstaller Then Begin
      RegString(HK, key, 'Class'           , typename     );
      RegString(HK, key, 'Assembly'        , lib.FullName );
      RegString(HK, key, 'RuntimeVersion'  , lib.Runtime  );
      RegString(HK, key, 'CodeBase'        , lib.PathDll  );
    End
  End;

// CLSID registration (32/64bits Independent) :
//
// Root\Software\Classes\CLSID\{ class guid }
//   ""="Selenium.WebDriver"
//   \InprocServer32
//     ""="C:\Windows\System32\mscoree.dll"
//     "Class"="Selenium.WebDriver"
//     "Assembly"="Selenium, Version=2.0.1.2, Culture=neutral, PublicKeyToken=null"
//     "RuntimeVersion"="v2.0.50727"
//     "CodeBase"="C:\...\SeleniumBasic\Selenium.dll"
//     "ThreadingModel"="Both"
//   \Implemented Categories\{62C8FE65-4EBB-45e7-B440-6E39B2CDBF29}
//     ""=""
//   \ProgId
//     ""="Selenium.WebDriver"
//   \VersionIndependentProgID
//     ""="Selenium.WebDriver"
//
Procedure RegClsid(Const lib : TNetLib; Const root: Integer; Const guid, progid, typename, sysdir: String);
  Var key, skey : String;
  Begin
    key := 'Software\Classes\CLSID\' + guid;
    RegDeleteKeyIncludingSubkeys(root, key);
    If Not IsUninstaller Then Begin
      RegString(root, key, '', typename);

      skey := key + '\InprocServer32';
      RegString(root, skey, ''               , ExpandConstant(sysdir) + '\mscoree.dll' );
      RegString(root, skey, 'Class'          , typename     );
      RegString(root, skey, 'Assembly'       , lib.FullName );
      RegString(root, skey, 'RuntimeVersion' , lib.Runtime  );
      RegString(root, skey, 'CodeBase'       , lib.PathDll  );
      RegString(root, skey, 'ThreadingModel' , 'Both'       );

      skey := key + '\Implemented Categories\{62C8FE65-4EBB-45e7-B440-6E39B2CDBF29}';
      RegString(root, skey, '', '');

      skey := key + '\ProgId';
      RegString(root, skey, '', progid);

      skey := key + '\VersionIndependentProgID';
      RegString(root, skey, '', progid);
    End
  End;

// Class registration (32/64bits Shared) :
//
// HKCU\Software\Classes\[progid]
//   ""=[progid]
//   \CLSID
//     ""=[class guid]
//
Procedure RegClass(Const lib : TNetLib; Const guid, progid, typename: String);
  Var key, sysdir: String;
  Begin
    key := 'Software\Classes\' + progid;
    RegDeleteKeyIncludingSubkeys(HK, key);
    If Not IsUninstaller Then Begin
      RegString(HK, key, '', progid);
      RegString(HK, key + '\CLSID', '', guid);
    End

    RegClsid(lib, HK, guid, progid, typename, '{sys}');
    If IsWin64 Then
      RegClsid(lib, HK32, guid, progid, typename, '{syswow64}');
  End;

// TypeLib registration (32/64bits Shared) :
//
// HKCU\Software\Classes\TypeLib\[assembly guid]
//   \2.0
//     ""="App Type Library"
//     \0\win32
//       ""="C:\...\App32.tlb"
//     \0\win64
//       ""="C:\...\App64.tlb"
//     \FLAGS
//       ""="0"
//     \HELPDIR
//       ""="C:\..."
//
Procedure RegTypeLib(Const lib : TNetLib);
  Var key, skey : String;
  Begin
    key := 'Software\Classes\TypeLib\' + lib.Guid;
    RegDeleteKeyIncludingSubkeys(HK, key);
    If Not IsUninstaller Then Begin
      skey := key + '\' + lib.TypeVersion;
      RegString(HK, skey, '', lib.Description);
      RegString(HK, skey + '\FLAGS'   , ''  , '0'           );
      RegString(HK, skey + '\HELPDIR' , ''  , lib.Directory );
      RegString(HK, skey + '\0\win32' , ''  , lib.PathTlb32 );
      If IsWin64 Then
        RegString(HK, skey + '\0\win64', '' , lib.PathTlb64 );
    End
  End;

Procedure RegisterAssembly();
  Var lib : TNetLib;
  Begin
    { Includes the file generated by gen-registration.ipy }
    #include 'SeleniumBasicSetup.pas'
  End;

//---------------------------------------------------------------------------------------
// Workflow
//---------------------------------------------------------------------------------------

Function InitializeSetup() : Boolean;
  Begin
    ALL_USERS := HasPrivileges();
    InitRootKeys();
    //AssertFrameworkPresent('3.5');
    Result := True;
  End;

Function InitializeUninstall() : Boolean;
  var p : string;
  Begin
    ALL_USERS := GetPreviousData('AllUsers', '') = '1';
    InitRootKeys();
    Result := True;
  End;

Procedure RegisterPreviousData(PreviousDataKey: Integer);
  Begin
    SetPreviousData(PreviousDataKey, 'AllUsers', BoolToStr(ALL_USERS));
  End;

Procedure CurPageChanged(CurPageID: Integer);
  var lines : TStrings;
  Begin
    If CurPageID = wpReady Then Begin
      lines := Wizardform.ReadyMemo.Lines;
      If ALL_USERS Then
        lines.Insert(0, 'Install folder / All Users :')
      Else
        lines.Insert(0, 'Install folder / Current User :');

     lines.Insert(1, ExpandConstant('{app}'));
     lines.Insert(2, '');
    End;
  End;

Procedure CurStepChanged(CurStep: TSetupStep);
  Begin
    If CurStep = ssInstall Then Begin
      UninstallPrevious('SeleniumWrapper');
      UninstallPrevious('{#AppId}');
    End Else If CurStep = ssPostInstall Then Begin
      RegisterAssembly();
      PatchOfficeFileVersion();
    End;
  End;

Procedure CurUninstallStepChanged(CurUninstallStep: TUninstallStep);
  Begin
    If CurUninstallStep = usUninstall  Then Begin
      RegisterAssembly(); //Only deletes the main keys
    End;
  End;

#define ASSEMBLY_PATH ".\Selenium\bin\Release\Selenium.dll"
#define ASSEMBLY_VERSION GetFileVersion(ASSEMBLY_PATH)

#define AppName "Selenium"
#define AppID "{{0277FC34-FD1B-4616-BB19-1FDB7381B291}"
#define AppLongName "Selenium Basic"
#define AppPublisher "Florent BREHERET"
#define AppURL "https://github.com/florentbr/SeleniumBasic"
#define AppFolder "SeleniumBasic"
#define AppSetupFilename "SeleniumBasic-" + ASSEMBLY_VERSION

[Setup]

AppId={#AppID}
PrivilegesRequired=lowest
AppName={#AppLongName}
AppVersion={#ASSEMBLY_VERSION}
AppVerName={#AppLongName}
VersionInfoVersion={#ASSEMBLY_VERSION}
VersionInfoTextVersion={#ASSEMBLY_VERSION}
AppPublisher={#AppPublisher}
AppPublisherURL={#AppURL}
AppSupportURL={#AppURL}
AppUpdatesURL={#AppURL}
DisableDirPage=yes
DefaultDirName={code:GetRootDir}
UsePreviousAppDir=no
UsePreviousSetupType=yes
DefaultGroupName={#AppLongName}
DisableProgramGroupPage=yes
LicenseFile=.\LICENSE.txt
OutputDir="."
OutputBaseFilename={#AppSetupFilename}
;Compression=zip
Compression=lzma2
SolidCompression=yes
DirExistsWarning=no
ArchitecturesInstallIn64BitMode=x64

[Languages]
Name: "english"; MessagesFile: "compiler:Default.isl"

[CustomMessages]
MsgNETFrameworkNotInstalled=Microsoft .NET Framework 3.5 installation was Not detected.
MsgRegistryWriteFailure=Failed to register the library due to insufficient privileges.
MsgFileNotFound=File Not found: %1.
MsgCOMInvokeFailed=Installation failed. The installer was unable to call the registered library.

[Components]
Name: "pkg_core"; Description: ".Net core libraries";                         Types: full compact custom; Flags: fixed;
Name: "pkg_doc";  Description: "Templates and examples";                      Types: full compact custom;
Name: "pkg_cons"; Description: "Enhanced console runner for VBScript files";  Types: full compact custom;
Name: "pkg_ff";   Description: "WebDriver for Firefox";                       Types: full custom;
Name: "pkg_cr";   Description: "WebDriver for Chrome";                        Types: full custom;
Name: "pkg_op";   Description: "WebDriver for Opera";                         Types: full custom;
Name: "pkg_ie";   Description: "WebDriver for Internet Explorer";             Types: full custom;
Name: "pkg_edg";  Description: "WebDriver for Microsoft Edge";                Types: full custom;
Name: "pkg_pjs";  Description: "WebDriver for PhantomJS (headless browser)";  Types: full custom;
Name: "pkg_ide";  Description: "SeleniumIDE plugin for Firefox";              Types: full custom;

[Files]
Source: "Selenium\bin\Release\Selenium.dll";   DestDir: "{app}"; Flags: ignoreversion; Components: pkg_core;
Source: "Selenium\bin\Release\Selenium.pdb";   DestDir: "{app}"; Flags: ignoreversion; Components: pkg_core;
Source: "Selenium\bin\Release\Selenium32.tlb"; DestDir: "{app}"; Flags: ignoreversion; Components: pkg_core;
Source: "Selenium\bin\Release\Selenium64.tlb"; DestDir: "{app}"; Flags: ignoreversion; Components: pkg_core; Check: IsWin64;

Source: "Selenium\bin\Help\Selenium.chm"; DestDir: "{app}"; Flags: ignoreversion; Components: pkg_core;

Source: "LICENSE.txt";   DestDir: "{app}"; Flags: ignoreversion overwritereadonly ; Attribs:readonly;
Source: "CHANGELOG.txt"; DestDir: "{app}"; Flags: ignoreversion overwritereadonly ; Attribs:readonly;

Source: "VbsConsole\bin\Release\vbsc.exe"; DestDir: "{app}"; Flags: ignoreversion; Components: pkg_cons;

;drivers
Source: "References\firefoxdriver.xpi"; DestDir: "{app}"; Flags: ignoreversion; Components: pkg_ff;
Source: "References\chromedriver.exe";  DestDir: "{app}"; Flags: ignoreversion; Components: pkg_cr;
Source: "References\operadriver.exe";   DestDir: "{app}"; Flags: ignoreversion; Components: pkg_op;
Source: "References\phantomjs.exe";     DestDir: "{app}"; Flags: ignoreversion; Components: pkg_pjs;
Source: "References\iedriver.exe";      DestDir: "{app}"; Flags: ignoreversion; Components: pkg_ie;
;Source: "References\iedriver64.exe";    DestDir: "{app}"; Flags: ignoreversion; Components: pkg_ie;  Check: IsWin64;
Source: "References\edgedriver.exe";    DestDir: "{app}"; Flags: ignoreversion; Components: pkg_edg;

;Firefox extensions
Source: "FirefoxAddons\bin\extensions.xpi"; DestDir: "{app}"; Flags: ignoreversion; Components: pkg_ide;

;examples
Source: "Scripts\*.*" ;               DestDir: "{app}\Scripts";             Flags: ignoreversion overwritereadonly; Attribs:readonly; Components: pkg_core;
Source: "Templates\*.vbs" ;           DestDir: "{app}\Templates";           Flags: ignoreversion overwritereadonly; Attribs:readonly; Components: pkg_doc;
Source: "Templates\Xlbin\*.xlt";      DestDir: "{app}\Templates";           Flags: ignoreversion overwritereadonly; Attribs:readonly; Components: pkg_doc; Check: HasOldExcel
Source: "Templates\*.xltm" ;          DestDir: "{app}\Templates";           Flags: ignoreversion overwritereadonly; Attribs:readonly; Components: pkg_doc; Check: HasNewExcel
Source: "Templates\*.au3" ;           DestDir: "{app}\Templates";           Flags: ignoreversion overwritereadonly; Attribs:readonly; Components: pkg_doc; Check: HasAutoIt
Source: "Examples\VBScript\*.vbs";    DestDir: "{app}\Examples\VBScript";   Flags: ignoreversion overwritereadonly; Attribs:readonly; Components: pkg_doc;
Source: "Examples\JavaScript\*.js";   DestDir: "{app}\Examples\JavaScript"; Flags: ignoreversion overwritereadonly; Attribs:readonly; Components: pkg_doc;
Source: "Examples\Excel\Xlbin\*.xls"; DestDir: "{app}\Examples\Excel";      Flags: ignoreversion overwritereadonly; Attribs:readonly; Components: pkg_doc; Check: HasOldExcel
Source: "Examples\Excel\*.xlsm";      DestDir: "{app}\Examples\Excel";      Flags: ignoreversion overwritereadonly; Attribs:readonly; Components: pkg_doc; Check: HasNewExcel
Source: "Examples\AutoIt\*.au3";      DestDir: "{app}\Examples\AutoIt";     Flags: ignoreversion overwritereadonly; Attribs:readonly; Components: pkg_doc; Check: HasAutoIt

;copy config file
Source: "References\exe.config" ; DestDir: "{sys}";      DestName: "wscript.exe.config"; Flags: ignoreversion uninsneveruninstall; Check: HasPrivileges;
Source: "References\exe.config" ; DestDir: "{sys}";      DestName: "cscript.exe.config"; Flags: ignoreversion uninsneveruninstall; Check: HasPrivileges;
Source: "References\exe.config" ; DestDir: "{syswow64}"; DestName: "wscript.exe.config"; Flags: ignoreversion uninsneveruninstall; Check: IsWin64 And HasPrivileges;
Source: "References\exe.config" ; DestDir: "{syswow64}"; DestName: "cscript.exe.config"; Flags: ignoreversion uninsneveruninstall; Check: IsWin64 And HasPrivileges;
Source: "References\exe.config" ; DestDir: "{code:GetAppFolder|excel.exe}";    DestName: "EXCEL.EXE.CONFIG";    Flags: ignoreversion uninsneveruninstall; Check: HasPrivileges And HasApp('excel.exe');
Source: "References\exe.config" ; DestDir: "{code:GetAppFolder|winword.exe}";  DestName: "WINWORD.EXE.CONFIG";  Flags: ignoreversion uninsneveruninstall; Check: HasPrivileges And HasApp('winword.exe');
Source: "References\exe.config" ; DestDir: "{code:GetAppFolder|msaccess.exe}"; DestName: "MSACCESS.EXE.CONFIG"; Flags: ignoreversion uninsneveruninstall; Check: HasPrivileges And HasApp('msaccess.exe');
Source: "References\exe.config" ; DestDir: "{code:GetAppFolder|outlook.exe}";  DestName: "OUTLOOK.EXE.CONFIG";  Flags: ignoreversion uninsneveruninstall; Check: HasPrivileges And HasApp('outlook.exe');

[Icons]
Name: "{group}\Project Home Page";  Filename: {#AppURL};                      WorkingDir: "{app}";
Name: "{group}\Vbs Console";        Filename: "{app}\vbsc.exe";               Components: pkg_cons;
Name: "{group}\Examples";           Filename: "{app}\Examples";
Name: "{group}\Templates";          Filename: "{app}\Templates";
Name: "{group}\RunCleaner";         Filename: "{app}\Scripts\RunCleaner.vbs";
Name: "{group}\API documentation";  Filename: "{app}\Selenium.chm";
Name: "{group}\ChangeLog";          Filename: "{app}\CHANGELOG.txt";
Name: "{group}\Uninstall";          Filename: "{uninstallexe}"

Name: "{group}\Start Firefox";      Filename: "{app}\Scripts\StartFirefox.vbs";          Components: pkg_ff;
Name: "{group}\Start Chrome";       Filename: "{app}\Scripts\StartChrome.vbs";           Components: pkg_cr;
Name: "{group}\Start Chrome Debug"; Filename: "{app}\Scripts\StartChromeDebug.vbs";      Components: pkg_cr;
Name: "{group}\Start IE";           Filename: "{app}\Scripts\StartInternetExplorer.vbs"; Components: pkg_ie;
Name: "{group}\Start Opera";        Filename: "{app}\Scripts\StartOpera.vbs";            Components: pkg_op;
Name: "{group}\Start PhantomJS";    Filename: "{app}\Scripts\StartPhantomJS.vbs";        Components: pkg_pjs;

[Registry]

;Firefox plugins
;Root: HKCU; Subkey: "Software\Mozilla\Firefox\Extensions"; ValueName: "{{a6fd85ed-e919-4a43-a5af-8da18bda539f}"; ValueType: string; ValueData:"{app}\selenium-ide.xpi"; Flags: uninsdeletevalue; Components: pkg_ide;
;Root: HKCU; Subkey: "Software\Mozilla\Firefox\Extensions"; ValueName: "vbformatters@florent.breheret"; ValueType: string; ValueData:"{app}\vbformatters.xpi"; Flags: uninsdeletevalue; Components: pkg_ide;
;Root: HKCU; Subkey: "Software\Mozilla\Firefox\Extensions"; ValueName: "implicit-wait@florent.breheret"; ValueType: string; ValueData:"{app}\implicit-wait.xpi"; Flags: uninsdeletevalue; Components: pkg_ide;

;IE tweaks: Force the tabs to run in the same process as the manager process
;Root: HKCU; Subkey: "Software\Microsoft\Internet Explorer\Main"; ValueName: "TabProcGrowth"; ValueType: dword; ValueData: 0; Flags: uninsdeletevalue; Components: pkg_ie;

;IE tweaks: Maintain a connection to the instance (for IE11)
Root: HKCU; Subkey: "SOFTWARE\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_BFCACHE"; ValueName: "iexplore.exe"; ValueType: dword; ValueData: 0; Components: pkg_ie;

;IE tweaks: Restore default zoom level
Root: HKCU; Subkey: "Software\Microsoft\Internet Explorer\Zoom"; ValueName: "ZoomFactor"; Flags: dontcreatekey deletevalue; Components: pkg_ie;

;IE tweaks: Disable enhanced protected mode
Root: HKCU; Subkey: "Software\Microsoft\Internet Explorer\Main"; ValueName: "Isolation";      Flags: dontcreatekey deletevalue; Components: pkg_ie;
Root: HKCU; Subkey: "Software\Microsoft\Internet Explorer\Main"; ValueName: "Isolation64Bit"; Flags: dontcreatekey deletevalue; Components: pkg_ie;

;IE tweaks: Disable autocomplete
Root: HKCU; Subkey: "Software\Microsoft\Windows\CurrentVersion\Explorer\AutoComplete"; ValueName: "AutoSuggest"; ValueType: string; ValueData: "no"; Components: pkg_ie;
Root: HKCU; Subkey: "Software\Microsoft\Internet Explorer\Main"; ValueName: "Use FormSuggest";       ValueType: string; ValueData: "no"; Components: pkg_ie;
Root: HKCU; Subkey: "Software\Microsoft\Internet Explorer\Main"; ValueName: "FormSuggest Passwords"; ValueType: string; ValueData: "no"; Components: pkg_ie;
Root: HKCU; Subkey: "Software\Microsoft\Internet Explorer\Main"; ValueName: "FormSuggest PW Ask";    ValueType: string; ValueData: "no"; Components: pkg_ie;

;IE tweaks: Disable warn
Root: HKCU; Subkey: "Software\Microsoft\Windows\CurrentVersion\Internet Settings"; ValueName: "WarnonBadCertRecving"; ValueType: dword; ValueData: 0; Components: pkg_ie;
Root: HKCU; Subkey: "Software\Microsoft\Windows\CurrentVersion\Internet Settings"; ValueName: "WarnonZoneCrossing";   ValueType: dword; ValueData: 0; Components: pkg_ie;
Root: HKCU; Subkey: "Software\Microsoft\Windows\CurrentVersion\Internet Settings"; ValueName: "WarnOnPostRedirect";   ValueType: dword; ValueData: 0; Components: pkg_ie;

;IE tweaks: Disable Check for publisher's certificate revocation
Root: HKCU; Subkey: "Software\Microsoft\Windows\CurrentVersion\WinTrust\Trust Providers\Software Publishing"; ValueName: "State"; ValueType: dword; ValueData: 146944; Components: pkg_ie;
;IE tweaks: Disable Check for server certificate revocation
Root: HKCU; Subkey: "Software\Microsoft\Windows\CurrentVersion\Internet Settings"; ValueName: "CertificateRevocation"; ValueType: dword; ValueData: 0; Components: pkg_ie;
;IE tweaks: Disable Check for signatures on downloaded programs
Root: HKCU; Subkey: "Software\Microsoft\Internet Explorer\Download"; ValueName: "CheckExeSignatures"; ValueType: string; ValueData: "no"; Components: pkg_ie;

;IE tweaks: Disable Check default browser
Root: HKCU; Subkey: "Software\Microsoft\Internet Explorer\Main"; ValueName: "Check_Associations"; ValueType: string; ValueData: "no"; Components: pkg_ie;

;IE tweaks: Disable accelerator button
Root: HKCU; Subkey: "Software\Microsoft\Internet Explorer\Activities"; ValueName: "NoActivities"; ValueType: dword; ValueData: 1; Components: pkg_ie;

;IE tweaks: Set the same protected mode for all zones  Disable=3 Enable=0
Root: HKCU; Subkey: "Software\Microsoft\Internet Explorer\Main"; ValueName: "NoProtectedModeBanner"; ValueType: dword; ValueData: 1; Components: pkg_ie;
Root: HKCU; Subkey: "Software\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\0"; ValueName: "2500"; ValueType: dword; ValueData: 3; Components: pkg_ie;
Root: HKCU; Subkey: "Software\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\1"; ValueName: "2500"; ValueType: dword; ValueData: 3; Components: pkg_ie;
Root: HKCU; Subkey: "Software\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\2"; ValueName: "2500"; ValueType: dword; ValueData: 3; Components: pkg_ie;
Root: HKCU; Subkey: "Software\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3"; ValueName: "2500"; ValueType: dword; ValueData: 3; Components: pkg_ie;
Root: HKCU; Subkey: "Software\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4"; ValueName: "2500"; ValueType: dword; ValueData: 3; Components: pkg_ie;

;IE tweaks: Enable all cookies
Root: HKCU; Subkey: "Software\Microsoft\Windows\CurrentVersion\Internet Settings";         ValueName: "PrivacyAdvanced"; ValueType: dword; ValueData: 1; Components: pkg_ie;
Root: HKCU; Subkey: "Software\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3"; ValueName: "1A10";            ValueType: dword; ValueData: 1; Components: pkg_ie;

;IE tweak: Allow HTTP Basic Authentication in url
Root: HKCU; Subkey: "Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_HTTP_USERNAME_PASSWORD_DISABLE"; ValueName: "iexplore.exe"; ValueType: dword; ValueData: 0; Components: pkg_ie;

;IE tweak: Turn off popup blocker
Root: HKCU; Subkey: "Software\Microsoft\Internet Explorer\New Windows"; ValueName: "PopupMgr"; ValueType: dword; ValueData: 0; Components: pkg_ie;

;IE tweak: Delete browsing history on exit
Root: HKCU; Subkey: "Software\Microsoft\Internet Explorer\Privacy"; ValueName: "ClearBrowsingHistoryOnExit"; ValueType: dword; ValueData: 1; Components: pkg_ie;

;IE tweak: Disable cache
Root: HKCU; Subkey: "Software\Microsoft\Windows\CurrentVersion\Internet Settings\CACHE";             ValueName: "Persistent";  ValueType: dword; ValueData: 0;    Components: pkg_ie;
Root: HKCU; Subkey: "Software\Microsoft\Windows\CurrentVersion\Internet Settings";                   ValueName: "SyncMode5";   ValueType: dword; ValueData: 3;    Components: pkg_ie;
Root: HKCU; Subkey: "Software\Microsoft\Windows\CurrentVersion\Internet Settings\Url History";       ValueName: "DaysToKeep";  ValueType: dword; ValueData: 0;    Components: pkg_ie;
Root: HKCU; Subkey: "Software\Microsoft\Windows\CurrentVersion\Internet Settings\5.0\Cache\Content"; ValueName: "CacheLimit";  ValueType: dword; ValueData: 2000; Components: pkg_ie;
Root: HKCU; Subkey: "Software\Microsoft\Windows\CurrentVersion\Internet Settings\Cache\Content";     ValueName: "CacheLimit";  ValueType: dword; ValueData: 2000; Components: pkg_ie;

;File association for the console
Root: HKCU; Subkey: "Software\Microsoft\Windows\CurrentVersion\App Paths\vbsc.exe"; ValueType: string; ValueData: "{app}\vbsc.exe"; Flags: deletekey uninsdeletekey; Components: pkg_cons;

Root: HKCU; Subkey: "Software\Classes\VBSFile\Shell\Debug"; ValueType: string; ValueData: "Debug"; Flags: deletekey uninsdeletekey;
Root: HKCU; Subkey: "Software\Classes\VBSFile\Shell\Debug\Command"; ValueType: expandsz; ValueData: """%SystemRoot%\System32\wscript.exe"" //D //X ""%1"" %*"; Components: pkg_cons;

Root: HKCU; Subkey: "Software\Classes\VBSFile\shell\runas"; ValueType: string; ValueName: "HasLUAShield"; ValueData: ""; Flags: deletekey uninsdeletekey;
Root: HKCU; Subkey: "Software\Classes\VBSFile\shell\runas\Command"; ValueType: expandsz; ValueData: """%SystemRoot%\System32\wscript.exe"" ""%1"" %*";

Root: HKCU; Subkey: "Software\Classes\VBSFile\Shell\RunExt"; ValueType: string; ValueData: "Run VBScript"; Flags: deletekey uninsdeletekey; Components: pkg_cons;
Root: HKCU; Subkey: "Software\Classes\VBSFile\Shell\RunExt\Command"; ValueType: string; ValueData: """{app}\vbsc.exe"" -i ""%1"" %*"; Components: pkg_cons;

Root: HKCU; Subkey: "Software\Classes\Directory\shell\RunExt"; ValueType: string; ValueData: "Run VBScripts"; Flags: deletekey uninsdeletekey; Components: pkg_cons;
Root: HKCU; Subkey: "Software\Classes\Directory\shell\RunExt\Command"; ValueType: string; ValueData: """{app}\vbsc.exe"" -i ""%1\*.vbs"""; Components: pkg_cons;

;Add excel trusted location for templates and examples
Root: HKCU; Subkey: "Software\Microsoft\Office\{code:GetOfficeVersion|Excel}.0\Excel\Security\Trusted Locations\Selenium1"; ValueName: "Path"; ValueType: String; ValueData: "{app}\Templates"; Flags: uninsdeletekey; Check: HasExcel;
Root: HKCU; Subkey: "Software\Microsoft\Office\{code:GetOfficeVersion|Excel}.0\Excel\Security\Trusted Locations\Selenium2"; ValueName: "Path"; ValueType: String; ValueData: "{app}\Examples";  Flags: uninsdeletekey; Check: HasExcel;
Root: HKCU; Subkey: "Software\Microsoft\Office\{code:GetOfficeVersion|Word}.0\Word\Security\Trusted Locations\Selenium1";   ValueName: "Path"; ValueType: String; ValueData: "{app}\Templates"; Flags: uninsdeletekey; Check: HasWord;
Root: HKCU; Subkey: "Software\Microsoft\Office\{code:GetOfficeVersion|Word}.0\Word\Security\Trusted Locations\Selenium2";   ValueName: "Path"; ValueType: String; ValueData: "{app}\Examples";  Flags: uninsdeletekey; Check: HasWord;

;Enable WScript host in case it's been disabled
Root: HKCU; Subkey: "Software\Microsoft\Windows Script Host\Settings"; ValueName: "Enabled"; ValueType: dword; ValueData: 1;

[Run]
;Filename: "{app}\RegNet.exe"; Parameters: "-r"; WorkingDir: {app}; Flags: waituntilterminated runascurrentuser runhidden; StatusMsg: "Register for COM interoperability";
Filename: "{code:GetAppPath|firefox.exe}"; Parameters: "-url ""{app}\extensions.xpi"""; WorkingDir: {app}; Flags: shellexec postinstall skipifsilent runascurrentuser; Components: pkg_ide; Check: HasFirefox; Description: "Install the Selenium IDE Addon for Firefox";

[UninstallRun]
;Filename: "{app}\RegNet.exe"; Parameters: "-u"; WorkingDir: {app}; Flags: waituntilterminated runascurrentuser runhidden; StatusMsg: "Unregister for COM interoperability";

[InstallDelete]
Type: filesandordirs; Name: "{localappdata}\Temp\Selenium"

[UninstallDelete]
Type: filesandordirs; Name: "{app}"
Type: filesandordirs; Name: "{localappdata}\Temp\Selenium"

[Code]
var
  ALL_USERS : Boolean;
  HK : Integer;
  HK32 : Integer;

Function HasPrivileges(): Boolean;
  Begin
    Result := IsAdminLoggedOn Or IsPowerUserLoggedOn
  End;

Function GetRootDir(Param: String): String;
  Begin
    If ALL_USERS Then
      Result := ExpandConstant('{pf}\{#AppFolder}')
    Else
      Result := ExpandConstant('{localappdata}\{#AppFolder}');
  End;

Procedure InitRootKeys();
  Begin
    If ALL_USERS Then Begin
      HK := HKLM;
      HK32 := HKLM32;
    End Else Begin
      HK := HKCU;
      HK32 := HKCU32;
    End
  End;

Function GetAppPath(app: String): string;
  Begin
    RegQueryStringValue(HKLM, 'SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\' + app, '', Result);
  End;

Function HasFirefox(): Boolean;
  Begin
    Result := FileExists(GetAppPath('firefox.exe'));
  End;

Function GetAppFolder(app: String): string;
  Begin
    Result := ExtractFileDir(GetAppPath(app));
  End;

Function HasApp(app: String): Boolean;
  Begin
    Result := GetAppPath(app) <> '';
  End;

Function GetOfficeVersion(app: String): String;
  Var ver: String; i: Integer;
  Begin
    If RegQueryStringValue(HKCR, app + '.Application\CurVer', '', ver) Then Begin
      For i := 1 To Length(ver) Do Begin
        If (ver[i] >= '0') And (ver[i] <= '9') Then
          Result := Result + ver[i];
      End;
    End;
  End;

Function HasExcel(): Boolean;
  Begin
    Result := RegKeyExists(HKCR, 'Excel.Application');
  End;

Function HasWord(): Boolean;
  Begin
    Result := RegKeyExists(HKCR, 'Word.Application');
  End;

Function HasNewExcel(): Boolean;
  Begin
    Result := RegKeyExists(HKCR, '.xlsm');
  End;

Function HasOldExcel(): Boolean;
  Begin
    Result := RegKeyExists(HKCR, '.xls') And Not RegKeyExists(HKCR, '.xlsm');
  End;

Function HasAutoIt(): Boolean;
  Begin
    Result := RegKeyExists(HKCR, '.au3');
  End;

Procedure _PatchOfficeFileVersion(Const subkey: String);
  Var name, value: String;
  Begin
    name := 'Maximum File Version Number';
    If RegQueryStringValue(HKLM, subkey, name, value) Then Begin
        RegWriteStringValue(HKLM, subkey, 'Maximum File Version', value);
        RegDeleteValue(HKLM, subkey, name);
    End
  End;

Procedure PatchOfficeFileVersion();
  Begin
    If Not HasPrivileges() Then Exit;
    //Excel 11
    _PatchOfficeFileVersion('SOFTWARE\Microsoft\.NETFramework\Policy\AppPatch\v4.0.30319.00000\excel.exe\{2CCAA9FE-6884-4AF2-99DD-5217B94115DF}');
    _PatchOfficeFileVersion('SOFTWARE\Microsoft\.NETFramework\Policy\AppPatch\v2.0.50727.00000\excel.exe\{2CCAA9FE-6884-4AF2-99DD-5217B94115DF}');
    //Word 11
    _PatchOfficeFileVersion('SOFTWARE\Microsoft\.NETFramework\Policy\AppPatch\v4.0.30319.00000\winword.exe\{2CCAA9FE-6884-4AF2-99DD-5217B94115DF}');
    _PatchOfficeFileVersion('SOFTWARE\Microsoft\.NETFramework\Policy\AppPatch\v2.0.50727.00000\winword.exe\{2CCAA9FE-6884-4AF2-99DD-5217B94115DF}');
  End;

Procedure AssertFrameworkPresent(Const version: String);
  Begin
    If Not RegKeyExists(HKLM,'SOFTWARE\Microsoft\NET Framework Setup\NDP\v' + version) Then
        RaiseException(ExpandConstant('{cm:MsgNETFrameworkNotInstalled}'));
  End;

Procedure AssertFilePresent(Const path: String);
  Begin
      If Not FileExists(path) Then
          RaiseException(ExpandConstant('{cm:MsgFileNotFound,' + path +'}'));
  End;

Function UninstallPrevious(const appid: String): Boolean;
  Var key, name, out_cmd: String; retcode: Integer;
  Begin
    key := 'SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\' + ExpandConstant(appid) + '_is1';
    name := 'UninstallString';
    If Not RegQueryStringValue(HKLM, key, name, out_cmd) Then
      If Not RegQueryStringValue(HKLM32, key, name, out_cmd) Then
        If Not RegQueryStringValue(HKCU, key, name, out_cmd) Then
          RegQueryStringValue(HKCU32, key, name, out_cmd);
    If out_cmd <> '' Then
        Exec('>', out_cmd + ' /SILENT /NORESTART /SUPPRESSMSGBOXES', '', SW_SHOW, ewWaitUntilTerminated, retcode);
    Result := retcode = 0;
  End;

Function BoolToStr(const value: Boolean): String;
  Begin
    If value Then Result := '1' Else Result := '0';
  End;

//---------------------------------------------------------------------------------------
// Registration
//---------------------------------------------------------------------------------------

type
  TNetLib = record
    Guid: String;
    FullName: String;
    Description: String;
    TypeVersion: String;
    Directory: String;
    PathDll: String;
    PathTlb32: String;
    PathTlb64: String;
    Runtime: String;
  end;

Procedure RegString(Const root: Integer; Const subkey, name, value: String);
  Begin
      //Log('REG [' + subkey + '] "' + name + '"="' + value + '"');
      If Not RegWriteStringValue(root, subkey, name, value) Then
         RaiseException(ExpandConstant('{cm:MsgRegistryWriteFailure}'));
  End;

// Interface registration (32/64bits Independent) :
//
// HKCU\Software\Classes\Interface\{ interface guid }
//   ""=" interface name "
//   \ProxyStubClsid32
//     ""=" interface short name "
//   \TypeLib
//     ""="{ assembly guid }"
//   \Version
//     ""=" assembly type version "
//
Procedure RegInterface_(Const lib : TNetLib; Const root: Integer; Const guid, typename, proxyStub: String);
  Var key: String;
  Begin
    key := 'Software\Classes\Interface\' + guid;
    RegDeleteKeyIncludingSubkeys(root, key);
    If Not IsUninstaller Then Begin
      RegString(root, key                        , ''         , typename         );
      RegString(root, key + '\ProxyStubClsid32'  , ''         , proxyStub        );
      RegString(root, key + '\TypeLib'           , ''         , lib.Guid         );
      RegString(root, key + '\TypeLib'           , 'Version'  , lib.TypeVersion  );
    End
  End;

Procedure RegInterface(Const lib : TNetLib; Const guid, name, proxystub: String);
  Begin
    RegInterface_(lib, HK, guid, name, proxystub);
    If IsWin64 Then
      RegInterface_(lib, HK32, guid, name, proxystub);
  End;

// Enumeration registration (32/64bits Shared) :
//
// HKCU\Software\Classes\Record\{ record guid }]
//   ""="mscoree.dll"
//   "Class"="Selenium.Structures.Point"
//   "Assembly"="Selenium, Version=2.0.1.2, Culture=neutral, PublicKeyToken=null"
//   "RuntimeVersion"="v2.0.50727"
//   "CodeBase"="C:\...\SeleniumBasic\Selenium.dll"
//
Procedure RegRecord(Const lib : TNetLib; Const guid, typename: String);
  Var key: String;
  Begin
    key := 'Software\Classes\Record\' + guid;
    RegDeleteKeyIncludingSubkeys(HK, key);
    If Not IsUninstaller Then Begin
      RegString(HK, key, 'Class'           , typename     );
      RegString(HK, key, 'Assembly'        , lib.FullName );
      RegString(HK, key, 'RuntimeVersion'  , lib.Runtime  );
      RegString(HK, key, 'CodeBase'        , lib.PathDll  );
    End
  End;

// CLSID registration (32/64bits Independent) :
//
// Root\Software\Classes\CLSID\{ class guid }
//   ""="Selenium.WebDriver"
//   \InprocServer32
//     ""="C:\Windows\System32\mscoree.dll"
//     "Class"="Selenium.WebDriver"
//     "Assembly"="Selenium, Version=2.0.1.2, Culture=neutral, PublicKeyToken=null"
//     "RuntimeVersion"="v2.0.50727"
//     "CodeBase"="C:\...\SeleniumBasic\Selenium.dll"
//     "ThreadingModel"="Both"
//   \Implemented Categories\{62C8FE65-4EBB-45e7-B440-6E39B2CDBF29}
//     ""=""
//   \ProgId
//     ""="Selenium.WebDriver"
//   \VersionIndependentProgID
//     ""="Selenium.WebDriver"
//
Procedure RegClsid(Const lib : TNetLib; Const root: Integer; Const guid, progid, typename, sysdir: String);
  Var key, skey : String;
  Begin
    key := 'Software\Classes\CLSID\' + guid;
    RegDeleteKeyIncludingSubkeys(root, key);
    If Not IsUninstaller Then Begin
      RegString(root, key, '', typename);

      skey := key + '\InprocServer32';
      RegString(root, skey, ''               , ExpandConstant(sysdir) + '\mscoree.dll' );
      RegString(root, skey, 'Class'          , typename     );
      RegString(root, skey, 'Assembly'       , lib.FullName );
      RegString(root, skey, 'RuntimeVersion' , lib.Runtime  );
      RegString(root, skey, 'CodeBase'       , lib.PathDll  );
      RegString(root, skey, 'ThreadingModel' , 'Both'       );

      skey := key + '\Implemented Categories\{62C8FE65-4EBB-45e7-B440-6E39B2CDBF29}';
      RegString(root, skey, '', '');

      skey := key + '\ProgId';
      RegString(root, skey, '', progid);

      skey := key + '\VersionIndependentProgID';
      RegString(root, skey, '', progid);
    End
  End;

// Class registration (32/64bits Shared) :
//
// HKCU\Software\Classes\[progid]
//   ""=[progid]
//   \CLSID
//     ""=[class guid]
//
Procedure RegClass(Const lib : TNetLib; Const guid, progid, typename: String);
  Var key, sysdir: String;
  Begin
    key := 'Software\Classes\' + progid;
    RegDeleteKeyIncludingSubkeys(HK, key);
    If Not IsUninstaller Then Begin
      RegString(HK, key, '', progid);
      RegString(HK, key + '\CLSID', '', guid);
    End

    RegClsid(lib, HK, guid, progid, typename, '{sys}');
    If IsWin64 Then
      RegClsid(lib, HK32, guid, progid, typename, '{syswow64}');
  End;

// TypeLib registration (32/64bits Shared) :
//
// HKCU\Software\Classes\TypeLib\[assembly guid]
//   \2.0
//     ""="App Type Library"
//     \0\win32
//       ""="C:\...\App32.tlb"
//     \0\win64
//       ""="C:\...\App64.tlb"
//     \FLAGS
//       ""="0"
//     \HELPDIR
//       ""="C:\..."
//
Procedure RegTypeLib(Const lib : TNetLib);
  Var key, skey : String;
  Begin
    key := 'Software\Classes\TypeLib\' + lib.Guid;
    RegDeleteKeyIncludingSubkeys(HK, key);
    If Not IsUninstaller Then Begin
      skey := key + '\' + lib.TypeVersion;
      RegString(HK, skey, '', lib.Description);
      RegString(HK, skey + '\FLAGS'   , ''  , '0'           );
      RegString(HK, skey + '\HELPDIR' , ''  , lib.Directory );
      RegString(HK, skey + '\0\win32' , ''  , lib.PathTlb32 );
      If IsWin64 Then
        RegString(HK, skey + '\0\win64', '' , lib.PathTlb64 );
    End
  End;

Procedure RegisterAssembly();
  Var lib : TNetLib;
  Begin
    { Includes the file generated by gen-registration.ipy }
    #include 'SeleniumBasicSetup.pas'
  End;

//---------------------------------------------------------------------------------------
// Workflow
//---------------------------------------------------------------------------------------

Function InitializeSetup() : Boolean;
  Begin
    ALL_USERS := HasPrivileges();
    InitRootKeys();
    //AssertFrameworkPresent('3.5');
    Result := True;
  End;

Function InitializeUninstall() : Boolean;
  var p : string;
  Begin
    ALL_USERS := GetPreviousData('AllUsers', '') = '1';
    InitRootKeys();
    Result := True;
  End;

Procedure RegisterPreviousData(PreviousDataKey: Integer);
  Begin
    SetPreviousData(PreviousDataKey, 'AllUsers', BoolToStr(ALL_USERS));
  End;

Procedure CurPageChanged(CurPageID: Integer);
  var lines : TStrings;
  Begin
    If CurPageID = wpReady Then Begin
      lines := Wizardform.ReadyMemo.Lines;
      If ALL_USERS Then
        lines.Insert(0, 'Install folder / All Users :')
      Else
        lines.Insert(0, 'Install folder / Current User :');

     lines.Insert(1, ExpandConstant('{app}'));
     lines.Insert(2, '');
    End;
  End;

Procedure CurStepChanged(CurStep: TSetupStep);
  Begin
    If CurStep = ssInstall Then Begin
      UninstallPrevious('SeleniumWrapper');
      UninstallPrevious('{#AppId}');
    End Else If CurStep = ssPostInstall Then Begin
      RegisterAssembly();
      PatchOfficeFileVersion();
    End;
  End;

Procedure CurUninstallStepChanged(CurUninstallStep: TUninstallStep);
  Begin
    If CurUninstallStep = usUninstall  Then Begin
      RegisterAssembly(); //Only deletes the main keys
    End;
  End;