Archive: MultiUser.nsh & INSTDIR


MultiUser.nsh & INSTDIR
So I created an installer and uninstaller.

Due to the Vista virus^wOS it seems necessary to use MultiUser.nsh; however, when the user changes the install location, then that is not reflected in the default uninstall location.

What am I missing?

Commenting out

; Function un.onInit
; !insertmacro MULTIUSER_UNINIT
; FunctionEnd


makes the right install location be found, and then the uninstaller can read the install log to know what to uninstall... but for the cases where it is running in USER mode, and the installer ran in ADMIN mode, the SHCTX is wrong. But if I just

SetShellVarContext all

then if the ADMIN chooses a single user install, the SHCTX is wrong the other way.

Should I save $INSTDIR around the call to MULTIUSER_UNINIT? Why is MULTIUSER_UNINIT changing INSTDIR anyway? The uninstaller is installed corresponding to where the application is installed, so the INSTDIR is right, MULTIUSER_UNINIT shouldn't change it, as far as I can tell.

Pity there is no GetShellVarContext, but not clear how to pass that to the uninstaller anyway.


Well, I tried the save/restore of $INSTDIR around the MULTIUSER_UNINIT call, but it still left SHCTX wrong when an ADMIN installs the app for personal use.


I could be a bug with the multiuser stuff


I do this with multiuser:

!define APP_NAME "My App"
#
!define INSTDIR_REG_ROOT "SHELL_CONTEXT"
!define INSTDIR_REG_KEY "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APP_NAME}"
!define UNINST_EXE "$INSTDIR\uninstall.exe"
#
!define MULTIUSER_EXECUTIONLEVEL Admin
!define MULTIUSER_INSTALLMODE_DEFAULT_CURRENTUSER
!define MULTIUSER_INSTALLMODE_DEFAULT_REGISTRY_KEY "${INSTDIR_REG_KEY}"
!define MULTIUSER_INSTALLMODE_DEFAULT_REGISTRY_VALUENAME "InstallDir"
!define MULTIUSER_INSTALLMODE_INSTDIR_REGISTRY_KEY "${INSTDIR_REG_KEY}"
!define MULTIUSER_INSTALLMODE_INSTDIR_REGISTRY_VALUENAME "InstallDir"
!define MULTIUSER_MUI

!include MultiUser.nsh

!include MUI2.nsh

Name "${APP_NAME}"
OutFile "${APP_NAME} Setup.exe"
ShowInstDetails show
ShowUninstDetails show
InstallDir "$PROGRAMFILES\${APP_NAME}"

!insertmacro MUI_PAGE_WELCOME
!define MUI_PAGE_CUSTOMFUNCTION_PRE multiuser_pre_func
!insertmacro MULTIUSER_PAGE_INSTALLMODE
!insertmacro MUI_PAGE_DIRECTORY
!insertmacro MUI_PAGE_INSTFILES

!insertmacro MUI_UNPAGE_CONFIRM
!insertmacro MUI_UNPAGE_INSTFILES

!insertmacro MUI_LANGUAGE "English"


Section "" sec01

SetOutPath '$INSTDIR'

File "${NSISDIR}\nsis.exe"

WriteUninstaller "${UNINST_EXE}"

WriteRegStr ${INSTDIR_REG_ROOT} "${INSTDIR_REG_KEY}" "InstallDir" "$INSTDIR"
WriteRegStr ${INSTDIR_REG_ROOT} "${INSTDIR_REG_KEY}" "DisplayName" "${APP_NAME}"
WriteRegStr ${INSTDIR_REG_ROOT} "${INSTDIR_REG_KEY}" "DisplayIcon" "$INSTDIR\${APP_NAME}.exe"
WriteRegStr ${INSTDIR_REG_ROOT} "${INSTDIR_REG_KEY}" "UninstallString" "${UNINST_EXE}"

SectionEnd


Function .onInit

!insertmacro MULTIUSER_INIT

FunctionEnd


Function multiuser_pre_func

ClearErrors
ReadRegStr $R1 ${INSTDIR_REG_ROOT} "${INSTDIR_REG_KEY}" "InstallDir"
${Unless} ${Errors}
Abort
${EndUnless}

FunctionEnd

#################################

Section UnInstall

Delete "$INSTDIR\nsis.exe"
Delete "${UNINST_EXE}"
RmDir "$INSTDIR"

DeleteRegKey ${INSTDIR_REG_ROOT} "${INSTDIR_REG_KEY}"

SectionEnd


Function UN.onInit

!insertmacro MULTIUSER_UNINIT

FunctionEnd

Hi anders, thanks for the response; how is a NSIS newbie to figure out if this is a bug or not?

Hi Red Wine, thanks for the response; Nice to have an example to play with. I note that your code uses

!define MULTIUSER_EXECUTIONLEVEL Admin

and I wonder -- does that prevent non-admin users from running the installer (producing an error?)?


Obviously it produces error, after all this is the meaning of multiuser.nsh :)


Sure, but wouldn't using Highest allow non-Admin's to also install for their own use? Or does that prevent something else from working?


I'm not quite sure which is the exact usage of 'highest', I guess it make sense under vista environment. When I tried it in XP 'power user' account, it produced the error 'requires admin privileges'.


highest never makes any sense, on vista, it forces an admin to elevate, even if he does not want to


Thanks for the reply, Anders. So Highest forces elevation, Power is the same as Admin, and Admin forces regular users to login as Admin? So Standard is the only default setting that makes sense? If not, then I guess Vista is senseless? :)


But, Standard produces an NSIS error:

!error: A mixed-mode installation requires MULTIUSER_EXECUTIONLEVEL to be set to Admin, Power or Highest.

So I guess Vista is senseless. Or NSIS is ... how do I get my installer to work for regular users, but be restricted to "currentuser" installs, but allow Admins to choose between "all" or "currentuser" ?


If you set the execution level to Highest, admins will be allowed to choose between "Current user" or "All users", while standard users will be able to perform the installation for their own user account.


Re: MultiUser.nsh & INSTDIR

Originally posted by daily guru
Should I save $INSTDIR around the call to MULTIUSER_UNINIT? Why is MULTIUSER_UNINIT changing INSTDIR anyway? The uninstaller is installed corresponding to where the application is installed, so the INSTDIR is right, MULTIUSER_UNINIT shouldn't change it, as far as I can tell.
Thanks for your report. This will be fixed in the next version.

Hi Joost, Thanks for your reply. Where's the best place to report bugs that are clearly bugs?

Here are a couple more:

MUI2 Finish page: code enables Next button when the option to enable the Cancel button is specified.

MUI2 Welcome page: code ensures that MUI_${}WELCOMEFINISHPAGE_BITMAPS is not already set before setting MUI_${}WELCOMEFINISHPAGE_BITMAP -- note one has a trailing S the other doesn't.

The INSTALL page progress bar, when not autoclosed, doesn't ever reach 100% for some of my installs. It is not clear that there is any control over this, at the user level. Seems like even installs of fewer than all components should reach 100% complete...


Originally posted by daily guru
MUI2 Finish page: code enables Next button when the option to enable the Cancel button is specified.
Thanks, fixed.
Originally posted by daily guru
MUI2 Welcome page: code ensures that MUI_${}WELCOMEFINISHPAGE_BITMAPS is not already set before setting MUI_${}WELCOMEFINISHPAGE_BITMAP -- note one has a trailing S the other doesn't.
This is not really a bug, because the MUI_DEFAULT macro already does the check. So the check for BITMAPS is harmless but also useless :) I'll remove this code.

Thanks again. Being a new user, and seeing that extra S on BITMAPS, it just looked like a bug, compared to other similar code, but I don't have a full knowledge or understanding of all the code internals...

Any idea about the progress bar? I was making my own Finish page, and apparently the "autoclose" feature gets turned on by the finish page, so when I deleted the MUI2 one in favor of mine, I started seeing this.


NSIS doesn't always know how long certain actions will take or what decisions are made during installation. This is why the progress bar may not be that accurate.


Sure; without advance performance analysis, I can see that it would be hard to keep the progress bar completely accurate... but then, most progress bars aren't all that accurate.

The point is, though, that when it is _done_, it should be 100%, not 40%... even if it means a 60% jump just as the final state is reached.


Originally posted by Joost Verburg
If you set the execution level to Highest, admins will be allowed to choose between "Current user" or "All users", while standard users will be able to perform the installation for their own user account.
It's work fine, but it is not exactly what I want. :(

I want the following scenario:
1. Choice language page.
2. Welcome page.
3. License page.
4. "Choose installation type" page.
If user is not an administrator that skip the page and install for current user only.
If user is administrator than show page "Choose installation type (All users/Current user)". If installation for "All users" that elevate execution level (it means that Vista's UAC window will shown). If installation for "Current user only" not elevate execution level.
5. Dir page.
6. etc...

It is possible?
What I have to do to achieve this?
I searched the forum hardly, but I am not found such scenario. :(


PS: Sorry for my bad English - English is not my native language. :(