!include nsDialogs.nshVar HasTwoAvailableOptionsVar RadioButtonLabel1Var isForceMachineInstallVar isForceCurrentInstall!macro PAGE_INSTALL_MODE!insertmacro MUI_PAGE_INIT!insertmacro MUI_SET MULTIUSER_${MUI_PAGE_UNINSTALLER_PREFIX}INSTALLMODEPAGE ""Var MultiUser.InstallModePageVar MultiUser.InstallModePage.TextVar MultiUser.InstallModePage.AllUsersVar MultiUser.InstallModePage.CurrentUserVar MultiUser.InstallModePage.ReturnValue!ifndef BUILD_UNINSTALLER!insertmacro FUNCTION_INSTALL_MODE_PAGE_FUNCTION MultiUser.InstallModePre_${MUI_UNIQUEID} MultiUser.InstallModeLeave_${MUI_UNIQUEID} ""PageEx customPageCallbacks MultiUser.InstallModePre_${MUI_UNIQUEID} MultiUser.InstallModeLeave_${MUI_UNIQUEID}Caption " "PageExEnd!else!insertmacro FUNCTION_INSTALL_MODE_PAGE_FUNCTION MultiUser.InstallModePre_${MUI_UNIQUEID} MultiUser.InstallModeLeave_${MUI_UNIQUEID} un.UninstPage custom un.multiUser.InstallModePre_${MUI_UNIQUEID} un.MultiUser.InstallModeLeave_${MUI_UNIQUEID}!endif!macroend!macro FUNCTION_INSTALL_MODE_PAGE_FUNCTION PRE LEAVE UNINSTALLER_FUNCPREFIXFunction "${UNINSTALLER_FUNCPREFIX}${PRE}"${if} ${UAC_IsInnerInstance}${andIf} ${UAC_IsAdmin}# inner Process (and Admin) - skip selection, inner process is always used for elevation (machine-wide)!insertmacro setInstallModePerAllUsersAbort${endIf}StrCpy $isForceMachineInstall "0"StrCpy $isForceCurrentInstall "0"!ifmacrodef customInstallmode!insertmacro customInstallMode!endif${if} $isForceMachineInstall == "1"${OrIf} ${isForAllUsers}StrCpy $hasPerMachineInstallation "1"StrCpy $hasPerUserInstallation "0"${ifNot} ${UAC_IsAdmin}ShowWindow $HWNDPARENT ${SW_HIDE}!insertmacro UAC_RunElevatedQuit${endIf}!insertmacro setInstallModePerAllUsersAbort${endIf}${if} $isForceCurrentInstall == "1"${OrIf} ${isForCurrentUser}StrCpy $hasPerMachineInstallation "0"StrCpy $hasPerUserInstallation "1"!insertmacro setInstallModePerUserAbort${endIf}# If uninstalling, will check if there is both a per-user and per-machine installation. If there is only one, will skip the form.# If uninstallation was invoked from the "add/remove programs" Windows will automatically requests elevation (depending if uninstall keys are in HKLM or HKCU)# so (for uninstallation) just checking UAC_IsAdmin would probably be enought to determine if it's a per-user or per-machine. However, user can run the uninstall.exe from the folder itself!ifdef BUILD_UNINSTALLER${if} $hasPerUserInstallation == "1"${andif} $hasPerMachineInstallation == "0"!insertmacro setInstallModePerUserAbort${elseIf} $hasPerUserInstallation == "0"${andIf} $hasPerMachineInstallation == "1"${IfNot} ${UAC_IsAdmin}ShowWindow $HWNDPARENT ${SW_HIDE}!insertmacro UAC_RunElevatedQuit${endIf}!insertmacro setInstallModePerAllUsersAbort${endIf}!insertmacro MUI_HEADER_TEXT "$(chooseUninstallationOptions)" "$(whichInstallationShouldBeRemoved)"!else!insertmacro MUI_HEADER_TEXT "$(chooseInstallationOptions)" "$(whoShouldThisApplicationBeInstalledFor)"!endif!insertmacro MUI_PAGE_FUNCTION_CUSTOM PREnsDialogs::Create 1018Pop $MultiUser.InstallModePage!ifndef BUILD_UNINSTALLER${NSD_CreateLabel} 0u 0u 300u 20u "$(selectUserMode)"StrCpy $8 "$(forAll)"StrCpy $9 "$(onlyForMe)"!else${NSD_CreateLabel} 0u 0u 300u 20u "$(whichInstallationRemove)"StrCpy $8 "$(forAll)"StrCpy $9 "$(onlyForMe)"!endifPop $MultiUser.InstallModePage.Text${NSD_CreateRadioButton} 10u 30u 280u 20u "$8"Pop $MultiUser.InstallModePage.AllUsers${IfNot} ${UAC_IsAdmin}!ifdef MULTIUSER_INSTALLMODE_ALLOW_ELEVATIONStrCpy $HasTwoAvailableOptions 1!else# since radio button is disabled, we add that comment to the disabled control itselfSendMessage $MultiUser.InstallModePage.AllUsers ${WM_SETTEXT} 0 "STR:$8 (must run as admin)"EnableWindow $MultiUser.InstallModePage.AllUsers 0 # start out disabledStrCpy $HasTwoAvailableOptions 0!endif${else}StrCpy $HasTwoAvailableOptions 1${endif}System::Call "advapi32::GetUserName(t.r0,*i${NSIS_MAX_STRLEN})i"${NSD_CreateRadioButton} 10u 50u 280u 20u "$9 ($0)"Pop $MultiUser.InstallModePage.CurrentUsernsDialogs::SetUserData $MultiUser.InstallModePage.AllUsers 1 ; Install for All Users (1, pra exibir o icone SHIELD de elevation)nsDialogs::SetUserData $MultiUser.InstallModePage.CurrentUser 0 ; Install for Single User (0 pra não exibir)${if} $HasTwoAvailableOptions == "1" ; if there are 2 available options, bind to radiobutton change${NSD_OnClick} $MultiUser.InstallModePage.CurrentUser ${UNINSTALLER_FUNCPREFIX}InstModeChange${NSD_OnClick} $MultiUser.InstallModePage.AllUsers ${UNINSTALLER_FUNCPREFIX}InstModeChange${endif}${NSD_CreateLabel} 0u 110u 280u 50u ""Pop $RadioButtonLabel1${if} $installMode == "all"SendMessage $MultiUser.InstallModePage.AllUsers ${BM_SETCHECK} ${BST_CHECKED} 0 ; set as defaultSendMessage $MultiUser.InstallModePage.AllUsers ${BM_CLICK} 0 0 ; trigger click event${else}SendMessage $MultiUser.InstallModePage.CurrentUser ${BM_SETCHECK} ${BST_CHECKED} 0 ; set as defaultSendMessage $MultiUser.InstallModePage.CurrentUser ${BM_CLICK} 0 0 ; trigger click event${endif}!insertmacro MUI_PAGE_FUNCTION_CUSTOM SHOWnsDialogs::ShowFunctionEndFunction "${UNINSTALLER_FUNCPREFIX}${LEAVE}"SendMessage $MultiUser.InstallModePage.AllUsers ${BM_GETCHECK} 0 0 $MultiUser.InstallModePage.ReturnValue${if} $MultiUser.InstallModePage.ReturnValue = ${BST_CHECKED}${IfNot} ${UAC_IsAdmin}ShowWindow $HWNDPARENT ${SW_HIDE}!insertmacro UAC_RunElevated${Switch} $0${Case} 0${If} $1 = 1Quit ;we are the outer process, the inner process has done its work (ExitCode is $2), we are done${EndIf}${If} $1 = 3 ;RunAs completed successfully, but with a non-admin user${OrIf} $2 = 0x666666 ;our special return, the new process was not admin after allMessageBox mb_IconStop|mb_TopMost|mb_SetForeground "$(loginWithAdminAccount)"${EndIf}${Break}${Case} 1223 ;user aborted;MessageBox mb_IconStop|mb_TopMost|mb_SetForeground "This option requires admin privileges, aborting!";Quit ; instead of quit just abort going to the next page, and stay in the radiobuttons${Break}${Case} 1062MessageBox mb_IconStop|mb_TopMost|mb_SetForeground "Logon service not running, aborting!" ; "Unable to elevate, Secondary Logon service not running!";Quit ; instead of quit just abort going to the next page, and stay in the radiobuttons${Break}${Default}MessageBox mb_IconStop|mb_TopMost|mb_SetForeground "Unable to elevate, error $0";Quit ; instead of quit just abort going to the next page, and stay in the radiobuttons${Break}${EndSwitch}ShowWindow $HWNDPARENT ${SW_SHOW}BringToFrontAbort${else}!insertmacro setInstallModePerAllUsers${endif}${else}!insertmacro setInstallModePerUser${endif}!insertmacro MUI_PAGE_FUNCTION_CUSTOM LEAVEFunctionEndFunction "${UNINSTALLER_FUNCPREFIX}InstModeChange"pop $1nsDialogs::GetUserData $1pop $1GetDlgItem $0 $hwndParent 1 ; get item 1 (next button) at parent window, store in $0 - (0 is back, 1 is next .. what about CANCEL? http://nsis.sourceforge.net/Buttons_Header )StrCpy $7 ""${if} "$1" == "0" ; current user${if} $hasPerUserInstallation == "1"!ifndef BUILD_UNINSTALLERStrCpy $7 "$(perUserInstallExists)($perUserInstallationFolder)$\r$\n$(reinstallUpgrade)"!elseStrCpy $7 "$(perUserInstall)($perUserInstallationFolder)$\r$\n$(uninstall)"!endif${else}StrCpy $7 "$(freshInstallForCurrent)"${endif}SendMessage $0 ${BCM_SETSHIELD} 0 0 ; hide SHIELD${else} ; all users${if} $hasPerMachineInstallation == "1"!ifndef BUILD_UNINSTALLERStrCpy $7 "$(perMachineInstallExists)($perMachineInstallationFolder)$\r$\n$(reinstallUpgrade)"!elseStrCpy $7 "$(perMachineInstall)($perMachineInstallationFolder)$\r$\n$(uninstall)"!endif${else}StrCpy $7 "$(freshInstallForAll)"${endif}${ifNot} ${UAC_IsAdmin}StrCpy $7 "$7"SendMessage $0 ${BCM_SETSHIELD} 0 1 ; display SHIELD${else}SendMessage $0 ${BCM_SETSHIELD} 0 0 ; hide SHIELD${endif}${endif}SendMessage $RadioButtonLabel1 ${WM_SETTEXT} 0 "STR:$7"FunctionEnd!macroend