5 Installer configuration for multi-user Windows environments
7 Copyright 2008-2009 Joost Verburg
8 Updated 2016 by H. Peter Anvin to handle 64-bit Windows
12 !ifndef MULTIUSER_INCLUDED
13 !define MULTIUSER_INCLUDED
17 ;Standard NSIS header files
22 !include nsDialogs.nsh
29 Var MultiUser.Privileges
30 Var MultiUser.InstallMode
32 ;Command line installation mode setting
34 !ifdef MULTIUSER_INSTALLMODE_COMMANDLINE
36 !ifndef StrStr_INCLUDED
39 !ifndef MULTIUSER_NOUNINSTALL
40 !ifndef UnStrStr_INCLUDED
45 Var MultiUser.Parameters
49 ;Installation folder stored in registry
51 !ifdef MULTIUSER_INSTALLMODE_INSTDIR_REGISTRY_KEY & MULTIUSER_INSTALLMODE_INSTDIR_REGISTRY_VALUENAME
55 !ifdef MULTIUSER_INSTALLMODE_DEFAULT_REGISTRY_KEY & MULTIUSER_INSTALLMODE_DEFAULT_REGISTRY_VALUENAME
56 Var MultiUser.DefaultKeyValue
59 ;Windows Vista UAC setting
61 !if "${MULTIUSER_EXECUTIONLEVEL}" == Admin
62 RequestExecutionLevel admin
63 !define MULTIUSER_EXECUTIONLEVEL_ALLUSERS
64 !else if "${MULTIUSER_EXECUTIONLEVEL}" == Power
65 RequestExecutionLevel admin
66 !define MULTIUSER_EXECUTIONLEVEL_ALLUSERS
67 !else if "${MULTIUSER_EXECUTIONLEVEL}" == Highest
68 RequestExecutionLevel highest
69 !define MULTIUSER_EXECUTIONLEVEL_ALLUSERS
71 RequestExecutionLevel user
80 !macro MULTIUSER_INSTALLMODE_ALLUSERS UNINSTALLER_PREFIX UNINSTALLER_FUNCPREFIX
82 ;Install mode initialization - per-machine
85 ${orif} $MultiUser.Privileges == "Admin"
86 ${orif} $MultiUser.Privileges == "Power"
88 StrCpy $MultiUser.InstallMode AllUsers
90 SetShellVarContext all
92 !if "${UNINSTALLER_PREFIX}" != UN
93 ;Set default installation location for installer
94 !ifdef MULTIUSER_INSTALLMODE_INSTDIR
95 StrCpy $INSTDIR "${GLOBALINSTDIR}\${MULTIUSER_INSTALLMODE_INSTDIR}"
99 !ifdef MULTIUSER_INSTALLMODE_INSTDIR_REGISTRY_KEY & MULTIUSER_INSTALLMODE_INSTDIR_REGISTRY_VALUENAME
101 ReadRegStr $MultiUser.InstDir HKLM "${MULTIUSER_INSTALLMODE_INSTDIR_REGISTRY_KEY}" "${MULTIUSER_INSTALLMODE_INSTDIR_REGISTRY_VALUENAME}"
103 ${if} $MultiUser.InstDir != ""
104 StrCpy $INSTDIR $MultiUser.InstDir
109 !ifdef MULTIUSER_INSTALLMODE_${UNINSTALLER_PREFIX}FUNCTION
110 Call "${MULTIUSER_INSTALLMODE_${UNINSTALLER_PREFIX}FUNCTION}"
117 !macro MULTIUSER_INSTALLMODE_CURRENTUSER UNINSTALLER_PREFIX UNINSTALLER_FUNCPREFIX
119 ;Install mode initialization - per-user
123 StrCpy $MultiUser.InstallMode CurrentUser
125 SetShellVarContext current
127 !if "${UNINSTALLER_PREFIX}" != UN
128 ;Set default installation location for installer
129 !ifdef MULTIUSER_INSTALLMODE_INSTDIR
130 ${if} ${AtLeastWin2000}
131 StrCpy $INSTDIR "$LOCALAPPDATA\bin\${MULTIUSER_INSTALLMODE_INSTDIR}"
133 StrCpy $INSTDIR "${GLOBALINSTDIR}\${MULTIUSER_INSTALLMODE_INSTDIR}"
138 !ifdef MULTIUSER_INSTALLMODE_INSTDIR_REGISTRY_KEY & MULTIUSER_INSTALLMODE_INSTDIR_REGISTRY_VALUENAME
140 ReadRegStr $MultiUser.InstDir HKCU "${MULTIUSER_INSTALLMODE_INSTDIR_REGISTRY_KEY}" "${MULTIUSER_INSTALLMODE_INSTDIR_REGISTRY_VALUENAME}"
142 ${if} $MultiUser.InstDir != ""
143 StrCpy $INSTDIR $MultiUser.InstDir
148 !ifdef MULTIUSER_INSTALLMODE_${UNINSTALLER_PREFIX}FUNCTION
149 Call "${MULTIUSER_INSTALLMODE_${UNINSTALLER_PREFIX}FUNCTION}"
156 Function MultiUser.InstallMode.AllUsers
157 !insertmacro MULTIUSER_INSTALLMODE_ALLUSERS "" ""
160 Function MultiUser.InstallMode.CurrentUser
161 !insertmacro MULTIUSER_INSTALLMODE_CURRENTUSER "" ""
164 !ifndef MULTIUSER_NOUNINSTALL
166 Function un.MultiUser.InstallMode.AllUsers
167 !insertmacro MULTIUSER_INSTALLMODE_ALLUSERS UN .un
170 Function un.MultiUser.InstallMode.CurrentUser
171 !insertmacro MULTIUSER_INSTALLMODE_CURRENTUSER UN .un
178 Installer/uninstaller initialization
182 !macro MULTIUSER_INIT_QUIT UNINSTALLER_FUNCPREFIX
184 !ifdef MULTIUSER_INIT_${UNINSTALLER_FUNCPREFIX}FUNCTIONQUIT
185 Call "${MULTIUSER_INIT_${UNINSTALLER_FUNCPREFIX}FUCTIONQUIT}
192 !macro MULTIUSER_INIT_TEXTS
194 !ifndef MULTIUSER_INIT_TEXT_ADMINREQUIRED
195 !define MULTIUSER_INIT_TEXT_ADMINREQUIRED "$(^Caption) requires Administrator priviledges."
198 !ifndef MULTIUSER_INIT_TEXT_POWERREQUIRED
199 !define MULTIUSER_INIT_TEXT_POWERREQUIRED "$(^Caption) requires at least Power User priviledges."
202 !ifndef MULTIUSER_INIT_TEXT_ALLUSERSNOTPOSSIBLE
203 !define MULTIUSER_INIT_TEXT_ALLUSERSNOTPOSSIBLE "Your user account does not have sufficient privileges to install $(^Name) for all users of this compuetr."
208 !macro MULTIUSER_INIT_CHECKS UNINSTALLER_PREFIX UNINSTALLER_FUNCPREFIX
210 ;Installer initialization - check privileges and set install mode
212 !insertmacro MULTIUSER_INIT_TEXTS
214 UserInfo::GetAccountType
215 Pop $MultiUser.Privileges
221 !if "${MULTIUSER_EXECUTIONLEVEL}" == Admin
223 ${if} $MultiUser.Privileges != "Admin"
224 MessageBox MB_OK|MB_ICONSTOP "${MULTIUSER_INIT_TEXT_ADMINREQUIRED}"
225 !insertmacro MULTIUSER_INIT_QUIT "${UNINSTALLER_FUNCPREFIX}"
228 !else if "${MULTIUSER_EXECUTIONLEVEL}" == Power
230 ${if} $MultiUser.Privileges != "Power"
231 ${andif} $MultiUser.Privileges != "Admin"
233 MessageBox MB_OK|MB_ICONSTOP "${MULTIUSER_INIT_TEXT_POWERREQUIRED}"
235 MessageBox MB_OK|MB_ICONSTOP "${MULTIUSER_INIT_TEXT_ADMINREQUIRED}"
237 !insertmacro MULTIUSER_INIT_QUIT "${UNINSTALLER_FUNCPREFIX}"
242 !ifdef MULTIUSER_EXECUTIONLEVEL_ALLUSERS
244 ;Default to per-machine installation if possible
246 ${if} $MultiUser.Privileges == "Admin"
247 ${orif} $MultiUser.Privileges == "Power"
248 !ifndef MULTIUSER_INSTALLMODE_DEFAULT_CURRENTUSER
249 Call ${UNINSTALLER_FUNCPREFIX}MultiUser.InstallMode.AllUsers
251 Call ${UNINSTALLER_FUNCPREFIX}MultiUser.InstallMode.CurrentUser
254 !ifdef MULTIUSER_INSTALLMODE_DEFAULT_REGISTRY_KEY & MULTIUSER_INSTALLMODE_DEFAULT_REGISTRY_VALUENAME
256 ;Set installation mode to setting from a previous installation
258 !ifndef MULTIUSER_INSTALLMODE_DEFAULT_CURRENTUSER
259 ReadRegStr $MultiUser.DefaultKeyValue HKLM "${MULTIUSER_INSTALLMODE_DEFAULT_REGISTRY_KEY}" "${MULTIUSER_INSTALLMODE_DEFAULT_REGISTRY_VALUENAME}"
260 ${if} $MultiUser.DefaultKeyValue == ""
261 ReadRegStr $MultiUser.DefaultKeyValue HKCU "${MULTIUSER_INSTALLMODE_DEFAULT_REGISTRY_KEY}" "${MULTIUSER_INSTALLMODE_DEFAULT_REGISTRY_VALUENAME}"
262 ${if} $MultiUser.DefaultKeyValue != ""
263 Call ${UNINSTALLER_FUNCPREFIX}MultiUser.InstallMode.CurrentUser
267 ReadRegStr $MultiUser.DefaultKeyValue HKCU "${MULTIUSER_INSTALLMODE_DEFAULT_REGISTRY_KEY}" "${MULTIUSER_INSTALLMODE_DEFAULT_REGISTRY_VALUENAME}"
268 ${if} $MultiUser.DefaultKeyValue == ""
269 ReadRegStr $MultiUser.DefaultKeyValue HKLM "${MULTIUSER_INSTALLMODE_DEFAULT_REGISTRY_KEY}" "${MULTIUSER_INSTALLMODE_DEFAULT_REGISTRY_VALUENAME}"
270 ${if} $MultiUser.DefaultKeyValue != ""
271 Call ${UNINSTALLER_FUNCPREFIX}MultiUser.InstallMode.AllUsers
279 Call ${UNINSTALLER_FUNCPREFIX}MultiUser.InstallMode.CurrentUser
284 Call ${UNINSTALLER_FUNCPREFIX}MultiUser.InstallMode.CurrentUser
288 !ifdef MULTIUSER_INSTALLMODE_COMMANDLINE
290 ;Check for install mode setting on command line
292 ${${UNINSTALLER_FUNCPREFIX}GetParameters} $MultiUser.Parameters
294 ${${UNINSTALLER_PREFIX}StrStr} $MultiUser.Result $MultiUser.Parameters "/CurrentUser"
296 ${if} $MultiUser.Result != ""
297 Call ${UNINSTALLER_FUNCPREFIX}MultiUser.InstallMode.CurrentUser
300 ${${UNINSTALLER_PREFIX}StrStr} $MultiUser.Result $MultiUser.Parameters "/AllUsers"
302 ${if} $MultiUser.Result != ""
303 ${if} $MultiUser.Privileges == "Admin"
304 ${orif} $MultiUser.Privileges == "Power"
305 Call ${UNINSTALLER_FUNCPREFIX}MultiUser.InstallMode.AllUsers
307 MessageBox MB_OK|MB_ICONSTOP "${MULTIUSER_INIT_TEXT_ALLUSERSNOTPOSSIBLE}"
315 ;Not running Windows NT, per-user installation not supported
317 Call ${UNINSTALLER_FUNCPREFIX}MultiUser.InstallMode.AllUsers
323 !macro MULTIUSER_INIT
327 !insertmacro MULTIUSER_INIT_CHECKS "" ""
332 !ifndef MULTIUSER_NOUNINSTALL
334 !macro MULTIUSER_UNINIT
338 !insertmacro MULTIUSER_INIT_CHECKS Un un.
353 !macro MULTIUSER_INSTALLMODEPAGE_INTERFACE
355 !ifndef MULTIUSER_INSTALLMODEPAGE_INTERFACE
356 !define MULTIUSER_INSTALLMODEPAGE_INTERFACE
357 Var MultiUser.InstallModePage
359 Var MultiUser.InstallModePage.Text
361 Var MultiUser.InstallModePage.AllUsers
362 Var MultiUser.InstallModePage.CurrentUser
364 Var MultiUser.InstallModePage.ReturnValue
369 !macro MULTIUSER_PAGEDECLARATION_INSTALLMODE
371 !insertmacro MUI_SET MULTIUSER_${MUI_PAGE_UNINSTALLER_PREFIX}INSTALLMODEPAGE ""
372 !insertmacro MULTIUSER_INSTALLMODEPAGE_INTERFACE
374 !insertmacro MUI_DEFAULT MULTIUSER_INSTALLMODEPAGE_TEXT_TOP "$(MULTIUSER_INNERTEXT_INSTALLMODE_TOP)"
375 !insertmacro MUI_DEFAULT MULTIUSER_INSTALLMODEPAGE_TEXT_ALLUSERS "$(MULTIUSER_INNERTEXT_INSTALLMODE_ALLUSERS)"
376 !insertmacro MUI_DEFAULT MULTIUSER_INSTALLMODEPAGE_TEXT_CURRENTUSER "$(MULTIUSER_INNERTEXT_INSTALLMODE_CURRENTUSER)"
380 PageCallbacks MultiUser.InstallModePre_${MUI_UNIQUEID} MultiUser.InstallModeLeave_${MUI_UNIQUEID}
386 !insertmacro MULTIUSER_FUNCTION_INSTALLMODEPAGE MultiUser.InstallModePre_${MUI_UNIQUEID} MultiUser.InstallModeLeave_${MUI_UNIQUEID}
388 !undef MULTIUSER_INSTALLMODEPAGE_TEXT_TOP
389 !undef MULTIUSER_INSTALLMODEPAGE_TEXT_ALLUSERS
390 !undef MULTIUSER_INSTALLMODEPAGE_TEXT_CURRENTUSER
394 !macro MULTIUSER_PAGE_INSTALLMODE
396 ;Modern UI page for install mode
401 !ifndef MULTIUSER_EXECUTIONLEVEL_ALLUSERS
402 !error "A mixed-mode installation requires MULTIUSER_EXECUTIONLEVEL to be set to Admin, Power or Highest."
405 !insertmacro MUI_PAGE_INIT
406 !insertmacro MULTIUSER_PAGEDECLARATION_INSTALLMODE
412 !macro MULTIUSER_FUNCTION_INSTALLMODEPAGE PRE LEAVE
414 !ifndef MULTIUSER_TEXT_NOTADMIN
415 !define MULTIUSER_TEXT_NOTADMIN "The installer is currently running as an unprivileged user. It will not be possible to install this software for all users on the system. Cancel and re-run the installer as Administrator to install system-wide."
418 ;Page functions of Modern UI page
426 ${if} $MultiUser.Privileges != "Power"
427 ${andif} $MultiUser.Privileges != "Admin"
428 MessageBox MB_OKCANCEL "${MULTIUSER_TEXT_NOTADMIN}" /SD IDOK IDABORT nofun
435 !insertmacro MUI_PAGE_FUNCTION_CUSTOM PRE
436 !insertmacro MUI_HEADER_TEXT_PAGE $(MULTIUSER_TEXT_INSTALLMODE_TITLE) $(MULTIUSER_TEXT_INSTALLMODE_SUBTITLE)
438 nsDialogs::Create 1018
439 Pop $MultiUser.InstallModePage
441 ${NSD_CreateLabel} 0u 0u 300u 20u "${MULTIUSER_INSTALLMODEPAGE_TEXT_TOP}"
442 Pop $MultiUser.InstallModePage.Text
444 ${NSD_CreateRadioButton} 20u 50u 280u 10u "${MULTIUSER_INSTALLMODEPAGE_TEXT_ALLUSERS}"
445 Pop $MultiUser.InstallModePage.AllUsers
447 ${NSD_CreateRadioButton} 20u 70u 280u 10u "${MULTIUSER_INSTALLMODEPAGE_TEXT_CURRENTUSER}"
448 Pop $MultiUser.InstallModePage.CurrentUser
450 ${if} $MultiUser.InstallMode == "AllUsers"
451 SendMessage $MultiUser.InstallModePage.AllUsers ${BM_SETCHECK} ${BST_CHECKED} 0
453 SendMessage $MultiUser.InstallModePage.CurrentUser ${BM_SETCHECK} ${BST_CHECKED} 0
456 !insertmacro MUI_PAGE_FUNCTION_CUSTOM SHOW
462 SendMessage $MultiUser.InstallModePage.AllUsers ${BM_GETCHECK} 0 0 $MultiUser.InstallModePage.ReturnValue
464 ${if} $MultiUser.InstallModePage.ReturnValue = ${BST_CHECKED}
465 Call MultiUser.InstallMode.AllUsers
467 Call MultiUser.InstallMode.CurrentUser
470 !insertmacro MUI_PAGE_FUNCTION_CUSTOM LEAVE