Most operating systems have the concept of normal users and administrators. While regular applications can run with limited privileges, installers often need full administrator privileges because they make modifications to the system that are not granted to limited users. The required privileges depend on two factors: The operating system and the type of operations that are performed by the installer. The "Request privileges" action that is present in the "Startup" sequence of both installers and uninstallers by default takes care of elevating the privileges to the required level and optionally terminating the installer with an error message if the required privileged cannot be obtained. Due to the differences for the different operating systems, this configuration is made separately for Windows, macOS and Unix.
For the installer and the uninstaller, the privileges should be the same. This is why by default the uninstaller has a "Request installer privileges" action that will request the same privileges that were obtained in the installer. If you have more complex requirements, you can have multiple "Request privileges" actions with appropriate condition expressions, each with a link in the uninstaller.
Since Windows Vista, "User Account Control" (UAC) limits privileges for all users by default. An application can request full privileges, with different effects for normal users and admin users: A normal user cannot be elevated to full privileges, so the user has to enter credentials for a different administrator account. A normal user is not likely to have these credentials, so by default the "Request privileges" action does not try to obtain full privileges for normal users. An admin user can be elevated. A UAC prompt will be shown in this case and the user simply has to agree in order to elevate privileges for the installer. Since it is not possible to write to the program files directory without elevated privileges, this elevation is performed by default. With the "Try to obtain full privileges if admin user" and the "Try to obtain full privileges if normal user" properties in the "Windows" category, you can configure this behavior according to your own needs.
By default, the installer will fail if the requested privileges cannot be obtained. You can deselect the "Show failure if requested privileges cannot be obtained" property in the Windows category to continue and let the user install into the user home directory or another writable directory.
Under some circumstances, for example if you want to manage services in your installer, you absolutely require full privileges. In this case, you can select the "Try to obtain full privileges if normal user" property in the Windows category. When you insert a service action and the elevation properties are not selected, you will be asked whether the necessary changes should be made automatically.
Similar to Windows, macOS limits privileges for all users by default and normal users and admin users behave
differently with respect to privilege elevation: A normal user cannot be elevated to full privileges, so the user
has to enter the root password. A normal user is not likely to have the root password, so by default the
"Request privileges" action does not try to obtain full privileges for normal users. To elevate an admin user, an
authenticate dialog will be shown and users have to enter their own password. Contrary to Windows, admin users can
always write to the /Applications
directory, even without full privileges. That's why on macOS no
elevation of privileges is requested by default.
Like on Windows, the installer will fail by default if the requested privileges cannot be obtained. In the default setting this has no effect, because privileges are never requested.
Service installations require full privileges, so the "Try to obtain full privileges if admin user" and the "Try to obtain full privileges if normal user" properties in the macOS category should be selected in that case. Again, service actions will suggest to make the necessary changes automatically when they are inserted into the project.
install4j does not support elevation of privileges on Linux and Unix. Partly this is due to the different incompatible systems of elevation, most notably "su" and "sudo" which cannot be easily detected. If full privileges are required, the user has to elevate the installer manually, either with "su" or with "sudo" or with the corresponding GUI tools. In this case, the "Show failure if current user is not root" has to be selected, so that an error message is shown if the installer is not started as root.
install4j does not elevate the entire process, but it starts an elevated helper process with full privileges.
All actions have an "Action elevation type" property that can be set to "Inherit from parent", "Do not elevate" and "Elevate to maximum available privileges". The root element in the element hierarchy is always an installer application whose "Action elevation type" property is set to "Do not elevate by default".
Actions whose "Action elevation type" property results to "Elevate to maximum available privileges" will run in the helper process. They have full access to all installer variables as long as the contents of the variables are serializable.
Actions can have a preferred elevation type that is set automatically when you add the action. Actions that need to be elevated include
Actions that are explicitly not elevated by default include
Elevated actions can only interact with the GUI in a limited way. All methods in the com.install4j.api.Util
class for displaying message dialogs or option dialogs are supported. You cannot call context.getWizardContext() or directly display a GUI
using the Java Swing API. Also, calling methods in the com.api.install4j.context.Context
that change screens
is not supported. Since an elevated action runs in a different process, you cannot access any static state in custom code.
Installer variables are the only means to modify state from elevated actions.
For your own scripts or custom code, the API offers a way to push a piece of code to the elevated
helper process or to the original process if they exist. This is done by wrapping the code in a
com.install4j.api.context.RemoteCallable
and calling
context.runElevated(...)
for the elevated helper process and context.runUnelevated(...)
for the original process with the RemoteCallable
. The RemoteCallable
must be serializable,
so its fields can be transferred to the other process. Its execute()
method that contains the code
returns a Serializable
so you can return a result to the calling process.
Several actions in install4j use this mechanism, as explained in the next section.