;!verbose 3

!ifndef PACKAGE
	!define PACKAGE ..\..
!endif

!macro !echo msg
	!verbose push
	!verbose 4
	!echo "${msg}"
	!verbose pop
!macroend
!define !echo "!insertmacro !echo"

;=== Require at least Unicode NSIS 2.46 {{{1
!include RequireLatestNSIS.nsh
!define NewLine `$\r$\n`

;=== Privileges
!define RequestLevel USER
!define ResHacker    `${NSISDIR}\Contrib\Manifests\ResHacker.exe`
!define ManifDir     `${NSISDIR}\Contrib\Manifests`
!define Manifest     `NSIS_2.46_Win8`
!packhdr             `$%TEMP%\exehead.tmp` `"${Reshacker}" -addoverwrite "%TEMP%\exehead.tmp", "%TEMP%\exehead.tmp", "${ManifDir}\${Manifest}_${RequestLevel}.manifest", 24,1,1033`

;=== ExecAsUser
;!define Include_StdUtils.nsh ;=== include StndUtils w/out ExecAsUser
;!define ExecAsUser           ;=== for apps. which need to run as normal user.

;=== Custom Defines
;!define RegSleep 50           ;=== Sleep value for RegistryValueWrite. else function is innaccurate.
;!define Sleep 500             ;=== define sleep value for apps. which need to restart.
;!define NETCheck            ;=== function to check for .NET Framework.
;!define SetSysWOW64         ;=== Sets $SysWOW64 variable.
;!define CloseProc
;!define DisablePAL:LanguageCustom
;!define DisableProgramExecSegment    ;=== for apps. which require $ProgramExecutable built in !macro RunAsAdmin
;!define SYSTEMWIDE_DISABLEREDIR
;!define FORCE_SYSTEMWIDE_DISABLEREDIR ;=== checks using $Bit
!define RMEMPTYDIRECTORIES
;!define JAVA
;!define UAC
;!define XML_PLUGIN
;!define REGISTERDLL
!define REPLACE
;!define TLB_FUNCTION
;!define FIREWALL
;!define NSIS_REGISTRY
;!define 64.nsh
;!include StrRep.nsh
;!include RIF.nsh
;!define Disable_Settings
!define REGISTRY
;!define SERVICES
;!define DIRECTORIES_MOVE
;!define FILES_MOVE
;!define FONTS_ENABLE
;!define LocalLow
;!define PublicDoc
;!define NTFS
;!define ACL
;!define ACL_DIR
;!define CloseWindow
;!define DisableRMDirPostDirMove ; enable for SRWareIron
;!define SSDL
;!define GetBetween.nsh
;!define TrimString               ;=== enable for UAC
;!define IsFileLocked             ;=== enable ${If} ${FileLocked} / ${IfNot} ${FileLocked}
;!define INF_Install              ;=== enable !macros for .inf installation
;!define SSDL                     ;=== enable for SSDL
;!define FileCleanup               ;=== enable FilesCleanup
;!define Include_WordRep          ;=== enable WordRep & WordRepSs (same as ${WordReplace})
;!define Include_LineWrite.nsh    ;=== include LineWrite.nsh
;!define Include_ReadLine         ;=== enable ReadLine Function (same as LineRead)
;!define ConFunc                  ;=== enable ConfigWrite(s), ConfigRead(s) Functions.
;!define CompareVersions           ;=== enable VersionCompare Function.
;!define Include_WinMessages.nsh   ;=== include WinMessages.nsh
!ifdef REGISTRY
;	!define DISABLEFSR ;=== disable redirection
;	!define RegCopy    ;=== enable RegistryCopy
!endif
### APPLICATION SPECIFICATIONS ###
!define APP             YTD
;!define APP64           
!define APPNAME         `${APP}Portable`
!define FULLNAME        `YTD Video Downloader`
!define PORTABLEAPPNAME `${FULLNAME} Portable`
!define APPDIR          `$EXEDIR\App\${APP}`
;!define APPDIR64        `$EXEDIR\App\${APP64}`
!define APPINFO         `$EXEDIR\App\AppInfo`
!define DATA            `$EXEDIR\Data`
!define SET             `${DATA}\settings`
!define DEFDATA         `$EXEDIR\App\DefaultData`
!define DEFSET          `${DEFDATA}\settings`
!define LAUNCHDIR       `${APPINFO}\Launcher`
!define LAUNCHER        `${LAUNCHDIR}\${APPNAME}.ini`
!define LAUNCHER2       `$PLUGINSDIR\launcher.ini`
!define RUNTIME         `${DATA}\PortableApps.comLauncherRuntimeData-${APPNAME}.ini`
!define RUNTIME2        `$PLUGINSDIR\runtimedata.ini`
!define SETINI          `${SET}\${APPNAME}Settings.ini`
!define CONFIG          `$EXEDIR\${APPNAME}.ini`
!define OTHER           `$EXEDIR\Other`
;=== Runtime Switches
WindowIcon Off
XPStyle on
SilentInstall Silent
AutoCloseWindow True
!ifdef RUNASADMIN_COMPILEFORCE
	RequestExecutionLevel admin
!else
	RequestExecutionLevel user
!endif
SetCompressor /SOLID lzma
SetCompressorDictSize 32
!define PAL          PortableApps.comLauncher
!define LCID         `kernel32::GetUserDefaultLangID()i .r0`
!define GETSYSWOW64  `kernel32::GetSystemWow64Directory(t .r0, i ${NSIS_MAX_STRLEN})`
!define DISABLEREDIR `kernel32::Wow64EnableWow64FsRedirection(i0)`
!define ENABLEREDIR  `kernel32::Wow64EnableWow64FsRedirection(i1)`
!define GETCURRPROC  `kernel32::GetCurrentProcess()i.s`
!define WOW          `kernel32::IsWow64Process(is,*i.r0)`
Function IsWOW64
	!macro _IsWOW64 _RETURN
		Push ${_RETURN}
		Call IsWOW64
		Pop ${_RETURN}
	!macroend
	!define IsWOW64 `!insertmacro _IsWOW64`
	Exch $0
	System::Call `${GETCURRPROC}`
	System::Call `${WOW}`
	Exch $0
FunctionEnd
!define ReadLauncherConfig `!insertmacro ReadLauncherConfig`
!macro ReadLauncherConfig _RETURN _SECTION _ENTRY
	ReadINIStr ${_RETURN} `${LAUNCHER}` `${_SECTION}` `${_ENTRY}`
!macroend
!define WriteLauncherConfig `!insertmacro WriteLauncherConfig`
!macro WriteLauncherConfig _SECTION _ENTRY _VALUE
	WriteINIStr `${LAUNCHER}` `${_SECTION}` `${_ENTRY}` `${_VALUE}`
!macroend
!define DeleteLauncherConfig `!insertmacro DeleteLauncherConfig`
!macro DeleteLauncherConfig _SECTION _ENTRY
	DeleteINIStr `${LAUNCHER}` `${_SECTION}` `${_ENTRY}`
!macroend
!define DeleteLauncherConfigSec `!insertmacro DeleteLauncherConfigSec`
!macro DeleteLauncherConfigSec _SECTION
	DeleteINISec `${LAUNCHER}` `${_SECTION}`
!macroend
!define ReadLauncherConfigWithDefault `!insertmacro ReadLauncherConfigWithDefault`
!macro ReadLauncherConfigWithDefault _RETURN _SECTION _VALUE _DEFAULT
	ClearErrors
	${ReadLauncherConfig} ${_RETURN} `${_SECTION}` `${_VALUE}`
	${IfThen} ${Errors} ${|} StrCpy ${_OUTPUT} `${_DEFAULT}` ${|}
!macroend
!define ReadUserConfig `!insertmacro ReadUserConfig`
!macro ReadUserConfig _RETURN _KEY
	${ConfigReadS} `${CONFIG}` `${_KEY}=` `${_RETURN}`
!macroend
!define WriteUserConfig `!insertmacro WriteUserConfig`
!macro WriteUserConfig _VALUE _KEY
	${ConfigWriteS} `${CONFIG}` `${_KEY}=` `${_VALUE}` $R0
!macroend
!define ReadUserOverrideConfig `!insertmacro ReadUserOverrideConfigError`
!macro ReadUserOverrideConfigError a b
	!error `ReadUserOverrideConfig has been renamed to ReadUserConfig in PAL 2.1.`
!macroend
!define InvalidValueError `!insertmacro InvalidValueError`
!macro InvalidValueError _SECTION_KEY _VALUE
	MessageBox MB_OK|MB_ICONSTOP `Error: invalid value '${_VALUE}' for ${_SECTION_KEY}. Please refer to the Manual for valid values.`
!macroend
!define WriteRuntimeData "!insertmacro WriteRuntimeData"
!macro WriteRuntimeData _SECTION _KEY _VALUE
	WriteINIStr `${RUNTIME}` `${_SECTION}` `${_KEY}` `${_VALUE}`
	WriteINIStr `${RUNTIME2}` `${_SECTION}` `${_KEY}` `${_VALUE}`
!macroend
!define DeleteRuntimeData "!insertmacro DeleteRuntimeData"
!macro DeleteRuntimeData _SECTION _KEY
	DeleteINIStr `${RUNTIME}` `${_SECTION}` `${_KEY}`
	DeleteINIStr `${RUNTIME2}` `${_SECTION}` `${_KEY}`
!macroend
!define ReadRuntimeData "!insertmacro ReadRuntimeData"
!macro ReadRuntimeData _RETURN _SECTION _KEY
	IfFileExists `${RUNTIME}` 0 +3
	ReadINIStr `${_RETURN}` `${RUNTIME}` `${_SECTION}` `${_KEY}`
	Goto +2
	ReadINIStr `${_RETURN}` `${RUNTIME2}` `${_SECTION}` `${_KEY}`
!macroend
!define WriteRuntime "!insertmacro WriteRuntime"
!macro WriteRuntime _VALUE _KEY
	WriteINIStr `${RUNTIME}` PortableApps.comLauncher `${_KEY}` `${_VALUE}`
	WriteINIStr `${RUNTIME2}` PortableApps.comLauncher `${_KEY}` `${_VALUE}`
!macroend
!define ReadRuntime "!insertmacro ReadRuntime"
!macro ReadRuntime _RETURN _KEY
	IfFileExists `${RUNTIME}` 0 +3
	ReadINIStr `${_RETURN}` `${RUNTIME}` PortableApps.comLauncher `${_KEY}`
	Goto +2
	ReadINIStr `${_RETURN}` `${RUNTIME2}` PortableApps.comLauncher `${_KEY}`
!macroend
!define WriteSettings `!insertmacro WriteSettings`
!macro WriteSettings _VALUE _KEY
	WriteINIStr `${SETINI}` ${APPNAME}Settings `${_KEY}` `${_VALUE}`
!macroend
!define ReadSettings `!insertmacro ReadSettings`
!macro ReadSettings _RETURN _KEY
	ReadINIStr `${_RETURN}` `${SETINI}` ${APPNAME}Settings `${_KEY}`
!macroend
!define DeleteSettings `!insertmacro DeleteSettings`
!macro DeleteSettings _KEY
	DeleteINIStr `${SETINI}` ${APPNAME}Settings `${_KEY}`
!macroend
;=== Include {{{1
!include LangFile.nsh
!include LogicLib.nsh
!include FileFunc.nsh
!include TextFunc.nsh
!include WordFunc.nsh
!ifdef UAC
	!include UAC.nsh
!endif
# CUSTOM
;!include servicelib.nsh
;!include Junction.nsh
;(NSIS Plugins) {{{2
### PLUGINS DIR ###
!ifdef TLB_FUNCTION
	!ifndef PLUGINSDIR
		!define PLUGINSDIR
		!addplugindir Plugins
	!endif
!endif
!ifdef ExecAsUser
	!include StdUtils.nsh
	!ifndef PLUGINSDIR
		!define PLUGINSDIR
		!addplugindir Plugins
	!endif
!endif
!ifdef REPLACE
	!include NewTextReplace.nsh
	!ifndef PLUGINSDIR
		!define PLUGINSDIR
		!addplugindir Plugins
	!endif
!endif
!ifdef FIREWALL
	!ifndef PLUGINSDIR
		!define PLUGINSDIR
		!addplugindir Plugins
	!endif
!endif
!ifdef UAC
	!ifndef PLUGINSDIR
		!define PLUGINSDIR
		!addplugindir Plugins
	!endif
!endif
!ifdef WRITEREGBIN
	!ifndef PLUGINSDIR
		!define PLUGINSDIR
		!addplugindir Plugins
	!endif
!endif
!ifdef XML_PLUGIN
	!include XML.nsh
	!ifndef PLUGINSDIR
		!define PLUGINSDIR
		!addplugindir Plugins
	!endif
!endif
!ifdef Include_StdUtils.nsh
	!ifndef ExecAsUser
		!include StdUtils.nsh
		!ifndef PLUGINSDIR
			!define PLUGINSDIR
			!addplugindir Plugins
		!endif
	!endif
!endif
!ifdef NSIS_REGISTRY
	!include NSISRegistry.nsh
	!insertmacro MOVEREGKEY
!endif
;(Custom) {{{2
!ifdef REGISTRY
	!include Registry.nsh
	!define REGEXE `$SYSDIR\reg.exe`
	!define REGEDIT `$SYSDIR\regedit.exe`
!endif
!ifdef REPLACE
	!include ReplaceInFileWithTextReplace.nsh
!endif
!include ForEachINIPair.nsh
!include ForEachPath.nsh
!include SetFileAttributesDirectoryNormal.nsh
!include ProcFunc.nsh
!include EmptyWorkingSet.nsh
!include SetEnvironmentVariable.nsh
!include LogicLibAdditions.nsh
!ifdef GetBetween.nsh
	!include GetBetween.nsh
!endif
!ifdef GetLocale.nsh
	!include GetLocale.nsh
!endif
!ifdef 64.nsh
	!include x64.nsh
!endif
!ifdef IsFileLocked
	!ifndef 64.nsh
		!include x64.nsh
	!endif
!endif
!ifdef Include_LineWrite.nsh
	!include LineWrite.nsh
!endif
!ifdef Include_WinMessages.nsh
	!include WinMessages.nsh
!endif
!ifdef JAVA
	Var UsingJavaExecutable
	Var JavaMode
	Var JavaDirectory
!endif
!ifdef UAC
	Var RunAsAdmin
	!include UAC.nsh
	!ifndef TrimString
		!define TrimString
	!endif
!endif
!ifdef DIRECTORIES_MOVE
	!ifndef GET_ROOT
		!define GET_ROOT
	!endif
!endif
;=== Languages {{{1
${!echo} "Loading language strings..."
!include Languages.nsh
;=== Variables {{{1
${!echo} "Initialising variables and macros..."
var Bit
var Admin
Var AppID
Var BaseName
Var MissingFileOrPath
Var AppName
Var AppNamePortable
Var ProgramExecutable
Var StatusMutex
Var WaitForProgram
!ifdef REGISTRY
	var Registry
!endif
!include Segments.nsh
### BRANDING ###
!define BUILD                    5.5.0.2
${!echo}                         `Specifying program details and setting options...`
Name                             `${PORTABLEAPPNAME}`
OutFile                          `${PACKAGE}\${APPNAME}.exe`
Icon                             `${PACKAGE}\App\AppInfo\appicon.ico`
Caption                          `${FULLNAME}`
VIProductVersion                 ${BUILD}
VIAddVersionKey ProductName      `${FULLNAME}`
VIAddVersionKey Comments         http://portablewares.blogspot.com/
VIAddVersionKey CompanyName      `GreenTree Applications SRL`
VIAddVersionKey LegalCopyright   `Copyright © 2007-2015 GreenTree Applications SRL`
VIAddVersionKey FileDescription  `${FULLNAME}`
VIAddVersionKey FileVersion      ${BUILD}
VIAddVersionKey ProductVersion   Portable
VIAddVersionKey InternalName     `${APPNAME}.exe`
;VIAddVersionKey LegalTrademarks  ""
VIAddVersionKey OriginalFilename `${APPNAME}.exe`
!verbose 4
Function .onInit
	Push $0
	CreateDirectory `${SET}`
	!ifdef FORCE_SYSTEMWIDE_DISABLEREDIR
		!ifndef SYSTEMWIDE_DISABLEREDIR
			!define SYSTEMWIDE_DISABLEREDIR
		!endif
	!endif
	System::Call `kernel32::GetModuleHandle(t 'shell32.dll') i .s`
	System::Call `kernel32::GetProcAddress(i s, i 680) i .r0`
	System::Call `::$0() i .r0`
	StrCmpS $0 1 "" +2
	StrCpy $Admin true
	System::Call `${GETCURRPROC}`
	System::Call `${WOW}`
	StrCmpS $0 0 +3
	StrCpy $Bit 64
	Goto +2
	StrCpy $Bit 32
	!ifdef SYSTEMWIDE_DISABLEREDIR
		!ifdef FORCE_SYSTEMWIDE_DISABLEREDIR
			StrCmpS $Bit 64 "" +2
			System::Call `${DISABLEREDIR}`
		!else
			StrCmpS $APP ${APP64} "" +2
			System::Call `${DISABLEREDIR}`
		!endif
	!endif
	${RunSegment} Core
	${RunSegment} Custom
	${RunSegment} Temp
	${RunSegment} Language
	${RunSegment} OperatingSystem
	!ifdef UAC
		${RunSegment} RunAsAdmin
	!endif
	!ifdef SYSTEMWIDE_DISABLEREDIR
		!ifdef FORCE_SYSTEMWIDE_DISABLEREDIR
			StrCmpS $Bit 64 "" +2
			System::Call `${ENABLEREDIR}`
		!else
			StrCmpS $APP ${APP64} "" +2
			System::Call `${ENABLEREDIR}`
		!endif
	!endif
	Pop $0
FunctionEnd
Function Init
	!ifdef SYSTEMWIDE_DISABLEREDIR
		!ifdef FORCE_SYSTEMWIDE_DISABLEREDIR
			StrCmpS $Bit 64 "" +2
			System::Call `${DISABLEREDIR}`
		!else
			StrCmpS $APP ${APP64} "" +2
			System::Call `${DISABLEREDIR}`
		!endif
	!endif
	${If} $SecondaryLaunch != true
		${RunSegment} Language
		${RunSegment} Environment
		${RunSegment} Custom
	${EndIf}
	${RunSegment} Core
	${If} $SecondaryLaunch != true
		${RunSegment} PathChecks
		${RunSegment} DriveLetter
	${EndIf}
	${RunSegment} DirectoryMoving
	${RunSegment} Variables
	!ifdef JAVA
		${RunSegment} Java
	!endif
	${RunSegment} RunLocally
	${If} $SecondaryLaunch != true
		${RunSegment} Temp
	${EndIf}
	${RunSegment} InstanceManagement
	${If} $SecondaryLaunch != true
		${RunSegment} Settings
	${EndIf}
	!ifdef SYSTEMWIDE_DISABLEREDIR
		!ifdef FORCE_SYSTEMWIDE_DISABLEREDIR
			StrCmpS $Bit 64 "" +2
			System::Call `${ENABLEREDIR}`
		!else
			StrCmpS $APP ${APP64} "" +2
			System::Call `${ENABLEREDIR}`
		!endif
	!endif
FunctionEnd
Function Pre
	!ifdef SYSTEMWIDE_DISABLEREDIR
		!ifdef FORCE_SYSTEMWIDE_DISABLEREDIR
			StrCmpS $Bit 64 "" +2
			System::Call `${DISABLEREDIR}`
		!else
			StrCmpS $APP ${APP64} "" +2
			System::Call `${DISABLEREDIR}`
		!endif
	!endif
	${If} $SecondaryLaunch != true
		!ifdef SERVICES
			${RunSegment} Services
		!endif
		!ifdef REGISTERDLL
			${RunSegment} RegisterDLL
		!endif
	${EndIf}
	!ifdef REGISTRY
		${RunSegment} Registry
	!endif
	${RunSegment} Custom
	${RunSegment} RunLocally
	${RunSegment} Temp
	${RunSegment} Environment
	${RunSegment} ExecString
	!ifdef SYSTEMWIDE_DISABLEREDIR
		!ifdef FORCE_SYSTEMWIDE_DISABLEREDIR
			StrCmpS $Bit 64 "" +2
			System::Call `${ENABLEREDIR}`
		!else
			StrCmpS $APP ${APP64} "" +2
			System::Call `${ENABLEREDIR}`
		!endif
	!endif
FunctionEnd
Function PrePrimary
	!ifdef SYSTEMWIDE_DISABLEREDIR
		!ifdef FORCE_SYSTEMWIDE_DISABLEREDIR
			StrCmpS $Bit 64 "" +2
			System::Call `${DISABLEREDIR}`
		!else
			StrCmpS $APP ${APP64} "" +2
			System::Call `${DISABLEREDIR}`
		!endif
	!endif
	${If} $SecondaryLaunch != true
		!ifdef FileCleanup
			${RunSegment} FilesCleanup
		!endif
	${EndIf}
	${RunSegment} Custom
	${RunSegment} DriveLetter
	${RunSegment} Variables
	${RunSegment} DirectoryMoving
	${RunSegment} FileWrite
	${RunSegment} FilesMove
	${RunSegment} DirectoriesMove
	!ifdef REGISTRY
		${RunSegment} RegistryKeys
		!ifdef RegCopy
			${If} $SecondaryLaunch != true
				${RunSegment} RegistryCopyKeys
			${EndIf}
		!endif
		${RunSegment} RegistryValueBackupDelete
	!endif
	${If} $SecondaryLaunch != true
		!ifdef REGISTERDLL
			${RunSegment} RegisterDLL
		!endif
	${EndIf}
	!ifdef REGISTRY
		;=== this belongs here after Registering DLLs.
		${RunSegment} RegistryValueWrite
	!endif
	${If} $SecondaryLaunch != true
		!ifdef SERVICES
			${RunSegment} Services
		!endif
	${EndIf}
	!ifdef SYSTEMWIDE_DISABLEREDIR
		!ifdef FORCE_SYSTEMWIDE_DISABLEREDIR
			StrCmpS $Bit 64 "" +2
			System::Call `${ENABLEREDIR}`
		!else
			StrCmpS $APP ${APP64} "" +2
			System::Call `${ENABLEREDIR}`
		!endif
	!endif
FunctionEnd
Function PreSecondary
	!ifdef SYSTEMWIDE_DISABLEREDIR
		!ifdef FORCE_SYSTEMWIDE_DISABLEREDIR
			StrCmpS $Bit 64 "" +2
			System::Call `${DISABLEREDIR}`
		!else
			StrCmpS $APP ${APP64} "" +2
			System::Call `${DISABLEREDIR}`
		!endif
	!endif
	${RunSegment} Custom
	!ifdef SYSTEMWIDE_DISABLEREDIR
		!ifdef FORCE_SYSTEMWIDE_DISABLEREDIR
			StrCmpS $Bit 64 "" +2
			System::Call `${ENABLEREDIR}`
		!else
			StrCmpS $APP ${APP64} "" +2
			System::Call `${ENABLEREDIR}`
		!endif
	!endif
FunctionEnd
Function PreExec
	!ifdef SYSTEMWIDE_DISABLEREDIR
		!ifdef FORCE_SYSTEMWIDE_DISABLEREDIR
			StrCmpS $Bit 64 "" +2
			System::Call `${DISABLEREDIR}`
		!else
			StrCmpS $APP ${APP64} "" +2
			System::Call `${DISABLEREDIR}`
		!endif
	!endif
	${RunSegment} Custom
	${If} $SecondaryLaunch != true
		!ifdef REGISTERDLL
			${RunSegment} RegisterDLL
		!endif
	${EndIf}
	${RunSegment} RefreshShellIcons
	${RunSegment} WorkingDirectory
	!ifdef SYSTEMWIDE_DISABLEREDIR
		!ifdef FORCE_SYSTEMWIDE_DISABLEREDIR
			StrCmpS $Bit 64 "" +2
			System::Call `${ENABLEREDIR}`
		!else
			StrCmpS $APP ${APP64} "" +2
			System::Call `${ENABLEREDIR}`
		!endif
	!endif
FunctionEnd
Function PreExecPrimary
	!ifdef SYSTEMWIDE_DISABLEREDIR
		!ifdef FORCE_SYSTEMWIDE_DISABLEREDIR
			StrCmpS $Bit 64 "" +2
			System::Call `${DISABLEREDIR}`
		!else
			StrCmpS $APP ${APP64} "" +2
			System::Call `${DISABLEREDIR}`
		!endif
	!endif
	${RunSegment} Custom
	${RunSegment} Core
	!ifdef SYSTEMWIDE_DISABLEREDIR
		!ifdef FORCE_SYSTEMWIDE_DISABLEREDIR
			StrCmpS $Bit 64 "" +2
			System::Call `${ENABLEREDIR}`
		!else
			StrCmpS $APP ${APP64} "" +2
			System::Call `${ENABLEREDIR}`
		!endif
	!endif
FunctionEnd
Function PreExecSecondary
	!ifdef SYSTEMWIDE_DISABLEREDIR
		!ifdef FORCE_SYSTEMWIDE_DISABLEREDIR
			StrCmpS $Bit 64 "" +2
			System::Call `${DISABLEREDIR}`
		!else
			StrCmpS $APP ${APP64} "" +2
			System::Call `${DISABLEREDIR}`
		!endif
	!endif
	${RunSegment} Custom
	!ifdef SYSTEMWIDE_DISABLEREDIR
		!ifdef FORCE_SYSTEMWIDE_DISABLEREDIR
			StrCmpS $Bit 64 "" +2
			System::Call `${ENABLEREDIR}`
		!else
			StrCmpS $APP ${APP64} "" +2
			System::Call `${ENABLEREDIR}`
		!endif
	!endif
FunctionEnd
Function Execute
	!ifdef SYSTEMWIDE_DISABLEREDIR
		!ifdef FORCE_SYSTEMWIDE_DISABLEREDIR
			StrCmpS $Bit 64 "" +2
			System::Call `${DISABLEREDIR}`
		!else
			StrCmpS $APP ${APP64} "" +2
			System::Call `${DISABLEREDIR}`
		!endif
	!endif
	!ifmacrodef OverrideExecuteFunction
		!insertmacro OverrideExecuteFunction
	!else
		!ifmacrodef PreExecExecute
			!insertmacro PreExecExecute
		!endif
		${EmptyWorkingSet}
		ClearErrors
		${ReadLauncherConfig} $0 Launch HideCommandLineWindow
		${If} $0 == true
			StrCpy $ExecString "$ExecString $Parameters"
			ExecDos::exec /TOSTACK $ExecString
			Pop $0
		${Else}
			${IfNot} ${Errors}
			${AndIf} $0 != false
				${InvalidValueError} [Launch]:HideCommandLineWindow $0
			${EndIf}
			${If} $WaitForProgram != false
				!ifdef ExecAsUser
					${ConfigReads} `${CONFIG}` ExecAsAdmin= $0
					${If} $0 == true
						StrCpy $ExecString "$ExecString $Parameters"
						ExecWait $ExecString
					${Else}
						${StdUtils.ExecShellAsUser} $0 "$ExecString" "" "$Parameters"
						${EmptyWorkingSet}
						Sleep 1000
						${GetFileName} $ProgramExecutable $1
						${EmptyWorkingSet}
						${Do}
							${ProcessWaitClose} $1 -1 $R9
							${IfThen} $R9 > 0 ${|} ${Continue} ${|}
						${LoopWhile} $R9 > 0
					${EndIf}
				!else
					ExecWait $ExecString
				!endif
			${Else}
				!ifdef ExecAsUser
					${StdUtils.ExecShellAsUser} $0 "$ExecString" "" "$Parameters"
				!else
					Exec $ExecString
				!endif
			${EndIf}
		${EndIf}
		!ifmacrodef PostExecWaitCommand
			!insertmacro PostExecWaitCommand
		!endif
		${If} $WaitForProgram != false
			ClearErrors
			${ReadLauncherConfig} $0 Launch WaitForOtherInstances
			${If} $0 == true
			${OrIf} ${Errors}
				${GetFileName} $ProgramExecutable $1
				${EmptyWorkingSet}
				${Do}
					!ifdef Sleep
						Sleep ${Sleep}
					!endif
					${ProcessWaitClose} $1 -1 $R9
					${IfThen} $R9 > 0 ${|} ${Continue} ${|}
					StrCpy $0 1
					${Do}
						!ifdef Sleep
							Sleep ${Sleep}
						!endif
						ClearErrors
						${ConfigReadS} `${LAUNCHER}` WaitForEXE$0= $2
						${IfThen} ${Errors} ${|} ${ExitDo} ${|}
						ExpandEnvStrings $2 $2
						${ProcessWaitClose} $2 -1 $R9
						${IfThen} $R9 > 0 ${|} ${ExitDo} ${|}
						IntOp $0 $0 + 1
					${Loop}
				${LoopWhile} $R9 > 0
			${ElseIf} $0 != false
				${InvalidValueError} [Launch]:WaitForOtherInstances $0
			${EndIf}
		${EndIf}
	!endif
	!ifdef SYSTEMWIDE_DISABLEREDIR
		!ifdef FORCE_SYSTEMWIDE_DISABLEREDIR
			StrCmpS $Bit 64 "" +2
			System::Call `${ENABLEREDIR}`
		!else
			StrCmpS $APP ${APP64} "" +2
			System::Call `${ENABLEREDIR}`
		!endif
	!endif
FunctionEnd
Function PostPrimary
	!ifdef SYSTEMWIDE_DISABLEREDIR
		!ifdef FORCE_SYSTEMWIDE_DISABLEREDIR
			StrCmpS $Bit 64 "" +2
			System::Call `${DISABLEREDIR}`
		!else
			StrCmpS $APP ${APP64} "" +2
			System::Call `${DISABLEREDIR}`
		!endif
	!endif
	${If} $SecondaryLaunch != true
		!ifdef REGISTERDLL
			${RunSegment} RegisterDLL
		!endif
		!ifdef SERVICES
			${RunSegment} Services
		!endif
	${EndIf}
	!ifdef REGISTRY
		${RunSegment} RegistryValueBackupDelete
		${If} $SecondaryLaunch != true
			!ifdef RegCopy
				${RunSegment} RegistryCopyKeys
			!endif
		${EndIf}
		${RunSegment} RegistryKeys
		${RunSegment} RegistryCleanup
	!endif
	${If} $SecondaryLaunch != true
		${RunSegment} Qt
		!ifdef FileCleanup
			${RunSegment} FilesCleanup
		!endif
	${EndIf}
	${RunSegment} DirectoriesCleanup
	${RunSegment} DirectoriesMove
	${RunSegment} FilesMove
	${RunSegment} RunLocally
	${RunSegment} Temp
	${RunSegment} Custom
	!ifdef SYSTEMWIDE_DISABLEREDIR
		!ifdef FORCE_SYSTEMWIDE_DISABLEREDIR
			StrCmpS $Bit 64 "" +2
			System::Call `${ENABLEREDIR}`
		!else
			StrCmpS $APP ${APP64} "" +2
			System::Call `${ENABLEREDIR}`
		!endif
	!endif
FunctionEnd
Function PostSecondary
	!ifdef SYSTEMWIDE_DISABLEREDIR
		!ifdef FORCE_SYSTEMWIDE_DISABLEREDIR
			StrCmpS $Bit 64 "" +2
			System::Call `${DISABLEREDIR}`
		!else
			StrCmpS $APP ${APP64} "" +2
			System::Call `${DISABLEREDIR}`
		!endif
	!endif
	${RunSegment} Custom
	!ifdef SYSTEMWIDE_DISABLEREDIR
		!ifdef FORCE_SYSTEMWIDE_DISABLEREDIR
			StrCmpS $Bit 64 "" +2
			System::Call `${ENABLEREDIR}`
		!else
			StrCmpS $APP ${APP64} "" +2
			System::Call `${ENABLEREDIR}`
		!endif
	!endif
FunctionEnd
Function Post
	!ifdef SYSTEMWIDE_DISABLEREDIR
		!ifdef FORCE_SYSTEMWIDE_DISABLEREDIR
			StrCmpS $Bit 64 "" +2
			System::Call `${DISABLEREDIR}`
		!else
			StrCmpS $APP ${APP64} "" +2
			System::Call `${DISABLEREDIR}`
		!endif
	!endif
	${RunSegment} RefreshShellIcons
	${RunSegment} Custom
	!ifdef SYSTEMWIDE_DISABLEREDIR
		!ifdef FORCE_SYSTEMWIDE_DISABLEREDIR
			StrCmpS $Bit 64 "" +2
			System::Call `${ENABLEREDIR}`
		!else
			StrCmpS $APP ${APP64} "" +2
			System::Call `${ENABLEREDIR}`
		!endif
	!endif
FunctionEnd
Function Unload
	!ifdef SYSTEMWIDE_DISABLEREDIR
		!ifdef FORCE_SYSTEMWIDE_DISABLEREDIR
			StrCmpS $Bit 64 "" +2
			System::Call `${DISABLEREDIR}`
		!else
			StrCmpS $APP ${APP64} "" +2
			System::Call `${DISABLEREDIR}`
		!endif
	!endif
	${If} $SecondaryLaunch != true
		!ifdef REGISTERDLL
			${RunSegment} RegisterDLL
		!endif
		!ifdef SERVICES
			${RunSegment} Services
		!endif
		${RunSegment} FilesCleanup
		${RunSegment} DirectoriesCleanup
	${EndIf}
	${RunSegment} Core
	${RunSegment} Custom
	!ifdef SYSTEMWIDE_DISABLEREDIR
		!ifdef FORCE_SYSTEMWIDE_DISABLEREDIR
			StrCmpS $Bit 64 "" +2
			System::Call `${ENABLEREDIR}`
		!else
			StrCmpS $APP ${APP64} "" +2
			System::Call `${ENABLEREDIR}`
		!endif
	!endif
FunctionEnd
!define CallPS `!insertmacro CallPS`
!macro CallPS _func _rev
	!if ${_rev} == +
		Call ${_func}
	!endif
	${If} $SecondaryLaunch == true
		Call ${_func}Secondary
	${Else}
		Call ${_func}Primary
	${EndIf}
	!if ${_rev} != +
		Call ${_func}
	!endif
!macroend
Section
	!ifdef SYSTEMWIDE_DISABLEREDIR
		!ifdef FORCE_SYSTEMWIDE_DISABLEREDIR
			StrCmpS $Bit 64 "" +2
			System::Call `${DISABLEREDIR}`
		!else
			StrCmpS $APP ${APP64} "" +2
			System::Call `${DISABLEREDIR}`
		!endif
	!endif
	Call Init
	System::Call 'Kernel32::OpenMutex(i1048576, b0, t"PortableApps.comLauncher${APPNAME}-${APPNAME}::Starting") i.R0 ?e'
	System::Call 'Kernel32::CloseHandle(iR0)'
	Pop $R9
	${If} $R9 <> 2
		MessageBox MB_ICONSTOP $(LauncherAlreadyStarting)
		Quit
	${EndIf}
	System::Call 'Kernel32::OpenMutex(i1048576, i0, t"PortableApps.comLauncher${APPNAME}-${APPNAME}::Stopping") i.R0 ?e'
	System::Call 'Kernel32::CloseHandle(iR0)'
	Pop $R9
	${If} $R9 <> 2
		MessageBox MB_ICONSTOP $(LauncherAlreadyStopping)
		Quit
	${EndIf}
	${IfNot} ${FileExists} `${RUNTIME}`
	${OrIf} $SecondaryLaunch == true
		${If} $SecondaryLaunch != true
			System::Call 'Kernel32::CreateMutex(i0, i0, t"PortableApps.comLauncher${APPNAME}-${APPNAME}::Starting") i.r0'
			StrCpy $StatusMutex $0
		${EndIf}
		${CallPS} Pre +
		${CallPS} PreExec +
		${If} $SecondaryLaunch != true
			StrCpy $0 $StatusMutex
			System::Call 'Kernel32::CloseHandle(ir0) ?e'
			Pop $R9
		${EndIf}
		Call Execute
	${Else}
		MessageBox MB_ICONSTOP $(LauncherCrashCleanup)
	${EndIf}
	${If} $SecondaryLaunch != true
		System::Call 'Kernel32::CreateMutex(i0, i0, t"PortableApps.comLauncher${APPNAME}-${APPNAME}::Stopping")'
	${EndIf}
	${If} $WaitForProgram != false
		${CallPS} Post -
	${EndIf}
	Call Unload
	!ifdef SYSTEMWIDE_DISABLEREDIR
		!ifdef FORCE_SYSTEMWIDE_DISABLEREDIR
			StrCmpS $Bit 64 "" +2
			System::Call `${ENABLEREDIR}`
		!else
			StrCmpS $APP ${APP64} "" +2
			System::Call `${ENABLEREDIR}`
		!endif
	!endif
SectionEnd
Function .onInstFailed
	Call Unload
FunctionEnd