+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+; Path Manipulation functions ;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+!verbose 3
+!include "WinMessages.nsh"
+!verbose 4
+
+Function AddBinToPath
+ Push "$INSTDIR\bin"
+ Call AddToPath
+FunctionEnd
+
+; AddToPath - Adds the given dir to the search path.
+; Input - head of the stack
+; Note - Win9x systems requires reboot
+
+Function AddToPath
+ Exch $0
+ Push $1
+ Push $2
+ Push $3
+ Push $4
+
+ ; don't add if the path doesn't exist
+ IfFileExists $0 "" AddToPath_done
+
+ Call IsNT
+ Pop $4
+ StrCmp $4 1 +3
+ ; Not on NT: read PATH from environment variable
+ ReadEnvStr $1 PATH
+ Goto +2
+ ; On NT: read PATH from registry
+ ReadRegStr $1 HKCU "Environment" "PATH"
+ ${StrStr} $2 "$1;" "$0;"
+ StrCmp $2 "" "" AddToPath_done
+
+ ${StrStr} $2 "$1;" "$0\;"
+ StrCmp $2 "" "" AddToPath_done
+
+ GetFullPathName /SHORT $3 $0
+ ${StrStr} $2 "$1;" "$3;"
+ StrCmp $2 "" "" AddToPath_done
+
+ ${StrStr} $2 "$1;" "$03\;"
+ StrCmp $2 "" "" AddToPath_done
+
+ StrCmp $4 1 AddToPath_NT
+ ; Not on NT
+ StrCpy $1 $WINDIR 2
+ FileOpen $1 "$1\autoexec.bat" a
+ FileSeek $1 -1 END
+ FileReadByte $1 $2
+ IntCmp $2 26 0 +2 +2 ; DOS EOF
+ FileSeek $1 -1 END ; write over EOF
+ FileWrite $1 "$\r$\nSET PATH=%PATH%;$3$\r$\n"
+ FileClose $1
+ SetRebootFlag true
+ Goto AddToPath_done
+
+ AddToPath_NT:
+ ;System PATH variable is at:
+ ;HKLM "/SYSTEM/CurrentControlSet/Control/Session Manager/Environment" "Path"
+ ReadRegStr $1 HKCU "Environment" "PATH"
+ StrCpy $2 $1 1 -1 ; copy last char
+ StrCmp $2 ";" 0 +2 ; if last char == ;
+ StrCpy $1 $1 -1 ; remove last char
+ StrCmp $1 "" AddToPath_NTdoIt
+ StrCpy $0 "$1;$0"
+ AddToPath_NTdoIt:
+ WriteRegExpandStr HKCU "Environment" "PATH" $0
+ SendMessage ${HWND_BROADCAST} ${WM_WININICHANGE} 0 "STR:Environment" /TIMEOUT=5000
+
+ AddToPath_done:
+ Pop $4
+ Pop $3
+ Pop $2
+ Pop $1
+ Pop $0
+FunctionEnd
+
+; RemoveFromPath - Remove a given dir from the path
+; Input: head of the stack
+
+Function un.RemoveFromPath
+ Exch $0
+ Push $1
+ Push $2
+ Push $3
+ Push $4
+ Push $5
+ Push $6
+
+ IntFmt $6 "%c" 26 ; DOS EOF
+
+ Call un.IsNT
+ Pop $1
+ StrCmp $1 1 unRemoveFromPath_NT
+ ; Not on NT
+ StrCpy $1 $WINDIR 2
+ FileOpen $1 "$1\autoexec.bat" r
+ GetTempFileName $4
+ FileOpen $2 $4 w
+ GetFullPathName /SHORT $0 $0
+ StrCpy $0 "SET PATH=%PATH%;$0"
+ Goto unRemoveFromPath_dosLoop
+
+ unRemoveFromPath_dosLoop:
+ FileRead $1 $3
+ StrCpy $5 $3 1 -1 ; read last char
+ StrCmp $5 $6 0 +2 ; if DOS EOF
+ StrCpy $3 $3 -1 ; remove DOS EOF so we can compare
+ StrCmp $3 "$0$\r$\n" unRemoveFromPath_dosLoopRemoveLine
+ StrCmp $3 "$0$\n" unRemoveFromPath_dosLoopRemoveLine
+ StrCmp $3 "$0" unRemoveFromPath_dosLoopRemoveLine
+ StrCmp $3 "" unRemoveFromPath_dosLoopEnd
+ FileWrite $2 $3
+ Goto unRemoveFromPath_dosLoop
+ unRemoveFromPath_dosLoopRemoveLine:
+ SetRebootFlag true
+ Goto unRemoveFromPath_dosLoop
+
+ unRemoveFromPath_dosLoopEnd:
+ FileClose $2
+ FileClose $1
+ StrCpy $1 $WINDIR 2
+ Delete "$1\autoexec.bat"
+ CopyFiles /SILENT $4 "$1\autoexec.bat"
+ Delete $4
+ Goto unRemoveFromPath_done
+
+ unRemoveFromPath_NT:
+ ;System PATH variable is at:
+ ;HKLM "/SYSTEM/CurrentControlSet/Control/Session Manager/Environment" "Path"
+ ReadRegStr $1 HKCU "Environment" "PATH"
+ StrCpy $5 $1 1 -1 ; copy last char
+ StrCmp $5 ";" +2 ; if last char != ;
+ StrCpy $1 "$1;" ; append ;
+ ${UnStrStr} $2 $1 "$0;" ; Find `$0;` in $1
+ StrCmp $2 "" unRemoveFromPath_done
+ ; else, it is in path
+ ; $0 - path to add
+ ; $1 - path var
+ StrLen $3 "$0;"
+ StrLen $4 $2
+ StrCpy $5 $1 -$4 ; $5 is now the part before the path to remove
+ StrCpy $6 $2 "" $3 ; $6 is now the part after the path to remove
+ StrCpy $3 $5$6
+
+ StrCpy $5 $3 1 -1 ; copy last char
+ StrCmp $5 ";" 0 +2 ; if last char == ;
+ StrCpy $3 $3 -1 ; remove last char
+
+ StrCmp $3 "" +3
+ ; New PATH not empty: update the registry
+ WriteRegExpandStr HKCU "Environment" "PATH" $3
+ Goto +2
+ ; New PATH empty: remove from the registry
+ DeleteRegValue HKCU "Environment" "PATH"
+ SendMessage ${HWND_BROADCAST} ${WM_WININICHANGE} 0 "STR:Environment" /TIMEOUT=5000
+
+ unRemoveFromPath_done:
+ Pop $6
+ Pop $5
+ Pop $4
+ Pop $3
+ Pop $2
+ Pop $1
+ Pop $0
+FunctionEnd
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+; Utility Functions ;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+; IsNT
+; no input
+; output, top of the stack = 1 if NT or 0 if not
+;
+; Usage:
+; Call IsNT
+; Pop $R0
+; ($R0 at this point is 1 or 0)
+
+!macro IsNT un
+Function ${un}IsNT
+ Push $0
+ ReadRegStr $0 HKLM "SOFTWARE\Microsoft\Windows NT\CurrentVersion" CurrentVersion
+ StrCmp $0 "" 0 IsNT_yes
+ ; we are not NT.
+ Pop $0
+ Push 0
+ Return
+
+ IsNT_yes:
+ ; NT!!!
+ Pop $0
+ Push 1
+FunctionEnd
+!macroend
+!insertmacro IsNT ""
+!insertmacro IsNT "un."
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+; Uninstall/Reinstall page functions ;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+!ifdef VER_MAJOR & VER_MINOR & VER_REVISION & VER_BUILD
+
+Var ReinstallPageCheck
+
+Function PageReinstall
+
+ ReadRegStr $R0 HKLM "Software\${PRODUCT_NAME}" ""
+
+ ${If} $R0 == ""
+ ReadRegStr $R0 HKLM "${PRODUCT_UNINST_KEY}" "UninstallString"
+ ${If} $R0 == ""
+ Abort
+ ${EndIf}
+ ${EndIf}
+
+ ReadRegDWORD $R0 HKLM "Software\${PRODUCT_NAME}" "VersionMajor"
+ ReadRegDWORD $R1 HKLM "Software\${PRODUCT_NAME}" "VersionMinor"
+ ReadRegDWORD $R2 HKLM "Software\${PRODUCT_NAME}" "VersionRevision"
+ ReadRegDWORD $R3 HKLM "Software\${PRODUCT_NAME}" "VersionBuild"
+ StrCpy $R0 $R0.$R1.$R2.$R3
+
+ ${VersionCompare} ${VER_MAJOR}.${VER_MINOR}.${VER_REVISION}.${VER_BUILD} $R0 $R0
+ ${If} $R0 == 0
+ StrCpy $R1 "${PRODUCT_NAME} ${PRODUCT_VERSION} is already installed. Select the operation you want to perform and click Next to continue."
+ StrCpy $R2 "Add/Reinstall components"
+ StrCpy $R3 "Uninstall ${PRODUCT_NAME}"
+ !insertmacro MUI_HEADER_TEXT "Already Installed" "Choose the maintenance option to perform."
+ StrCpy $R0 "2"
+ ${ElseIf} $R0 == 1
+ StrCpy $R1 "An older version of ${PRODUCT_NAME} is installed on your system. It's recommended that you uninstall the current version before installing. Select the operation you want to perform and click Next to continue."
+ StrCpy $R2 "Uninstall before installing"
+ StrCpy $R3 "Do not uninstall"
+ !insertmacro MUI_HEADER_TEXT "Already Installed" "Choose how you want to install ${PRODUCT_NAME}."
+ StrCpy $R0 "1"
+ ${ElseIf} $R0 == 2
+ StrCpy $R1 "A newer version of ${PRODUCT_NAME} is already installed! It is not recommended that you install an older version. If you really want to install this older version, it's better to uninstall the current version first. Select the operation you want to perform and click Next to continue."
+ StrCpy $R2 "Uninstall before installing"
+ StrCpy $R3 "Do not uninstall"
+ !insertmacro MUI_HEADER_TEXT "Already Installed" "Choose how you want to install ${PRODUCT_NAME}."
+ StrCpy $R0 "1"
+ ${Else}
+ Abort
+ ${EndIf}
+
+ nsDialogs::Create /NOUNLOAD 1018
+
+ ${NSD_CreateLabel} 0 0 100% 24u $R1
+ Pop $R1
+
+ ${NSD_CreateRadioButton} 30u 50u -30u 8u $R2
+ Pop $R2
+ ${NSD_OnClick} $R2 PageReinstallUpdateSelection
+
+ ${NSD_CreateRadioButton} 30u 70u -30u 8u $R3
+ Pop $R3
+ ${NSD_OnClick} $R3 PageReinstallUpdateSelection
+
+ ${If} $ReinstallPageCheck != 2
+ SendMessage $R2 ${BM_SETCHECK} ${BST_CHECKED} 0
+ ${Else}
+ SendMessage $R3 ${BM_SETCHECK} ${BST_CHECKED} 0
+ ${EndIf}
+
+ nsDialogs::Show
+
+FunctionEnd
+
+Function PageReinstallUpdateSelection
+
+ Pop $R1
+
+ ${NSD_GetState} $R2 $R1
+
+ ${If} $R1 == ${BST_CHECKED}
+ StrCpy $ReinstallPageCheck 1
+ ${Else}
+ StrCpy $ReinstallPageCheck 2
+ ${EndIf}
+
+FunctionEnd
+
+Function PageLeaveReinstall
+
+ ${NSD_GetState} $R2 $R1
+
+ StrCmp $R0 "1" 0 +2
+ StrCmp $R1 "1" reinst_uninstall reinst_done
+
+ StrCmp $R0 "2" 0 +3
+ StrCmp $R1 "1" reinst_done reinst_uninstall
+
+ reinst_uninstall:
+ ReadRegStr $R1 HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" "UninstallString"
+
+ ;Run uninstaller
+ HideWindow
+
+ ClearErrors
+ ExecWait '$R1 _?=$INSTDIR'
+
+ IfErrors no_remove_uninstaller
+ IfFileExists "$INSTDIR\bin\${PRODUCT_NAME}.exe" no_remove_uninstaller
+
+ Delete $R1
+ RMDir $INSTDIR
+
+ no_remove_uninstaller:
+
+ StrCmp $R0 "2" 0 +2
+ Quit
+
+ BringToFront
+
+ reinst_done:
+
+FunctionEnd
+
+!endif # VER_MAJOR & VER_MINOR & VER_REVISION & VER_BUILD