I am quite new with NSIS. I am trying to request administrator permissions in order to run the installer, as it messes around a bit with registries. My problem with "RequestExecutionLevel" and "MULTIUSER_EXECUTIONLEVEL" is that they both absolutely block any non-Admin user from opening the installer, even when selecting "Run as Administrator" in the context menu. I have tried using the RunAs DLL, but I have not found a single thread as to what to put in the $command variable passed to "RunAsW" function.
Here is my (pretty hacked-up) code:
StrCpy $0 0
StrCpy $1 ""
System::Call 'RunAs::GetAdministrators(w r1, *i .r0) i .r2 ? u'
System::Alloc 64
Pop $4
StrCpy $4 $2
StrCpy $5 ""
loop:
IntCmp $0 0 endloop
System::Call '*$4(w .r3)'
StrCpy $5 "$5|$3"
endloop:
System::Free $4 ; we free the memory used by the array
StrCpy $5 "$5" "" 1
!insertmacro MUI_INSTALLOPTIONS_WRITE "Settings.ini" "Field 1" "ListItems" $5
!insertmacro MUI_INSTALLOPTIONS_DISPLAY "Settings.ini"
!insertmacro MUI_INSTALLOPTIONS_READ $1 "UserPass" "Field 1" "State"
!insertmacro MUI_INSTALLOPTIONS_READ $2 "Settings.ini" "Field 2" "State"
StrCpy $3 "%%LOGONSERVER%%"
StrCpy $3 0
StrCpy $4 0
System::Call 'RunAs::RunAsW(w r1, w r2, w r3, *w .r4) i .r0 ? u'
MessageBox MB_OK $0
IntCmp $0 1 success
Quit
success:
!insertmacro MUI_LANGDLL_DISPLAY
A lot of it is just guess work and trial and error. (btw - I also tried running through a loop to get all Administrators, but it seems the DLL was intended only for 32-bit machines, so...).
Anyway, my question is:
Does anybody know of a way (using "RunAs" or otherwise) to open a dialog requesting Username and password, check the credentials and continue with the installation only if they check out?
Also, I know there is a way to set up an installer so that it comes with that nice shield icon on it that lets users know that Admin permission will be requested. Does anybody know how to do that?
Any help would be very much appreciated, as this is the only thing currently preventing the deployment of my app.
Outfile RequireAdmin.exe
RequestExecutionLevel admin ;Require admin rights on NT6+ (When UAC is turned on)
!include LogicLib.nsh
Function .onInit
UserInfo::GetAccountType
pop $0
${If} $0 != "admin" ;Require admin rights on NT4+
MessageBox mb_iconstop "Administrator rights required!"
SetErrorLevel 740 ;ERROR_ELEVATION_REQUIRED
Quit
${EndIf}
FunctionEnd
Page InstFiles
Section
SectionEnd
is the basic code I usually recommend to make sure the installer is running as an Administrator.
IMHO it does not make sense to prompt for credentials on a custom page unless only parts of the install process requires administrator access and the other part requires access to the users profile. If this applies to you then you should take a look at the UAC plug-in (It is a bit complicated to use and makes it impossible for your exe file to get the shield overlay icon)
I don't think the RunAs plug-in works correctly on Vista+ when UAC is on so trying to get it to work might be a dead end...
The recommended way to get the shield is to request elevation in the exe manifest, RequestExecutionLevel admin
does that. If you don't use RequestExecutionLevel
at all in your script your installer might be detected as a legacy installer and it will also get the shield overlay.
In Windows Vista, if an executable file requires elevation to launch, then the executable's icon should be "stamped" with a shield icon to indicate this fact. The executable's application manifest must mark "requireAdministrator" to designate the executable as requiring a full administrative access token. The shield icon overlay will also be automatically placed on executables that are deemed to require elevation as per the installer detection heuristics. For example, a file named setup.exe will automatically receive a shield icon overlay even if the executable does not have an embedded application manifest.