multiUserUi.nsh 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
  1. !include nsDialogs.nsh
  2. Var HasTwoAvailableOptions
  3. Var RadioButtonLabel1
  4. Var isForceMachineInstall
  5. Var isForceCurrentInstall
  6. !macro PAGE_INSTALL_MODE
  7. !insertmacro MUI_PAGE_INIT
  8. !insertmacro MUI_SET MULTIUSER_${MUI_PAGE_UNINSTALLER_PREFIX}INSTALLMODEPAGE ""
  9. Var MultiUser.InstallModePage
  10. Var MultiUser.InstallModePage.Text
  11. Var MultiUser.InstallModePage.AllUsers
  12. Var MultiUser.InstallModePage.CurrentUser
  13. Var MultiUser.InstallModePage.ReturnValue
  14. !ifndef BUILD_UNINSTALLER
  15. !insertmacro FUNCTION_INSTALL_MODE_PAGE_FUNCTION MultiUser.InstallModePre_${MUI_UNIQUEID} MultiUser.InstallModeLeave_${MUI_UNIQUEID} ""
  16. PageEx custom
  17. PageCallbacks MultiUser.InstallModePre_${MUI_UNIQUEID} MultiUser.InstallModeLeave_${MUI_UNIQUEID}
  18. Caption " "
  19. PageExEnd
  20. !else
  21. !insertmacro FUNCTION_INSTALL_MODE_PAGE_FUNCTION MultiUser.InstallModePre_${MUI_UNIQUEID} MultiUser.InstallModeLeave_${MUI_UNIQUEID} un.
  22. UninstPage custom un.multiUser.InstallModePre_${MUI_UNIQUEID} un.MultiUser.InstallModeLeave_${MUI_UNIQUEID}
  23. !endif
  24. !macroend
  25. !macro FUNCTION_INSTALL_MODE_PAGE_FUNCTION PRE LEAVE UNINSTALLER_FUNCPREFIX
  26. Function "${UNINSTALLER_FUNCPREFIX}${PRE}"
  27. ${if} ${UAC_IsInnerInstance}
  28. ${andIf} ${UAC_IsAdmin}
  29. # inner Process (and Admin) - skip selection, inner process is always used for elevation (machine-wide)
  30. !insertmacro setInstallModePerAllUsers
  31. Abort
  32. ${endIf}
  33. StrCpy $isForceMachineInstall "0"
  34. StrCpy $isForceCurrentInstall "0"
  35. !ifmacrodef customInstallmode
  36. !insertmacro customInstallMode
  37. !endif
  38. ${if} $isForceMachineInstall == "1"
  39. ${OrIf} ${isForAllUsers}
  40. StrCpy $hasPerMachineInstallation "1"
  41. StrCpy $hasPerUserInstallation "0"
  42. ${ifNot} ${UAC_IsAdmin}
  43. ShowWindow $HWNDPARENT ${SW_HIDE}
  44. !insertmacro UAC_RunElevated
  45. Quit
  46. ${endIf}
  47. !insertmacro setInstallModePerAllUsers
  48. Abort
  49. ${endIf}
  50. ${if} $isForceCurrentInstall == "1"
  51. ${OrIf} ${isForCurrentUser}
  52. StrCpy $hasPerMachineInstallation "0"
  53. StrCpy $hasPerUserInstallation "1"
  54. !insertmacro setInstallModePerUser
  55. Abort
  56. ${endIf}
  57. # If uninstalling, will check if there is both a per-user and per-machine installation. If there is only one, will skip the form.
  58. # If uninstallation was invoked from the "add/remove programs" Windows will automatically requests elevation (depending if uninstall keys are in HKLM or HKCU)
  59. # 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
  60. !ifdef BUILD_UNINSTALLER
  61. ${if} $hasPerUserInstallation == "1"
  62. ${andif} $hasPerMachineInstallation == "0"
  63. !insertmacro setInstallModePerUser
  64. Abort
  65. ${elseIf} $hasPerUserInstallation == "0"
  66. ${andIf} $hasPerMachineInstallation == "1"
  67. ${IfNot} ${UAC_IsAdmin}
  68. ShowWindow $HWNDPARENT ${SW_HIDE}
  69. !insertmacro UAC_RunElevated
  70. Quit
  71. ${endIf}
  72. !insertmacro setInstallModePerAllUsers
  73. Abort
  74. ${endIf}
  75. !insertmacro MUI_HEADER_TEXT "$(chooseUninstallationOptions)" "$(whichInstallationShouldBeRemoved)"
  76. !else
  77. !insertmacro MUI_HEADER_TEXT "$(chooseInstallationOptions)" "$(whoShouldThisApplicationBeInstalledFor)"
  78. !endif
  79. !insertmacro MUI_PAGE_FUNCTION_CUSTOM PRE
  80. nsDialogs::Create 1018
  81. Pop $MultiUser.InstallModePage
  82. !ifndef BUILD_UNINSTALLER
  83. ${NSD_CreateLabel} 0u 0u 300u 20u "$(selectUserMode)"
  84. StrCpy $8 "$(forAll)"
  85. StrCpy $9 "$(onlyForMe)"
  86. !else
  87. ${NSD_CreateLabel} 0u 0u 300u 20u "$(whichInstallationRemove)"
  88. StrCpy $8 "$(forAll)"
  89. StrCpy $9 "$(onlyForMe)"
  90. !endif
  91. Pop $MultiUser.InstallModePage.Text
  92. ${NSD_CreateRadioButton} 10u 30u 280u 20u "$8"
  93. Pop $MultiUser.InstallModePage.AllUsers
  94. ${IfNot} ${UAC_IsAdmin}
  95. !ifdef MULTIUSER_INSTALLMODE_ALLOW_ELEVATION
  96. StrCpy $HasTwoAvailableOptions 1
  97. !else
  98. # since radio button is disabled, we add that comment to the disabled control itself
  99. SendMessage $MultiUser.InstallModePage.AllUsers ${WM_SETTEXT} 0 "STR:$8 (must run as admin)"
  100. EnableWindow $MultiUser.InstallModePage.AllUsers 0 # start out disabled
  101. StrCpy $HasTwoAvailableOptions 0
  102. !endif
  103. ${else}
  104. StrCpy $HasTwoAvailableOptions 1
  105. ${endif}
  106. System::Call "advapi32::GetUserName(t.r0,*i${NSIS_MAX_STRLEN})i"
  107. ${NSD_CreateRadioButton} 10u 50u 280u 20u "$9 ($0)"
  108. Pop $MultiUser.InstallModePage.CurrentUser
  109. nsDialogs::SetUserData $MultiUser.InstallModePage.AllUsers 1 ; Install for All Users (1, pra exibir o icone SHIELD de elevation)
  110. nsDialogs::SetUserData $MultiUser.InstallModePage.CurrentUser 0 ; Install for Single User (0 pra não exibir)
  111. ${if} $HasTwoAvailableOptions == "1" ; if there are 2 available options, bind to radiobutton change
  112. ${NSD_OnClick} $MultiUser.InstallModePage.CurrentUser ${UNINSTALLER_FUNCPREFIX}InstModeChange
  113. ${NSD_OnClick} $MultiUser.InstallModePage.AllUsers ${UNINSTALLER_FUNCPREFIX}InstModeChange
  114. ${endif}
  115. ${NSD_CreateLabel} 0u 110u 280u 50u ""
  116. Pop $RadioButtonLabel1
  117. ${if} $installMode == "all"
  118. SendMessage $MultiUser.InstallModePage.AllUsers ${BM_SETCHECK} ${BST_CHECKED} 0 ; set as default
  119. SendMessage $MultiUser.InstallModePage.AllUsers ${BM_CLICK} 0 0 ; trigger click event
  120. ${else}
  121. SendMessage $MultiUser.InstallModePage.CurrentUser ${BM_SETCHECK} ${BST_CHECKED} 0 ; set as default
  122. SendMessage $MultiUser.InstallModePage.CurrentUser ${BM_CLICK} 0 0 ; trigger click event
  123. ${endif}
  124. !insertmacro MUI_PAGE_FUNCTION_CUSTOM SHOW
  125. nsDialogs::Show
  126. FunctionEnd
  127. Function "${UNINSTALLER_FUNCPREFIX}${LEAVE}"
  128. SendMessage $MultiUser.InstallModePage.AllUsers ${BM_GETCHECK} 0 0 $MultiUser.InstallModePage.ReturnValue
  129. ${if} $MultiUser.InstallModePage.ReturnValue = ${BST_CHECKED}
  130. ${IfNot} ${UAC_IsAdmin}
  131. ShowWindow $HWNDPARENT ${SW_HIDE}
  132. !insertmacro UAC_RunElevated
  133. ${Switch} $0
  134. ${Case} 0
  135. ${If} $1 = 1
  136. Quit ;we are the outer process, the inner process has done its work (ExitCode is $2), we are done
  137. ${EndIf}
  138. ${If} $1 = 3 ;RunAs completed successfully, but with a non-admin user
  139. ${OrIf} $2 = 0x666666 ;our special return, the new process was not admin after all
  140. MessageBox mb_IconStop|mb_TopMost|mb_SetForeground "$(loginWithAdminAccount)"
  141. ${EndIf}
  142. ${Break}
  143. ${Case} 1223 ;user aborted
  144. ;MessageBox mb_IconStop|mb_TopMost|mb_SetForeground "This option requires admin privileges, aborting!"
  145. ;Quit ; instead of quit just abort going to the next page, and stay in the radiobuttons
  146. ${Break}
  147. ${Case} 1062
  148. MessageBox mb_IconStop|mb_TopMost|mb_SetForeground "Logon service not running, aborting!" ; "Unable to elevate, Secondary Logon service not running!"
  149. ;Quit ; instead of quit just abort going to the next page, and stay in the radiobuttons
  150. ${Break}
  151. ${Default}
  152. MessageBox mb_IconStop|mb_TopMost|mb_SetForeground "Unable to elevate, error $0"
  153. ;Quit ; instead of quit just abort going to the next page, and stay in the radiobuttons
  154. ${Break}
  155. ${EndSwitch}
  156. ShowWindow $HWNDPARENT ${SW_SHOW}
  157. BringToFront
  158. Abort
  159. ${else}
  160. !insertmacro setInstallModePerAllUsers
  161. ${endif}
  162. ${else}
  163. !insertmacro setInstallModePerUser
  164. ${endif}
  165. !insertmacro MUI_PAGE_FUNCTION_CUSTOM LEAVE
  166. FunctionEnd
  167. Function "${UNINSTALLER_FUNCPREFIX}InstModeChange"
  168. pop $1
  169. nsDialogs::GetUserData $1
  170. pop $1
  171. GetDlgItem $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 )
  172. StrCpy $7 ""
  173. ${if} "$1" == "0" ; current user
  174. ${if} $hasPerUserInstallation == "1"
  175. !ifndef BUILD_UNINSTALLER
  176. StrCpy $7 "$(perUserInstallExists)($perUserInstallationFolder)$\r$\n$(reinstallUpgrade)"
  177. !else
  178. StrCpy $7 "$(perUserInstall)($perUserInstallationFolder)$\r$\n$(uninstall)"
  179. !endif
  180. ${else}
  181. StrCpy $7 "$(freshInstallForCurrent)"
  182. ${endif}
  183. SendMessage $0 ${BCM_SETSHIELD} 0 0 ; hide SHIELD
  184. ${else} ; all users
  185. ${if} $hasPerMachineInstallation == "1"
  186. !ifndef BUILD_UNINSTALLER
  187. StrCpy $7 "$(perMachineInstallExists)($perMachineInstallationFolder)$\r$\n$(reinstallUpgrade)"
  188. !else
  189. StrCpy $7 "$(perMachineInstall)($perMachineInstallationFolder)$\r$\n$(uninstall)"
  190. !endif
  191. ${else}
  192. StrCpy $7 "$(freshInstallForAll)"
  193. ${endif}
  194. ${ifNot} ${UAC_IsAdmin}
  195. StrCpy $7 "$7"
  196. SendMessage $0 ${BCM_SETSHIELD} 0 1 ; display SHIELD
  197. ${else}
  198. SendMessage $0 ${BCM_SETSHIELD} 0 0 ; hide SHIELD
  199. ${endif}
  200. ${endif}
  201. SendMessage $RadioButtonLabel1 ${WM_SETTEXT} 0 "STR:$7"
  202. FunctionEnd
  203. !macroend