UAC plug-in: Difference between revisions
(Update docs to current status.) |
|||
Line 95: | Line 95: | ||
====Launching an application with user privileges==== | ====Launching an application with user privileges==== | ||
<highlight-nsis> | <highlight-nsis> | ||
; | ; !insertmacro UAC_AsUser_ExecShell <Command> <File> <Parameters> <WorkingDir> <ShowWindow> | ||
!insertmacro UAC_AsUser_ExecShell 'open' '$INSTDIR\${APPFILE}' '-firstrun' '$INSTDIR' '' | |||
</highlight-nsis> | </highlight-nsis> | ||
Line 108: | Line 108: | ||
Function ExecAppFile | Function ExecAppFile | ||
!insertmacro UAC_AsUser_ExecShell 'open' '$INSTDIR\${APPFILE}' '-firstrun' '$INSTDIR' '' | |||
FunctionEnd | FunctionEnd | ||
</highlight-nsis> | </highlight-nsis> |
Revision as of 23:42, 25 February 2010
Author: Anders (talk, contrib) |
Download & Info
This plug-in attempts to work around UAC installation problems on Vista. This plug-in allows your installer to operate with a user level process and an admin level process. This allows you to accomplish things that would otherwise be very difficult. For example, you can have an admin level installer launch another process at a user level. Or you can have an admin level installer create shortcuts at a user level.
It all started in this thread. It has been field tested with good results. It is still definitely in the beta stage (i.e. use at your own risk).
Stable aka "Old": v0.0.11d
Experimental version: v0.2.2b
Basic installation
To install the UAC plugin in your NSIS setup, you just need to copy two files from the above ZIP:
- For ANSI installers, copy UAC.nsh into your Include directory (e.g. C:\Program Files\NSIS\Include) and UAC.dll from Release/A into your Plugins directory (e.g. C:\Program Files\NSIS\Plugins).
- For Unicode installers, copy UAC.nsh into your Include directory (e.g. C:\Program Files\NSIS\Unicode\Include) and UAC.dll from Release/U into your Plugins directory (e.g. C:\Program Files\NSIS\Unicode\Plugins).
How it works
Supplying the necessary code
- First, the NSIS script must specify that it should run with user privileges, not admin privileges.
RequestExecutionLevel user /* RequestExecutionLevel REQUIRED! */
- Next, the most common approach is to let the UAC plugin initialize in the .onInit code:
; Attempt to give the UAC plug-in a user process and an admin process. Function .OnInit UAC_Elevate: UAC::RunElevated StrCmp 1223 $0 UAC_ElevationAborted ; UAC dialog aborted by user? StrCmp 0 $0 0 UAC_Err ; Error? StrCmp 1 $1 0 UAC_Success ;Are we the real deal or just the wrapper? Quit UAC_Err: MessageBox mb_iconstop "Unable to elevate, error $0" Abort UAC_ElevationAborted: # elevation was aborted, run as normal? MessageBox mb_iconstop "This installer requires admin access, aborting!" Abort UAC_Success: StrCmp 1 $3 +4 ;Admin? StrCmp 3 $1 0 UAC_ElevationAborted ;Try again? MessageBox mb_iconstop "This installer requires admin access, try again" goto UAC_Elevate FunctionEnd
- Before the installer exits, you will need to clean up the plugin. If you don't, it will leave behind a UAC.dll in the user's %TEMP% folder. One easy way to clean it up is by supplying the following:
Function .OnInstFailed UAC::Unload ;Must call unload! FunctionEnd Function .OnInstSuccess UAC::Unload ;Must call unload! FunctionEnd
Remember that if your installer quits before those events can be fired, you should supply a UAC::Unload before the installer quits.
How the UAC plug-in works with user and admin privileges
- When the NSIS installer launches, it has user privileges (as specified by RequestExecutionLevel user). Immediately, the NSIS installer calls its .onInit code. (Note, no window is visible yet at this point). The UAC plugin makes a second installer process and attempts to elevate it with admin privileges. If needed, a UAC or Run As dialog is shown to help elevate this second process with admin privileges. At this point, if you open up Task Manager, you will see two installer processes running. The user process can be thought of as the outer process, and the admin process the inner process.
- Once elevated, the admin/inner process will display. This is the installer window that users will see.
- Now that you have an admin process, you can continue to let your script do its thing. If you ever need to do something at a user level, you do it through the UAC plugin, and the UAC plugin will run whats needed through the hidden user/outer process. For example, UAC::Exec can execute something with user privileges and not admin privileges. Or UAC::ExecCodeSegment can execute an entire function with user privileges.
Examples
Many examples are found in the .zip file above. If you want a better idea of what this plugin can do, study those examples. A brief overview of two simple examples are given here:
Creating a user shortcut
UAC_RealWorldExample.nsi does:
Function CreateShortcuts CreateShortcut "$Desktop\${APPNAME}.lnk" "$Windir\Notepad.exe" FunctionEnd Section "Desktop Shortcut" GetFunctionAddress $0 CreateShortcuts UAC::ExecCodeSegment $0 SectionEnd
In this example, we would want to run the CreateShortcuts function with user privileges, so it can create a user-level shortcut. So first, define the function. Then use GetFunctionAddress to get the address of that function. Then, call UAC::ExecCodeSegment to ask the outer/user process to run that function. Since the function will be run at a user level, it will create a shortcut for the user instead of for the administrator.
Launching an application with user privileges
; !insertmacro UAC_AsUser_ExecShell <Command> <File> <Parameters> <WorkingDir> <ShowWindow> !insertmacro UAC_AsUser_ExecShell 'open' '$INSTDIR\${APPFILE}' '-firstrun' '$INSTDIR' ''
Where $INSTDIR\${APPFILE} is the path to the file you want to launch.
If you use the MUI skin and have the installer launch the app for you, you will need to do a little more work.
!define MUI_FINISHPAGE_RUN !define MUI_FINISHPAGE_RUN_FUNCTION ExecAppFile Function ExecAppFile !insertmacro UAC_AsUser_ExecShell 'open' '$INSTDIR\${APPFILE}' '-firstrun' '$INSTDIR' '' FunctionEnd
Keep in mind that you still have to define MUI_FINISHPAGE_RUN (as empty) otherwise MUI won't provide the option at all.
Important Notes
- If you need to use the UAC plugin for the uninstaller as well, you will need to initalize the UAC plugin for the uninstaller, such as through un.onInit. Remember to run clean it up with UAC::Unload before your uninstaller exits. Great places to clean it up are un.OnUnInstFailed and un.OnUnInstSuccess
- The outer/user process does not display any output as to what occurred. For example, if you have the outer/user process create a shortcut, and it fails, the inner/admin process currently visible will not display anything to indicate that a problem occurred. This is because the outer/user process does not yet communicate back to the inner/admin process.
- When a standard or limited user supplies administrator information into the Run As dialog, you may experience permissions trouble with any extracted file. For example, if a Windows 2000 standard user supplies administrator info into the Run As dialog, and the NSIS installer extracts an .exe file, then trying to call that .exe through an Exec can fail. If this is a problem, you will want to use the AccessControl plug-in.
Tested Environments
This plugin has been tested under the following environments:
- Windows Vista - UAC On - Administrator
- Windows Vista - UAC Off - Administrator
- Windows Vista - UAC On - Standard User - User supplies administrator info into the UAC dialog
- Windows Vista - UAC On - Standard User - User does not supply administrator info into the UAC dialog
- Windows Vista - UAC Off - Standard User - User supplies administrator info into the Run As dialog
- Windows Vista - UAC Off - Standard User - User does not supply administrator info into the Run As dialog
- Windows XP - Administrator
- Windows XP - Limited User - User supplies administrator info into the Run As dialog
- Windows XP - Limited User - User does not supply administrator info into the Run As dialog
- Windows 2000 - Administrator
- Windows 2000 - Standard User - User supplies administrator info into the Run As dialog
- Windows 2000 - Standard User - User does not supply administrator info into the Run As dialog
- Windows 95 & 98 were tested in early builds and hopefully still work (No elevation here for obvious reasons)
Windows ME & NT4 are untested, but should work. (If you have tested on one of these OS'es, please report results here or on the forum)