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