# Setting the installation directory

One of the crucial decisions that generated installers must make is where to install the application. This involves various considerations, like update installations, command line directory selection and user selections in the installer. The consequences of that decision must be managed carefully because depending on the directory, elevated privileges are required. install4j offers functional defaults while allowing maximum flexibility for a wide variety of requirements.

### Basic behavior

On the "Installer options" step of the media wizard, you define the name of the installation directory. However, unless you also define a "Custom base directory" for specific deployment scenarios, the parent directory of the installation directory is not pre-set.

By default, installers generated by install4j install into a user-writable location which differs for each operating system:

- Windows: `%LOCALAPPDATA%\Programs`
- macOS: `$HOME/Applications`
- Linux: `$HOME`

Usually, this initial installation directory is changed with a "Set installation directory" action in the "Startup" node of your installer.

![](../images/ui/set_installation_directory_action.png)

Its "Installation scope" property defines the strategy on how to set the installation directory. By default, the installation scope is set to "For all users if directory is writable". This means that if the current process has rights to perform installations for all users, the parent directory of the installation directory will be set to:

- Windows: `%PROGRAMFILES%`
- macOS: `/Applications`
- Linux: `/opt`. If not writable, fall back to `/usr/local`, then to `$HOME`

On Windows and Linux, you usually need to run as administrator for that to be the case, but on macOS, it is enough to be a member of the admin group so that you can write to `/Applications`.

The "Set installation directory" action also sets the boolean installer variable `sys.installForAllUsers`. Other screens and actions in the installer can react to this condition to modify their behavior.

### Requesting privileges

For an installer, the process privileges provided when the user starts the installer are often insufficient. To elevate the privileges to those of an administrator, the "Request privileges" action is used. If that action runs successfully, an elevated helper process will be started that can perform installations for all users.

![](../images/ui/request_privileges_action.png)

Whether and where such "Request privileges" actions are present in your project is up to you. In many cases, you will want to adjust the installation directory for a new installation after elevated privileges have been obtained. For that purpose, you add the "Set installation directory" action after the "Request privileges" action.

This is exactly how new projects in install4j are configured. The "Startup" node of the installer will include a "Request privileges" action followed by a "Set installation directory" action. Your requirements may be different, so you can remove these actions, reconfigure them or insert them at a later stage into the installer.

### Update installations

If the application has already been installed before, you likely want the user to update the existing installation instead of creating a new installation. Finding and setting the previous installation directory is a task that is also handled by the "Set installation directory" action.

For this purpose, it offers a "Search for previous installation" property. By default, update installations are only detected if they match the "Installation scope" that is configured for the action. In this way, it is assured that the installation directory will be writable later on. You can modify this behavior with the child properties, "Always search for global installations" and "Always search for user-specific installations".

The flexibility of the update installation detection allows you to handle a multitude of scenarios. For example, if you detect an update installation whose directory is not writable, you can alert the user and then use the value of the `sys.installForAllUsers` installer variable to conditionally run a "Request privileges action".

### Command line installation directory

With the -dir [installation directory] command line parameter, a user or an update downloader can force the installer to install into a particular directory. In most cases, you do not want to further change the installation directory in that case. The installer variable `sys.installForAllUsers` installer variable will be set according to whether the directory is writable or not. This allows for common handling of conditional privilege escalations.

If a command line installation directory has been set and the "Skip for command line installation directory" property of the "Set installation directory" action is selected, the action will not change the installation directory.

### Explicit decisions

In some situations, you may want to explicitly determine whether the installation directory is user-writable or for all users. The "Installation scope" property of the "Set installation directory" action has two values for these situations: "Installation directory for all users" and "User-specific installation directory".

Again, you need to manage the required privileges explicitly with a "Request privileges" action if the installation should be performed for all users and the process has insufficient rights for that operation.

![](../images/ui/installation_scopes.png)

### The installation scope screen

To allow the user to change the installation scope, you can add the "Installation scope" screen. It will ask the user whether to perform a user-specific or a global installation. Note that this is a form screen that can be augmented with your own form component. In fact the "Installation scope chooser" form component can also be inserted into other screens.

![](../images/ui/installation_scope_screen.png)

The "Installation scope" screen has two attached actions: A "Request privileges" action with a "Condition expression" property of `context.getBooleanVariable("sys.installForAllUsers")` and a "Set installation directory" action with an "Installation scope" property set to "According to the sys.installForAllUsers variable".

When the user selects an option in the "Installation scope chooser" form component, the `sys.installForAllUsers` installer variable is changed accordingly and both actions act according to the user selection.

In addition, adding the "Installation scope" screen proposes to add another "Request privileges" action to the "Installation" screen that handles the privilege escalation for streamlined installations where the "Installation scope" screen is not executed.
