!macro moveFile FROM TOClearErrorsRename `${FROM}` `${TO}`${if} ${errors}# not clear - can NSIS rename on another drive or not, so, in case of error, just copyClearErrors!insertmacro copyFile `${FROM}` `${TO}`Delete `${FROM}`${endif}!macroend!macro copyFile FROM TO${StdUtils.GetParentPath} $R5 `${TO}`CreateDirectory `$R5`ClearErrorsCopyFiles /SILENT `${FROM}` `${TO}`!macroendFunction GetInQuotesExch $R0Push $R1Push $R2Push $R3StrCpy $R2 -1IntOp $R2 $R2 + 1StrCpy $R3 $R0 1 $R2StrCmp $R3 "" 0 +3StrCpy $R0 ""Goto DoneStrCmp $R3 '"' 0 -5IntOp $R2 $R2 + 1StrCpy $R0 $R0 "" $R2StrCpy $R2 0IntOp $R2 $R2 + 1StrCpy $R3 $R0 1 $R2StrCmp $R3 "" 0 +3StrCpy $R0 ""Goto DoneStrCmp $R3 '"' 0 -5StrCpy $R0 $R0 $R2Done:Pop $R3Pop $R2Pop $R1Exch $R0FunctionEnd!macro GetInQuotes Var StrPush "${Str}"Call GetInQuotesPop "${Var}"!macroendFunction GetFileParentExch $R0Push $R1Push $R2Push $R3StrCpy $R1 0StrLen $R2 $R0loop:IntOp $R1 $R1 + 1IntCmp $R1 $R2 get 0 getStrCpy $R3 $R0 1 -$R1StrCmp $R3 "\" getGoto loopget:StrCpy $R0 $R0 -$R1Pop $R3Pop $R2Pop $R1Exch $R0FunctionEndVar /GLOBAL isTryToKeepShortcuts!macro setIsTryToKeepShortcutsStrCpy $isTryToKeepShortcuts "true"!ifdef allowToChangeInstallationDirectory${ifNot} ${isUpdated}StrCpy $isTryToKeepShortcuts "false"${endIf}!endif!macroend# https://nsis-dev.github.io/NSIS-Forums/html/t-172971.html!macro readReg VAR ROOT_KEY SUB_KEY NAME${if} "${ROOT_KEY}" == "SHELL_CONTEXT"ReadRegStr "${VAR}" SHELL_CONTEXT "${SUB_KEY}" "${NAME}"${elseif} "${ROOT_KEY}" == "HKEY_CURRENT_USER"ReadRegStr "${VAR}" HKEY_CURRENT_USER "${SUB_KEY}" "${NAME}"${elseif} "${ROOT_KEY}" == "HKEY_LOCAL_MACHINE"ReadRegStr "${VAR}" HKEY_LOCAL_MACHINE "${SUB_KEY}" "${NAME}"${else}MessageBox MB_OK "Unsupported ${ROOT_KEY}"${endif}!macroendFunction handleUninstallResultVar /GLOBAL rootKey_uninstallResultExch $rootKey_uninstallResult${if} "$rootKey_uninstallResult" == "SHELL_CONTEXT"!ifmacrodef customUnInstallCheck!insertmacro customUnInstallCheckReturn!endif${elseif} "$rootKey_uninstallResult" == "HKEY_CURRENT_USER"!ifmacrodef customUnInstallCheckCurrentUser!insertmacro customUnInstallCheckCurrentUserReturn!endif${endif}IfErrors 0 +3DetailPrint `Uninstall was not successful. Not able to launch uninstaller!`Return${if} $R0 != 0MessageBox MB_OK|MB_ICONEXCLAMATION "$(uninstallFailed): $R0"DetailPrint `Uninstall was not successful. Uninstaller error code: $R0.`SetErrorLevel 2Quit${endif}FunctionEnd!macro handleUninstallResult ROOT_KEYPush "${ROOT_KEY}"Call handleUninstallResult!macroend# http://stackoverflow.com/questions/24595887/waiting-for-nsis-uninstaller-to-finish-in-nsis-installer-either-fails-or-the-uniFunction uninstallOldVersionVar /GLOBAL uninstallerFileNameVar /Global uninstallerFileNameTempVar /GLOBAL installationDirVar /GLOBAL uninstallStringVar /GLOBAL rootKeyClearErrorsExch $rootKeyPush 0Pop $R0!insertmacro readReg $uninstallString "$rootKey" "${UNINSTALL_REGISTRY_KEY}" UninstallString${if} $uninstallString == ""!ifdef UNINSTALL_REGISTRY_KEY_2!insertmacro readReg $uninstallString "$rootKey" "${UNINSTALL_REGISTRY_KEY_2}" UninstallString!endif${if} $uninstallString == ""ClearErrorsReturn${endif}${endif}# uninstaller should be copied out of app installation dir (because this dir will be deleted), so, extract uninstaller file name!insertmacro GetInQuotes $uninstallerFileName "$uninstallString"!insertmacro readReg $installationDir "$rootKey" "${INSTALL_REGISTRY_KEY}" InstallLocation${if} $installationDir == ""${andIf} $uninstallerFileName != ""# https://github.com/electron-userland/electron-builder/issues/735#issuecomment-246918567Push $uninstallerFileNameCall GetFileParentPop $installationDir${endif}${if} $installationDir == ""${andIf} $uninstallerFileName == ""ClearErrorsReturn${endif}${if} $installMode == "CurrentUser"${orIf} $rootKey == "HKEY_CURRENT_USER"StrCpy $0 "/currentuser"${else}StrCpy $0 "/allusers"${endif}!insertMacro setIsTryToKeepShortcuts${if} $isTryToKeepShortcuts == "true"!insertmacro readReg $R5 "$rootKey" "${INSTALL_REGISTRY_KEY}" KeepShortcuts# if true, it means that old uninstaller supports --keep-shortcuts flag${if} $R5 == "true"${andIf} ${FileExists} "$appExe"StrCpy $0 "$0 --keep-shortcuts"${endIf}${endIf}${if} ${isDeleteAppData}StrCpy $0 "$0 --delete-app-data"${else}# always pass --updated flag - to ensure that if DELETE_APP_DATA_ON_UNINSTALL is defined, user data will be not removedStrCpy $0 "$0 --updated"${endif}StrCpy $uninstallerFileNameTemp "$PLUGINSDIR\old-uninstaller.exe"!insertmacro copyFile "$uninstallerFileName" "$uninstallerFileNameTemp"# Retry counterStrCpy $R5 0UninstallLoop:IntOp $R5 $R5 + 1${if} $R5 > 5MessageBox MB_RETRYCANCEL|MB_ICONEXCLAMATION "$(appCannotBeClosed)" /SD IDCANCEL IDRETRY OneMoreAttemptReturn${endIf}OneMoreAttempt:ExecWait '"$uninstallerFileNameTemp" /S /KEEP_APP_DATA $0 _?=$installationDir' $R0ifErrors TryInPlace CheckResultTryInPlace:# the execution failed - might have been caused by some group policy restrictions# we try to execute the uninstaller in placeExecWait '"$uninstallerFileName" /S /KEEP_APP_DATA $0 _?=$installationDir' $R0ifErrors DoesNotExistCheckResult:${if} $R0 == 0Return${endIf}Sleep 1000Goto UninstallLoopDoesNotExist:SetErrorsFunctionEnd!macro uninstallOldVersion ROOT_KEYPush "${ROOT_KEY}"Call uninstallOldVersion!macroend