Hooman Valibeigi
Hooman Valibeigi

Reputation: 105

Customize INSTDIR according to CurrentUser/AllUsers install modes in NSIS

According to the macros of MultiUser.nsh, $INSTDIR will be set to one of the following paths based on the value of $MultiUser.InstallMode:

Basically the macro appends $MULTIUSER_INSTALLMODE_INSTDIR to either $LOCALAPPDATA or $PROGRAMFILES and uses that as the default install path.

What I need is a slightly different path for CurrentUser install mode only, which is:

"$LOCALAPPDATA\Programs\${MULTIUSER_INSTALLMODE_INSTDIR}"

How can I achieve that?

Given that the user is given a chance to choose the installMode, the default $INSTDIR value must be set after this choice is made.

Upvotes: 0

Views: 1585

Answers (1)

Anders
Anders

Reputation: 101636

You can use the MULTIUSER_INSTALLMODE_FUNCTION callback function define to make changes:

Name "MultiUser test"
!define MULTIUSER_INSTALLMODE_INSTDIR "$(^Name)"
!define MULTIUSER_EXECUTIONLEVEL Highest
!define MULTIUSER_INSTALLMODE_FUNCTION onMultiUserModeChanged
!define MULTIUSER_MUI
!include MultiUser.nsh
!include MUI2.nsh
!include LogicLib.nsh

!insertmacro MULTIUSER_PAGE_INSTALLMODE
!insertmacro MUI_PAGE_DIRECTORY
!insertmacro MUI_PAGE_INSTFILES 
!insertmacro MUI_UNPAGE_CONFIRM
!insertmacro MUI_UNPAGE_INSTFILES 
!insertmacro MUI_LANGUAGE English

Function .onInit
    !insertmacro MULTIUSER_INIT
FunctionEnd
Function un.onInit
    !insertmacro MULTIUSER_UNINIT
FunctionEnd

Function onMultiUserModeChanged
${If} $MultiUser.InstallMode == "CurrentUser"
    StrCpy $InstDir "$LocalAppdata\Programs\${MULTIUSER_INSTALLMODE_INSTDIR}"
${EndIf}
FunctionEnd

Section
MessageBox MB_OK $InstDir
Quit ; This is just a demo

SetOutPath $InstDir
WriteUninstaller "$InstDir\Uninst.exe"
SectionEnd

Section Uninstall
Delete "$InstDir\Uninst.exe"
RMDir $InstDir
SectionEnd

or even better, use the UserProgramFiles known folder if it is available:

!macro GetUserProgramFiles outvar
!define /IfNDef KF_FLAG_CREATE 0x00008000
!define /IfNDef FOLDERID_UserProgramFiles {5CD7AEE2-2219-4A67-B85D-6C9CE15660CB}
System::Store S
System::Call 'SHELL32::SHGetKnownFolderPath(g "${FOLDERID_UserProgramFiles}", i ${KF_FLAG_CREATE}, p 0, *p .r2)i.r1' ; This will only work on Win7+
${If} $1 == 0
    System::Call '*$2(&w${NSIS_MAX_STRLEN} .s)'
    System::Call 'OLE32::CoTaskMemFree(p r2)'
${Else}
    Push "$LocalAppData\Programs"
${EndIf}
System::Store L
Pop ${outvar}
!macroend

Function onMultiUserModeChanged
${If} $MultiUser.InstallMode == "CurrentUser"
    !insertmacro GetUserProgramFiles $InstDir
    StrCpy $InstDir "$InstDir\${MULTIUSER_INSTALLMODE_INSTDIR}"
${EndIf}
FunctionEnd

Upvotes: 1

Related Questions