MultiUser.nsh 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486
  1. /*
  2. MultiUser.nsh
  3. Installer configuration for multi-user Windows environments
  4. Copyright 2008-2018 Joost Verburg
  5. */
  6. !ifndef MULTIUSER_INCLUDED
  7. !define MULTIUSER_INCLUDED
  8. !verbose push
  9. !verbose 3
  10. ;Standard NSIS header files
  11. !ifdef MULTIUSER_MUI
  12. !include MUI2.nsh
  13. !endif
  14. !include nsDialogs.nsh
  15. !include LogicLib.nsh
  16. !include WinVer.nsh
  17. !include FileFunc.nsh
  18. ;Variables
  19. Var MultiUser.Privileges
  20. Var MultiUser.InstallMode
  21. ;Command line installation mode setting
  22. !ifdef MULTIUSER_INSTALLMODE_COMMANDLINE
  23. !include StrFunc.nsh
  24. !ifndef StrStr_INCLUDED
  25. ${StrStr}
  26. !endif
  27. !ifndef MULTIUSER_NOUNINSTALL
  28. !ifndef UnStrStr_INCLUDED
  29. ${UnStrStr}
  30. !endif
  31. !endif
  32. Var MultiUser.Parameters
  33. Var MultiUser.Result
  34. !endif
  35. ;Installation folder stored in registry
  36. !ifdef MULTIUSER_INSTALLMODE_INSTDIR_REGISTRY_KEY & MULTIUSER_INSTALLMODE_INSTDIR_REGISTRY_VALUENAME
  37. Var MultiUser.InstDir
  38. !endif
  39. !ifdef MULTIUSER_INSTALLMODE_DEFAULT_REGISTRY_KEY & MULTIUSER_INSTALLMODE_DEFAULT_REGISTRY_VALUENAME
  40. Var MultiUser.DefaultKeyValue
  41. !endif
  42. ;Windows Vista UAC setting
  43. !if "${MULTIUSER_EXECUTIONLEVEL}" == Admin
  44. RequestExecutionLevel admin
  45. !define MULTIUSER_EXECUTIONLEVEL_ALLUSERS
  46. !else if "${MULTIUSER_EXECUTIONLEVEL}" == Power
  47. RequestExecutionLevel admin
  48. !define MULTIUSER_EXECUTIONLEVEL_ALLUSERS
  49. !else if "${MULTIUSER_EXECUTIONLEVEL}" == Highest
  50. RequestExecutionLevel highest
  51. !define MULTIUSER_EXECUTIONLEVEL_ALLUSERS
  52. !else
  53. RequestExecutionLevel user
  54. !ifndef MULTIUSER_EXECUTIONLEVEL
  55. !warning "MULTIUSER_EXECUTIONLEVEL not set!"
  56. !endif
  57. !endif
  58. /*
  59. Install modes
  60. */
  61. !macro MULTIUSER_INSTALLMODE_ALLUSERS UNINSTALLER_PREFIX UNINSTALLER_FUNCPREFIX
  62. ;Install mode initialization - per-machine
  63. ${ifnot} ${IsNT}
  64. ${orif} $MultiUser.Privileges == "Admin"
  65. ${orif} $MultiUser.Privileges == "Power"
  66. StrCpy $MultiUser.InstallMode AllUsers
  67. SetShellVarContext all
  68. !if "${UNINSTALLER_PREFIX}" != UN
  69. ;Set default installation location for installer
  70. !ifdef MULTIUSER_INSTALLMODE_INSTDIR
  71. !ifdef MULTIUSER_USE_PROGRAMFILES64
  72. StrCpy $INSTDIR "$PROGRAMFILES64\${MULTIUSER_INSTALLMODE_INSTDIR}"
  73. !else
  74. StrCpy $INSTDIR "$PROGRAMFILES\${MULTIUSER_INSTALLMODE_INSTDIR}"
  75. !endif
  76. !endif
  77. !endif
  78. !ifdef MULTIUSER_INSTALLMODE_INSTDIR_REGISTRY_KEY & MULTIUSER_INSTALLMODE_INSTDIR_REGISTRY_VALUENAME
  79. ReadRegStr $MultiUser.InstDir HKLM "${MULTIUSER_INSTALLMODE_INSTDIR_REGISTRY_KEY}" "${MULTIUSER_INSTALLMODE_INSTDIR_REGISTRY_VALUENAME}"
  80. ${if} $MultiUser.InstDir != ""
  81. StrCpy $INSTDIR $MultiUser.InstDir
  82. ${endif}
  83. !endif
  84. !ifdef MULTIUSER_INSTALLMODE_${UNINSTALLER_PREFIX}FUNCTION
  85. Call "${MULTIUSER_INSTALLMODE_${UNINSTALLER_PREFIX}FUNCTION}"
  86. !endif
  87. ${endif}
  88. !macroend
  89. !macro MULTIUSER_INSTALLMODE_CURRENTUSER UNINSTALLER_PREFIX UNINSTALLER_FUNCPREFIX
  90. ;Install mode initialization - per-user
  91. ${if} ${IsNT}
  92. StrCpy $MultiUser.InstallMode CurrentUser
  93. SetShellVarContext current
  94. !if "${UNINSTALLER_PREFIX}" != UN
  95. ;Set default installation location for installer
  96. !ifdef MULTIUSER_INSTALLMODE_INSTDIR
  97. ${if} ${AtLeastWin2000}
  98. StrCpy $INSTDIR "$LOCALAPPDATA\${MULTIUSER_INSTALLMODE_INSTDIR}"
  99. ${else}
  100. StrCpy $INSTDIR "$PROGRAMFILES\${MULTIUSER_INSTALLMODE_INSTDIR}"
  101. ${endif}
  102. !endif
  103. !endif
  104. !ifdef MULTIUSER_INSTALLMODE_INSTDIR_REGISTRY_KEY & MULTIUSER_INSTALLMODE_INSTDIR_REGISTRY_VALUENAME
  105. ReadRegStr $MultiUser.InstDir HKCU "${MULTIUSER_INSTALLMODE_INSTDIR_REGISTRY_KEY}" "${MULTIUSER_INSTALLMODE_INSTDIR_REGISTRY_VALUENAME}"
  106. ${if} $MultiUser.InstDir != ""
  107. StrCpy $INSTDIR $MultiUser.InstDir
  108. ${endif}
  109. !endif
  110. !ifdef MULTIUSER_INSTALLMODE_${UNINSTALLER_PREFIX}FUNCTION
  111. Call "${MULTIUSER_INSTALLMODE_${UNINSTALLER_PREFIX}FUNCTION}"
  112. !endif
  113. ${endif}
  114. !macroend
  115. Function MultiUser.InstallMode.AllUsers
  116. !insertmacro MULTIUSER_INSTALLMODE_ALLUSERS "" ""
  117. FunctionEnd
  118. Function MultiUser.InstallMode.CurrentUser
  119. !insertmacro MULTIUSER_INSTALLMODE_CURRENTUSER "" ""
  120. FunctionEnd
  121. !ifndef MULTIUSER_NOUNINSTALL
  122. Function un.MultiUser.InstallMode.AllUsers
  123. !insertmacro MULTIUSER_INSTALLMODE_ALLUSERS UN .un
  124. FunctionEnd
  125. Function un.MultiUser.InstallMode.CurrentUser
  126. !insertmacro MULTIUSER_INSTALLMODE_CURRENTUSER UN .un
  127. FunctionEnd
  128. !endif
  129. /*
  130. Installer/uninstaller initialization
  131. */
  132. !macro MULTIUSER_INIT_QUIT UNINSTALLER_FUNCPREFIX
  133. !ifdef MULTIUSER_INIT_${UNINSTALLER_FUNCPREFIX}FUNCTIONQUIT
  134. Call "${MULTIUSER_INIT_${UNINSTALLER_FUNCPREFIX}FUCTIONQUIT}
  135. !else
  136. Quit
  137. !endif
  138. !macroend
  139. !macro MULTIUSER_INIT_TEXTS UNINSTALLER_PREFIX
  140. !if "${UNINSTALLER_PREFIX}" == ""
  141. !define /ReDef MULTIUSER_TMPSTR_CAPTION "$(^SetupCaption)"
  142. !else
  143. !define /ReDef MULTIUSER_TMPSTR_CAPTION "$(^Name)"
  144. !endif
  145. !ifndef MULTIUSER_INIT_TEXT_ADMINREQUIRED
  146. !define MULTIUSER_INIT_TEXT_ADMINREQUIRED "${MULTIUSER_TMPSTR_CAPTION} requires administrator privileges."
  147. !endif
  148. !ifndef MULTIUSER_INIT_TEXT_POWERREQUIRED
  149. !define MULTIUSER_INIT_TEXT_POWERREQUIRED "${MULTIUSER_TMPSTR_CAPTION} requires at least Power User privileges."
  150. !endif
  151. !ifndef MULTIUSER_INIT_TEXT_ALLUSERSNOTPOSSIBLE
  152. !define MULTIUSER_INIT_TEXT_ALLUSERSNOTPOSSIBLE "Your user account does not have sufficient privileges to install $(^Name) for all users of this computer."
  153. !endif
  154. !undef MULTIUSER_TMPSTR_CAPTION
  155. !macroend
  156. !macro MULTIUSER_INIT_CHECKS UNINSTALLER_PREFIX UNINSTALLER_FUNCPREFIX
  157. ;Installer initialization - check privileges and set install mode
  158. !insertmacro MULTIUSER_INIT_TEXTS "${UNINSTALLER_PREFIX}"
  159. UserInfo::GetAccountType
  160. Pop $MultiUser.Privileges
  161. ${if} ${IsNT}
  162. ;Check privileges
  163. !if "${MULTIUSER_EXECUTIONLEVEL}" == Admin
  164. ${if} $MultiUser.Privileges != "Admin"
  165. MessageBox MB_OK|MB_ICONSTOP "${MULTIUSER_INIT_TEXT_ADMINREQUIRED}"
  166. !insertmacro MULTIUSER_INIT_QUIT "${UNINSTALLER_FUNCPREFIX}"
  167. ${endif}
  168. !else if "${MULTIUSER_EXECUTIONLEVEL}" == Power
  169. ${if} $MultiUser.Privileges != "Power"
  170. ${andif} $MultiUser.Privileges != "Admin"
  171. ${if} ${AtMostWinXP}
  172. MessageBox MB_OK|MB_ICONSTOP "${MULTIUSER_INIT_TEXT_POWERREQUIRED}"
  173. ${else}
  174. MessageBox MB_OK|MB_ICONSTOP "${MULTIUSER_INIT_TEXT_ADMINREQUIRED}"
  175. ${endif}
  176. !insertmacro MULTIUSER_INIT_QUIT "${UNINSTALLER_FUNCPREFIX}"
  177. ${endif}
  178. !endif
  179. !ifdef MULTIUSER_EXECUTIONLEVEL_ALLUSERS
  180. ;Default to per-machine installation if possible
  181. ${if} $MultiUser.Privileges == "Admin"
  182. ${orif} $MultiUser.Privileges == "Power"
  183. !ifndef MULTIUSER_INSTALLMODE_DEFAULT_CURRENTUSER
  184. Call ${UNINSTALLER_FUNCPREFIX}MultiUser.InstallMode.AllUsers
  185. !else
  186. Call ${UNINSTALLER_FUNCPREFIX}MultiUser.InstallMode.CurrentUser
  187. !endif
  188. !ifdef MULTIUSER_INSTALLMODE_DEFAULT_REGISTRY_KEY & MULTIUSER_INSTALLMODE_DEFAULT_REGISTRY_VALUENAME
  189. ;Set installation mode to setting from a previous installation
  190. !ifndef MULTIUSER_INSTALLMODE_DEFAULT_CURRENTUSER
  191. ReadRegStr $MultiUser.DefaultKeyValue HKLM "${MULTIUSER_INSTALLMODE_DEFAULT_REGISTRY_KEY}" "${MULTIUSER_INSTALLMODE_DEFAULT_REGISTRY_VALUENAME}"
  192. ${if} $MultiUser.DefaultKeyValue == ""
  193. ReadRegStr $MultiUser.DefaultKeyValue HKCU "${MULTIUSER_INSTALLMODE_DEFAULT_REGISTRY_KEY}" "${MULTIUSER_INSTALLMODE_DEFAULT_REGISTRY_VALUENAME}"
  194. ${if} $MultiUser.DefaultKeyValue != ""
  195. Call ${UNINSTALLER_FUNCPREFIX}MultiUser.InstallMode.CurrentUser
  196. ${endif}
  197. ${endif}
  198. !else
  199. ReadRegStr $MultiUser.DefaultKeyValue HKCU "${MULTIUSER_INSTALLMODE_DEFAULT_REGISTRY_KEY}" "${MULTIUSER_INSTALLMODE_DEFAULT_REGISTRY_VALUENAME}"
  200. ${if} $MultiUser.DefaultKeyValue == ""
  201. ReadRegStr $MultiUser.DefaultKeyValue HKLM "${MULTIUSER_INSTALLMODE_DEFAULT_REGISTRY_KEY}" "${MULTIUSER_INSTALLMODE_DEFAULT_REGISTRY_VALUENAME}"
  202. ${if} $MultiUser.DefaultKeyValue != ""
  203. Call ${UNINSTALLER_FUNCPREFIX}MultiUser.InstallMode.AllUsers
  204. ${endif}
  205. ${endif}
  206. !endif
  207. !endif
  208. ${else}
  209. Call ${UNINSTALLER_FUNCPREFIX}MultiUser.InstallMode.CurrentUser
  210. ${endif}
  211. !else
  212. Call ${UNINSTALLER_FUNCPREFIX}MultiUser.InstallMode.CurrentUser
  213. !endif
  214. !ifdef MULTIUSER_INSTALLMODE_COMMANDLINE
  215. ;Check for install mode setting on command line
  216. ${${UNINSTALLER_FUNCPREFIX}GetParameters} $MultiUser.Parameters
  217. ${${UNINSTALLER_PREFIX}StrStr} $MultiUser.Result $MultiUser.Parameters "/CurrentUser"
  218. ${if} $MultiUser.Result != ""
  219. Call ${UNINSTALLER_FUNCPREFIX}MultiUser.InstallMode.CurrentUser
  220. ${endif}
  221. ${${UNINSTALLER_PREFIX}StrStr} $MultiUser.Result $MultiUser.Parameters "/AllUsers"
  222. ${if} $MultiUser.Result != ""
  223. ${if} $MultiUser.Privileges == "Admin"
  224. ${orif} $MultiUser.Privileges == "Power"
  225. Call ${UNINSTALLER_FUNCPREFIX}MultiUser.InstallMode.AllUsers
  226. ${else}
  227. MessageBox MB_OK|MB_ICONSTOP "${MULTIUSER_INIT_TEXT_ALLUSERSNOTPOSSIBLE}"
  228. ${endif}
  229. ${endif}
  230. !endif
  231. !if ${NSIS_PTR_SIZE} <= 4
  232. ${else}
  233. ;Not running Windows NT, per-user installation not supported
  234. Call ${UNINSTALLER_FUNCPREFIX}MultiUser.InstallMode.AllUsers
  235. !endif
  236. ${endif}
  237. !macroend
  238. !macro MULTIUSER_INIT
  239. !verbose push
  240. !verbose 3
  241. !insertmacro MULTIUSER_INIT_CHECKS "" ""
  242. !verbose pop
  243. !macroend
  244. !ifndef MULTIUSER_NOUNINSTALL
  245. !macro MULTIUSER_UNINIT
  246. !verbose push
  247. !verbose 3
  248. !insertmacro MULTIUSER_INIT_CHECKS Un un.
  249. !verbose pop
  250. !macroend
  251. !endif
  252. /*
  253. Modern UI 2 page
  254. */
  255. !ifdef MULTIUSER_MUI
  256. !macro MULTIUSER_INSTALLMODEPAGE_INTERFACE
  257. !ifndef MULTIUSER_INSTALLMODEPAGE_INTERFACE
  258. !define MULTIUSER_INSTALLMODEPAGE_INTERFACE
  259. Var MultiUser.InstallModePage
  260. Var MultiUser.InstallModePage.Text
  261. Var MultiUser.InstallModePage.AllUsers
  262. Var MultiUser.InstallModePage.CurrentUser
  263. Var MultiUser.InstallModePage.ReturnValue
  264. !endif
  265. !macroend
  266. !macro MULTIUSER_PAGEDECLARATION_INSTALLMODE
  267. !insertmacro MUI_SET MULTIUSER_${MUI_PAGE_UNINSTALLER_PREFIX}INSTALLMODEPAGE ""
  268. !insertmacro MULTIUSER_INSTALLMODEPAGE_INTERFACE
  269. !insertmacro MUI_DEFAULT MULTIUSER_INSTALLMODEPAGE_TEXT_TOP "$(MULTIUSER_INNERTEXT_INSTALLMODE_TOP)"
  270. !insertmacro MUI_DEFAULT MULTIUSER_INSTALLMODEPAGE_TEXT_ALLUSERS "$(MULTIUSER_INNERTEXT_INSTALLMODE_ALLUSERS)"
  271. !insertmacro MUI_DEFAULT MULTIUSER_INSTALLMODEPAGE_TEXT_CURRENTUSER "$(MULTIUSER_INNERTEXT_INSTALLMODE_CURRENTUSER)"
  272. PageEx custom
  273. PageCallbacks MultiUser.InstallModePre_${MUI_UNIQUEID} MultiUser.InstallModeLeave_${MUI_UNIQUEID}
  274. Caption " "
  275. PageExEnd
  276. !insertmacro MULTIUSER_FUNCTION_INSTALLMODEPAGE MultiUser.InstallModePre_${MUI_UNIQUEID} MultiUser.InstallModeLeave_${MUI_UNIQUEID}
  277. !undef MULTIUSER_INSTALLMODEPAGE_TEXT_TOP
  278. !undef MULTIUSER_INSTALLMODEPAGE_TEXT_ALLUSERS
  279. !undef MULTIUSER_INSTALLMODEPAGE_TEXT_CURRENTUSER
  280. !macroend
  281. !macro MULTIUSER_PAGE_INSTALLMODE
  282. ;Modern UI page for install mode
  283. !verbose push
  284. !verbose 3
  285. !ifndef MULTIUSER_EXECUTIONLEVEL_ALLUSERS
  286. !error "A mixed-mode installation requires MULTIUSER_EXECUTIONLEVEL to be set to Admin, Power or Highest."
  287. !endif
  288. !insertmacro MUI_PAGE_INIT
  289. !insertmacro MULTIUSER_PAGEDECLARATION_INSTALLMODE
  290. !verbose pop
  291. !macroend
  292. !macro MULTIUSER_FUNCTION_INSTALLMODEPAGE PRE LEAVE
  293. ;Page functions of Modern UI page
  294. Function "${PRE}"
  295. ${ifnot} ${IsNT}
  296. Abort
  297. ${endif}
  298. ${if} $MultiUser.Privileges != "Power"
  299. ${andif} $MultiUser.Privileges != "Admin"
  300. Abort
  301. ${endif}
  302. !insertmacro MUI_PAGE_FUNCTION_CUSTOM PRE
  303. !insertmacro MUI_HEADER_TEXT_PAGE $(MULTIUSER_TEXT_INSTALLMODE_TITLE) $(MULTIUSER_TEXT_INSTALLMODE_SUBTITLE)
  304. nsDialogs::Create 1018
  305. Pop $MultiUser.InstallModePage
  306. ${NSD_CreateLabel} 0u 0u 300u 40u "${MULTIUSER_INSTALLMODEPAGE_TEXT_TOP}"
  307. Pop $MultiUser.InstallModePage.Text
  308. ${NSD_CreateRadioButton} 20u 50u 280u 10u "${MULTIUSER_INSTALLMODEPAGE_TEXT_ALLUSERS}"
  309. Pop $MultiUser.InstallModePage.AllUsers
  310. ${NSD_CreateRadioButton} 20u 70u 280u 10u "${MULTIUSER_INSTALLMODEPAGE_TEXT_CURRENTUSER}"
  311. Pop $MultiUser.InstallModePage.CurrentUser
  312. ${if} $MultiUser.InstallMode == "AllUsers"
  313. SendMessage $MultiUser.InstallModePage.AllUsers ${BM_SETCHECK} ${BST_CHECKED} 0
  314. ${else}
  315. SendMessage $MultiUser.InstallModePage.CurrentUser ${BM_SETCHECK} ${BST_CHECKED} 0
  316. ${endif}
  317. !insertmacro MUI_PAGE_FUNCTION_CUSTOM SHOW
  318. nsDialogs::Show
  319. !insertmacro MUI_PAGE_FUNCTION_CUSTOM DESTROYED
  320. FunctionEnd
  321. Function "${LEAVE}"
  322. SendMessage $MultiUser.InstallModePage.AllUsers ${BM_GETCHECK} 0 0 $MultiUser.InstallModePage.ReturnValue
  323. ${if} $MultiUser.InstallModePage.ReturnValue = ${BST_CHECKED}
  324. Call MultiUser.InstallMode.AllUsers
  325. ${else}
  326. Call MultiUser.InstallMode.CurrentUser
  327. ${endif}
  328. !insertmacro MUI_PAGE_FUNCTION_CUSTOM LEAVE
  329. FunctionEnd
  330. !macroend
  331. !endif
  332. !verbose pop
  333. !endif