9. Rules

## 9. Rules

### 9.1. What is a Rule?

BitRock InstallBuilder allows you to control whether or not certain actions take place, pages are shown or files are installed. You just have to attach rules to the `<ruleList>` section of the desired element (an action, parameter, component, folder or shortcut).

Examples of rules include checking if ports are in use, if a file exists, if a process is running or comparing texts.

    <ruleList>
      <windowsServiceTest service="myservice" condition="not_exists"/>
    </ruleList>

    <ruleList>
      <processTest>
        <logic>is_running</logic>
        <name>${project.shortName}.exe</name>
      </processTest>
    </ruleList>

A complete list of supported rules can be found in the rules appendix.

All rules can be also negated using the `<negate>` tag. For example, the following rule will resolve to `"true"`:

       <ruleList>
         <isTrue value="1"/>
       </ruleList>

While this will resolve to `"false"`:

       <ruleList>
         <isTrue value="1" negate="1" />
       </ruleList>

This is very convenient when you want to execute an action in all supported platforms but one:

    <!-- It will resolve to true in all platforms supported but Windows 7 -->
    <ruleList>
      <platformTest type="windows-7" negate="1" />
    </ruleList>

### 9.2. Rule List

The `<ruleList>` is the most common way of attaching rules. It is supported by actions, folders, parameters and shortcuts and is evaluated at runtime.

When the set of rules contained in the rule list is evaluated, depending on the result and the element it is attached to, the following will occur:

- Action: The action is executed, otherwise it is ignored.

    <!-- The error is just thrown if the rule evaluates to
         true (it is running in Windows XP) -->
    <throwError text="This installer is not supported in Windows XP">
      <ruleList>
        <platformTest type="windows-xp"/>
      </ruleList>
    </throwError>

- Parameter: The associated page is displayed, otherwise it is hidden.

    <booleanParameter>
      <name>enableAdvanced</name>
      <description>Do you want to enable the advanced configuration?</description>
    </booleanParameter>

    <!-- The page will be displayed only if the user selected 'Yes'
         in the 'enableAdvanced' page -->
    <parameterGroup>
       <name>configuration</name>
       <title>Configuration</title>
       <explanation></explanation>
       <parameterList>
          <stringParameter name="username" description="Username"/>
          <passwordParameter name="password" description="Password"/>
       </parameterList>
       <ruleList>
          <isTrue value="${enableAdvanced}"/>
       </ruleList>
    </parameterGroup>

- Folder: If true, files belonging to that folder (files, directories and shortcuts) are installed and the associated `<actionList>` is executed.

    <folder>
      <name>fileswindowsx64</name>
      <platforms>windows</platforms>
      <destination>${installdir}</destination>
      <distributionFileList>
        <distributionDirectory origin="windows-x64/bin"/>
      </distributionFileList>
      <shortcutList>
        <shortcut>
          <comment>Uninstall</comment>
          <exec>${installdir}/${project.uninstallerName}</exec>
          ...
        </shortcut>
      </shortcutList>
      <actionList>
        <setWindowsACL>
          <action>allow</action>
          <files>${installdir}/admin;${installdir}/admin/*</files>
          <permissions>generic_all</permissions>
          <users>S-1-1-0</users>
        </setWindowsACL>
      </actionList>
      <ruleList>
        <platformTest type="windows-x64"/>
      </ruleList>
    </folder>

The rules will decide if the folder is unpacked at runtime but the installer will always bundle it (they are not considered when building the installer).

- Shortcut: If true, the shortcut will be created.

    <folder>
      <name>files</name>
      ...
      <shortcutList>
        ...
        <shortcut>
          <comment>Uninstall</comment>
          <exec>${installdir}/${project.uninstallerName}</exec>
          ...
          <ruleList>
             <!-- This can be configured through a boolean
                  parameter page -->
             <isTrue value="${createShortcuts}"/>
          </ruleList>
        </shortcut>
        ...
      </shortcutList>
      ...
    </folder>

In addition to the `<ruleList>` tag, the mentioned elements can also configure the logic used to evaluate the rules through the `<ruleEvaluationLogic>` setting. Its allowed values are:

- `and`: The set of rules will evaluate to true only if all of the rules are true. This is the default value if the `<ruleEvaluationLogic>` is not provided.

    <!-- The backup will be just executed if the folder exists and
         is not empty -->
    <createBackupFile>
      <path>${installdir}/data</path>
      <destination>${installdir}/backup</destination>
      <ruleEvaluationLogic>and</ruleEvaluationLogic>
      <ruleList>
         <fileTest path="${installdir}/data" condition="exists"/>
         <fileTest path="${installdir}/data" condition="is_not_empty"/>
      </ruleList>
    </createBackupFile>

When sequentially executing the rules using `and` evaluation logic, if any of the rules is not true, the rest are skipped and the full set evaluates to false.

You can apply this, for example, when checking whether a directory exists. You can first check if the target exists, and if so, check if it is a directory:

     <deleteFile path="some/directory" ruleEvaluationLogic="and">
       <ruleList>
         <fileExists path="some/directory"/>
         <!-- If the file does not exists, InstallBuilder will not check
         if it is a directory -->
         <fileTest path="some/directory" condition="is_directory"/>
       </ruleList>
     </deleteFile>

- `or`: The set of rules will evaluate to true if any of the rules is true.

    <!-- Just create the link if the platform is OS X or Linux -->
    <createSymLink>
      <target>${installdir}/bin/checker</target>
      <linkName>/usr/bin</linkName>
      <ruleEvaluationLogic>or</ruleEvaluationLogic>
      <ruleList>
        <platformTest type="osx"/>
        <platformTest type="linux"/>
      </ruleList>
    </createSymLink>

When sequentially executing the rules using `or` evaluation logic, if any of the rules is true, the rest are skipped and the full set evaluates to true.

### 9.3. Should Pack Rule List

The `<shouldPackRuleList>` is a special kind of `<ruleList>` only supported by `components` and `folders`.

It supports the same rules but instead of being executed at runtime, the rules are evaluated when building the installer. If they do not match, the element containing them won’t be packed at all in the installer:

- Component: The component, including all the contained folders, shortcuts, pages and actions won’t be included in the installer, as if the project were not defining them.
- Folder: The folder won’t be packed.

    <!-- The component will be packed only if the BUILD_TYPE environment
         variable defined at build-time is not set to 'demo' -->
    <component>
      <name>files</name>
      <canBeEdited>1</canBeEdited>
      <selected>1</selected>
      <show>1</show>
      ...
      <shouldPackRuleEvaluationLogic>and</shouldPackRuleEvaluationLogic>
      <shouldPackRuleList>
        <compareText>
          <text>${env(BUILD_TYPE)}</text>
          <logic>does_not_equal</logic>
          <value>demo</value>
        </compareText>
      </shouldPackRuleList>
    </component>

You can find a more complex example in the Custom Build Targets section.

The evaluation logic of the rules in the `<shouldPackRuleList>` is configured through the `<shouldPackRuleEvaluationLogic>`, which behaves as the `<ruleEvaluationLogic>` setting explained in the previous section.

### 9.4. Rule Groups

A `<ruleGroup>` is a special type of rule that can contain other rules and therefore perform more complex tests. For example, if you want to execute an action only on Windows 64bit and only if it is neither XP nor Vista:

     <runProgram program="myExec.exe" programArguments="--mode unattended">
       <ruleList>
          <platformTest type="windows-x64"/>
          <ruleGroup ruleEvaluationLogic="or" negate="1">
            <ruleList>
              <platformTest type="windows-xp"/>
              <platformTest type="windows-vista"/>
            </ruleList>
          </ruleGroup>
       </ruleList>
     </runProgram>

In the above example, you have created a new rule "Windows 64 bit that is neither XP nor Windows Vista". Please note the `<ruleGroup>` also accepts the `<ruleEvaluationLogic>` and `<negate>` tags.

Using it, you can perform any kind of logic test like `if (A and !(B or ((C or !D) and !E)))`

    <ruleList>
      <isTrue value="${A}"/>
      <ruleGroup negate="1" ruleEvaluationLogic="or">
        <ruleList>
          <isTrue value="${B}"/>
          <ruleGroup>
            <ruleList>
              <isTrue value="${E}" negate="1"/>
              <ruleGroup ruleEvaluationLogic="or">
                <ruleList>
                  <isTrue value="${C}"/>
                  <isTrue value="${D}" negate="1"/>
                </ruleList>
              </ruleGroup>
            </ruleList>
          </ruleGroup>
        </ruleList>
      </ruleGroup>
    </ruleList>

### 9.5. Creating Custom Rules

In addition to the built-in rules, InstallBuilder allows you to create new custom rules using a mix of base actions and rules. New rules are defined using the `<functionDefinitionList>`.

For example, let’s suppose you to decide whether certain component is enabled or not based on the contents of a file on Unix platforms and a registry key on Windows. To solve this you could simply create a couple of `<actionGroup>s` for the different platforms with the appropriate actions, which will in turn define a variable:

    <postInstallationActionList>
        <setInstallerVariable name="component_foo_exists" value="0"/>
        <actionGroup>
            <actionList>
                <foreach>
                    <variables>key</variables>
                    <values>HKEY_LOCAL_MACHINE\SOFTWARE\${project.windowsSoftwareRegistryPrefix}\components HKEY_LOCAL_MACHINE\SOFTWARE\${project.windowsSoftwareRegistryPrefix}\installed_components</values>
                    <actionList>
                        <continue>
                            <ruleList>
                                <registryTest>
                                    <key>${key}</key>
                                    <logic>exists</logic>
                                    <name>foo</name>
                                </registryTest>
                            </ruleList>
                        </continue>
                        <registryGet>
                            <key>${key}</key>
                            <name>foo</name>
                            <variable>foo_text</variable>
                        </registryGet>
                        <setInstallerVariable name="component_foo_exists" value="1">
                            <ruleList>
                                <compareText>
                                    <logic>contains</logic>
                                    <text>${foo_text}</text>
                                    <value>installed=1</value>
                                </compareText>
                            </ruleList>
                        </setInstallerVariable>
                    </actionList>
                </foreach>
            </actionList>
            <ruleList>
                <platformTest type="windows"/>
            </ruleList>
        </actionGroup>
        <actionGroup>
            <actionList>
                <foreach>
                    <variables>file</variables>
                    <values>${installdir}/components.txt ~/.components</values>
                    <actionList>
                        <continue>
                            <ruleList>
                                <fileTest>
                                    <condition>not_exists</condition>
                                    <path>${file}</path>
                                </fileTest>
                            </ruleList>
                        </continue>
                        <setInstallerVariable name="component_foo_exists" value="1">
                            <ruleList>
                                <fileContentTest>
                                    <path>${file}</path>
                                    <logic>contains</logic>
                                    <text>foo_component</text>
                                </fileContentTest>
                            </ruleList>
                        </setInstallerVariable>
                    </actionList>
                </foreach>
            </actionList>
            <ruleList>
                <platformTest type="unix"/>
            </ruleList>
        </actionGroup>
        <showInfo text="foo components is installed!">
           <ruleList>
              <isTrue value="${component_foo_exists}"/>
           </ruleList>
        </showInfo>
    </postInstallationActionList>

Although the above code works properly works, it is messy, hard to read and to reuse. It would be a much better approach to move all that verbose code to a different place, to avoid distracting from the real point of the code, which is notifying the user a certain component was installed. Using custom rules, that can be rewritten into a new rule definition:

    <functionDefinitionList>
        <ruleDefinition name="customComponentIsInstalled">
            <parameterList>
                <stringParameter name="name" default="" />
            </parameterList>
            <actionList>
                <setInstallerVariable name="component_exists" value="0"/>
                <actionGroup>
                    <actionList>
                        <foreach>
                            <variables>key</variables>
                            <values>HKEY_LOCAL_MACHINE\SOFTWARE\${project.windowsSoftwareRegistryPrefix}\components HKEY_LOCAL_MACHINE\SOFTWARE\${project.windowsSoftwareRegistryPrefix}\installed_components</values>
                            <actionList>
                                <continue>
                                    <ruleList>
                                        <registryTest>
                                            <key>${key}</key>
                                            <logic>exists</logic>
                                            <name>${name}</name>
                                        </registryTest>
                                    </ruleList>
                                </continue>
                                <registryGet>
                                    <key>${key}</key>
                                    <name>${name}</name>
                                    <variable>text</variable>
                                </registryGet>
                                <setInstallerVariable name="component_exists" value="1">
                                    <ruleList>
                                        <compareText>
                                            <logic>contains</logic>
                                            <text>${text}</text>
                                            <value>installed=1</value>
                                        </compareText>
                                    </ruleList>
                                </setInstallerVariable>
                            </actionList>
                        </foreach>
                    </actionList>
                    <ruleList>
                        <platformTest type="windows"/>
                    </ruleList>
                </actionGroup>
                <actionGroup>
                    <actionList>
                        <foreach>
                            <variables>file</variables>
                            <values>${installdir}/components.txt ~/.components</values>
                            <actionList>
                                <continue>
                                    <ruleList>
                                        <fileTest>
                                            <condition>not_exists</condition>
                                            <path>${file}</path>
                                        </fileTest>
                                    </ruleList>
                                </continue>
                                <setInstallerVariable name="component_exists" value="1">
                                    <ruleList>
                                        <fileContentTest>
                                            <path>${file}</path>
                                            <logic>contains</logic>
                                            <text>${name}_component</text>
                                        </fileContentTest>
                                    </ruleList>
                                </setInstallerVariable>
                            </actionList>
                        </foreach>
                    </actionList>
                    <ruleList>
                        <platformTest type="unix"/>
                    </ruleList>
                </actionGroup>
            </actionList>
            <ruleList>
                <isTrue value="${component_exists}"/>
            </ruleList>
        </ruleDefinition>
    </functionDefinitionList>

And its application:

    <postInstallationActionList>
        <showInfo text="foo components is installed!">
           <ruleList>
              <customComponentIsInstalled name="foo"/>
           </ruleList>
        </showInfo>
        <showInfo text="bar components is installed!">
           <ruleList>
              <customComponentIsInstalled name="bar"/>
           </ruleList>
        </showInfo>
    </postInstallationActionList>

The basics of how to define a new custom rule are as follow:

- `<name>`: The new custom rule will be available in other parts of the XML by its name. No other custom rule can be defined with the same `<name>`.
- `<actionList>`: This `<actionList>` defines the set of actions to wrap needed to obtain the results to be evaluated. In the simplest cases, you could omit this and simply use the ``<ruleList>`` of the custom rule. In these cases, you will be simply creating a named alias to a set of rules (a named `<ruleGroup>`). For example, if you want to create a rule that verifies if it is OS X or Windows, you could omit the `<actionList>` and create the above-mentioned named `<ruleGroup>`:

    <project>
      ...
      <functionDefinitionList>
        <ruleDefinition>
          <name>isOsxOrWindows</name>
          <ruleEvaluationLogic>or</ruleEvaluationLogic>
          <ruleList>
            <platformTest type="windows"/>
            <platformTest type="osx"/>
          </ruleList>
        </ruleDefinition>
      </functionDefinitionList>
      ...
    </project>

- `<parameterList>`: This `<parameterList>` defines the parameters of the new rule. They are used to interface with the inner actions in the `<ruleList>` and the inner ``<ruleList>``. The new custom rule will also support all the common action properties such as `<negate>`.

### 9.6. Additional Rule Lists

In addition to the previously mentioned `<ruleList>` and `<shouldPackRuleList>`, there are flow-control actions, such as `<while>` and `<if>` that allow specifying a `<conditionRuleList>` that controls the condition of the flow-control construct. They will behave like the regular `<ruleList>` but its evaluation logic is controlled by the `<conditionRuleEvaluationLogic>` setting.

### 9.7. List of Available Rules

##### Component Test

Perform check on a given component. The allowed properties in the `<componentTest>` rule are:

- `<logic>`: Comparison type
- `<name>`: Name of the component

Examples:

Deselect a component if it depends on another one that was deselected.

    <componentSelection>
      <deselect>subComponentA1</deselect>
      <ruleList>
        <componentTest>
          <logic>not_selected</logic>
          <name>componentA</name>
        </componentTest>
      </ruleList>
    </componentSelection>

`Additional Examples:` Example 1

##### Windows Firewall Test

Check whether or not a firewall is set up and running. Only available on Windows platform The allowed properties in the `<firewallTest>` rule are:

- `<type>`: Type of test

Examples:

Warn your users that a running firewall may interfere in the installation.

    <showWarning>
      <text>An Antivirus Software is running. You could get errors during the installation process. Please disable it before continuing.</text>
      <ruleList>
        <firewallTest type="enabled" />
      </ruleList>
    </showWarning>

##### Compare Text Length

Compare the length of a text. The allowed properties in the `<compareTextLength>` rule are:

- `<length>`: Length to compare with
- `<logic>`: Comparison type
- `<text>`: Text to compare the length of

Examples:

Check the length of a provided password.

    <passwordParameter>
       <name>password</name>
       <description>Password</description>
       <validationActionList>
          <throwError text="The password provided is too short.
            A minimum length of 8 characters is required">
            <ruleList>
              <compareTextLength>
                 <text>${password}</text>
                 <logic>less</logic>
                 <length>8</length>
              </compareTextLength>
            </ruleList>
          </throwError>
       </validationActionList>
    </passwordParameter>

`Additional Examples:` Example 1, Example 2, Example 3

##### String Test

Check the string type The allowed properties in the `<stringTest>` rule are:

- `<text>`: Text
- `<type>`: Type of string

Examples:

Check if a given username is alphanumeric only.

    <throwError text="The username can only contain alphanumeric characters!">
      <ruleList>
        <stringTest>
          <text>${username}</text>
          <type>not_alphanumeric</type>
        </stringTest>
      </ruleList>
    </throwError>

`Additional Examples:` Example 1, Example 2

##### Windows Account Test

Check whether or not a specified account has proper rights The allowed properties in the `<windowsAccountTest>` rule are:

- `<account>`: User or group name to check; if account does not exist, rule always returns false
- `<rights>`: Account rights to test for, separated by spaces; Example value: SeServiceLogonRight. A complete list can be obtained from http://msdn.microsoft.com/en-us/library/aa375728(v=VS.85).aspx

Examples:

Throw error if user cannot be used for running Windows services.

    <throwError>
        <text>Account ${service_account} cannot be used as a Windows service</text>
        <ruleList>
            <windowsAccountTest>
                <account>${service_account}</account>
                <rights>SeServiceLogonPrivilege</rights>
                <negate>1</negate>
            </windowsAccountTest>
        </ruleList>
    </throwError>

##### Host Validation

Validates whether or not a given hostname or IP address meets the given condition The allowed properties in the `<hostValidation>` rule are:

- `<condition>`: A valid host is one that can be resolved to an IP address and a valid IP is one that is syntactically correct
- `<host>`: Hostname or IP address to be checked
- `<type>`: Type of host specification

Examples:

Check if a provided IP is valid.

    <stringParameter>
      <name>machineIP</name>
      <description>Server IP</description>
      <validationActionList>
         <throwError text="The provided IP is malformed" >
           <ruleList>
             <hostValidation>
               <host>${machineIP}</host>
               <type>ip</type>
               <condition>is_not_valid</condition>
             </hostValidation>
           </ruleList>
         </throwError>
      </validationActionList>
    </stringParameter>

##### Regular Expression Match

Compare a text with a regular expression. The allowed properties in the `<regExMatch>` rule are:

- `<logic>`: Whether or not the rule will apply if the regular expression matches.
- `<pattern>`: Regular expression
- `<text>`: Text

Examples:

Get installation dir based on other path if it in form of (prefix)/common/….

    <setInstallerVariableFromRegEx>
        <name>installdir</name>
        <pattern>^(.*)/common/(.*?)$</pattern>
        <substitution>$1</substitution>
        <text>${path_retrieved_from_registry.unix}</text>
        <ruleList>
            <regExMatch>
                <logic>matches</logic>
                <pattern>^(.*)/common/(.*?)$</pattern>
                <text>${path_retrieved_from_registry.unix}</text>
            </regExMatch>
        </ruleList>
    </setInstallerVariableFromRegEx>

`Additional Examples:` Example 1, Example 2, Example 3

##### Compare Text

Compare a text with a value. The allowed properties in the `<compareText>` rule are:

- `<logic>`: Comparison type
- `<nocase>`: Case insensitive comparison
- `<text>`: Text
- `<value>`: Value

Examples:

Check if a given text contains a substring.

    <compareText>
        <logic>contains</logic>
        <text>${serverResponse}</text>
        <value>OK</value>
    </compareText>

`Additional Examples:` Example 1, Example 2, Example 3

##### Port Test

Allows you to test whether a port is free in the local machine. The allowed properties in the `<portTest>` rule are:

- `<condition>`: Condition to test for
- `<port>`: A port number

Examples:

Do not allow proceeding if specified port cannot be bound to.

    <stringParameter>
        <name>portNumber</name>
        <default>8080</default>
        <allowEmptyValue>0</allowEmptyValue>
        <width>40</width>
        <validationActionList>
            <throwError>
                <text>Port already taken</text>
                <ruleList>
                    <portTest>
                        <condition>cannot_bind</condition>
                        <port>${portNumber}</port>
                    </portTest>
                </ruleList>
            </throwError>
        </validationActionList>
    </stringParameter>

##### Single Instance Check

Check if there is another instance of the installer being executed. The allowed properties in the `<singleInstanceCheck>` rule are:

- `<logic>`: Condition to check.

Examples:

Check if any other instance of the installer is running.

      <throwError>
         <text>Another instance is running. This instance will abort</text>
         <ruleList>
             <singleInstanceCheck logic="is_running" />
         </ruleList>
      </throwError>

`Additional Examples:` Example 1, Example 2, Example 3

##### File Is Locked

Check if file is locked. The allowed properties in the `<fileIsLocked>` rule are:

- `<path>`: File or directory path to check

Examples:

Check if your application is running before trying to uninstall.

    <preUninstallationActionList>
      <actionGroup>
        <actionList>
           <showWarning>
              <text>It seems the application is in use, please close
              it and relaunch the uninstaller.</text>
           </showWarning>
           <exit/>
        </actionList>
        <ruleList>
          <fileIsLocked>
            <path>${installdir}/bin/yourApp.exe</path>
          </fileIsLocked>
        </ruleList>
      </actionGroup>
    </preUninstallationActionList>

##### Program Test

Check whether or not a program can be found in the system path. The allowed properties in the `<programTest>` rule are:

- `<condition>`: Condition to test for
- `<name>`: Program name

Examples:

Check if package is installed using rpm or dpkg, depending if dpkg command is available.

    <if>
        <actionList>
            <runProgram>
                <program>dpkg</program>
                <programArguments>-W ${native_packagename}</programArguments>
            </runProgram>
        </actionList>
        <conditionRuleList>
            <programTest>
                <condition>is_in_path</condition>
                <name>dpkg</name>
            </programTest>
        </conditionRuleList>
        <elseActionList>
            <runProgram>
                <program>rpm</program>
                <programArguments>-q ${native_packagename}</programArguments>
            </runProgram>
        </elseActionList>
    </if>
    <showWarning>
        <text>Package ${native_packagename} not found</text>
        <ruleList>
            <compareValues>
                <logic>does_not_equal</logic>
                <value1>${program_exit_code}</value1>
                <value2>0</value2>
            </compareValues>
        </ruleList>
    </showWarning>

##### Platform Test

Compare the system platform with a given platform name. The allowed properties in the `<platformTest>` rule are:

- `<type>`: Type of platform to test for

Examples:

Set executable permissions to your application on Unix.

    <changePermissions>
      <permissions>0755</permissions>
      <files>${installdir}/executables/*</files>
      <ruleList>
        <platformTest>
          <type>unix</type>
        </platformTest>
      </ruleList>
    </changePermissions>

`Additional Examples:` Example 1, Example 2, Example 3

##### Is True

The rule returns true if value is one of 1, yes or true. Otherwise it evaluates to false. The allowed properties in the `<isTrue>` rule are:

- `<value>`: String to test if it is true

Examples:

Create a shortcut if based on a parameter value.

    <createShortcuts>
      <destination>${windows_folder_startmenu}/${project.fullName}</destination>
      <shortcutList>
        <shortcut>
          <comment>Launches ${project.fullName}</comment>
          <name>Launch ${project.fullName}</name>
          <windowsIcon>%SystemRoot%\system32\cmd.exe</windowsIcon>
          <windowsExec>${installdir}/script/wrapped-shell.bat</windowsExec>
        </shortcut>
      </shortcutList>
      <ruleList>
        <isTrue>
          <value>${createShortcuts}</value>
        </isTrue>
      </ruleList>
    </createShortcuts>

`Additional Examples:` Example 1, Example 2, Example 3

##### Compare Values

Compare two values with each other. The allowed properties in the `<compareValues>` rule are:

- `<logic>`: Comparison type
- `<value1>`: First comparison operand
- `<value2>`: Second comparison operand

Examples:

Check if a given port is in the valid range.

    <stringParameter>
      <name>port</name>
      <description>Port:</description>
      <validationActionList>
        <throwError text="The provided port is out of range (1 to 65535)">
          <ruleEvaluationLogic>and</ruleEvaluationLogic>
          <ruleList>
             <compareValues value1="${port}" logic="less" value2="1"/>
             <compareValues value1="${port}" logic="greater" value2="65535"/>
          </ruleList>
        </throwError>
      </validationActionList>
    </stringParameter>

`Additional Examples:` Example 1, Example 2, Example 3

##### File Test

Perform test on a given directory or file. The allowed properties in the `<fileTest>` rule are:

- `<condition>`: Specifies the requirement to test over the given file
- `<path>`: File or directory path for the test

Examples:

Check if a directory is empty before trying to delete.

    <postUninstallationActionList>
      <deleteFile path="${installdir}">
        <ruleList>
          <fileTest>
            <path>${installdir}</path>
            <condition>is_empty</condition>
          </fileTest>
        </ruleList>
      </deleteFile>
    </postUninstallationActionList>

`Additional Examples:` Example 1, Example 2, Example 3

##### File Content Test

Check whether a file contains or does not contain a text. The allowed properties in the `<fileContentTest>` rule are:

- `<encoding>`: Encoding of the text file
- `<logic>`: Test type
- `<path>`: Path to file that contains text for comparison
- `<text>`: Text to compare with

Examples:

Add some text to a file if it does not already contain it.

    <addTextToFile>
      <file>${installdir}/report.txt</file>
      <text>${summaryText}</text>
      <ruleList>
        <fileContentTest>
          <path>${installdir}/report.txt</path>
          <logic>does_not_contain</logic>
          <text>${summaryText}</text>
        </fileContentTest>
      </ruleList>
    </addTextToFile>

`Additional Examples:` Example 1, Example 2

##### Rule Group

Group a set of rules. The allowed properties in the `<ruleGroup>` rule are:

- `<ruleEvaluationLogic>`: Rule evaluation logic
- `<ruleList>`: List of rules to be grouped

Examples:

Show warning if operating system is Windows Server 2003 or Windows Server 2008, but not Windows Server 2008 R2.

    <showWarning>
        <text>Windows Server 2008 (not R2) and Windows Server 2003 is not supported</text>
        <ruleEvaluationLogic>or</ruleEvaluationLogic>
        <ruleList>
            <ruleGroup>
                <ruleEvaluationLogic>and</ruleEvaluationLogic>
                <ruleList>
                    <platformTest>
                        <negate>1</negate>
                        <type>windows-2008-r2</type>
                    </platformTest>
                    <platformTest>
                        <type>windows-2008</type>
                    </platformTest>
                </ruleList>
            </ruleGroup>
            <platformTest>
                <type>windows-2003</type>
            </platformTest>
        </ruleList>
    </showWarning>

`Additional Examples:` Example 1, Example 2

##### Compare Versions

Compare two versions. The allowed properties in the `<compareVersions>` rule are:

- `<logic>`: Test type
- `<version1>`: First comparison operand
- `<version2>`: Second comparison operand

Examples:

Check if the current application is newer than the installed in the machine.

      <registryGet>
       <key>HKEY_LOCAL_MACHINE\SOFTWARE\${project.windowsSoftwareRegistryPrefix}</key>
       <name>Version</name>
       <variable>oldVersion</variable>
      </registryGet>

      <throwError text="The installed version is the same or newer than
    the current. Aborting">
        <ruleList>
          <compareVersions>
            <version1>${oldVersion}</version1>
            <logic>greater_or_equal</logic>
            <version2>${project.version}</version2>
          </compareVersions>
        </ruleList>
      </throwError>

`Additional Examples:` Example 1, Example 2

##### User Test

Check if a particular user exists in the system or has a valid password. The allowed properties in the `<userTest>` rule are:

- `<logic>`: Specifies the requirement to test over the given username.
- `<password>`: If test logic is set to verify the password, the password to be checked. Currently only available on the Windows platform
- `<username>`: User name that will be checked. In the case of using Windows domains, it needs to be specified in the form username@DOMAIN

Examples:

Check if a given user and password pair is valid.

    <parameterGroup>
      <name>userandpass</name>
      <explanation>Please enter the username and password of your account</explanation>
      <parameterList>
        <stringParameter>
          <name>username</name>
          <description>Username</description>
        </stringParameter>
        <passwordParameter>
          <ask>yes</ask>
          <name>password</name>
          <description>Password</description>
        </passwordParameter>
      </parameterList>
      <validationActionList>
        <throwError text="The provided credentials are not valid">
          <ruleList>
            <userTest>
              <logic>is_windows_admin_account</logic>
              <username>${username}</username>
              <password>${password}</password>
            </userTest>
          </ruleList>
        </throwError>
      </validationActionList>
    </parameterGroup>

##### Is False

The rule returns false if value is one of 1, yes or true. Otherwise it evaluates to true. The allowed properties in the `<isFalse>` rule are:

- `<value>`: String to test if it is false

Examples:

Require to install Java if it is not installed.

    <autodetectJava>
      <abortOnError>0</abortOnError>
      <promptUser>0</promptUser>
      <showMessageOnError>0</showMessageOnError>
    </autodetectJava>
    <throwError text="Java is required but was not found.
      Please install it an relaunch this installer">
      <ruleList>
        <isFalse>
          <value>${java_autodetected}</value>
        </isFalse>
      </ruleList>
    </throwError>

`Additional Examples:` Example 1, Example 2, Example 3

##### Mac OS X Service Test

Check whether or not a service exists and whether or not it is running. Checking if service exists requires Mac OS X version 10.4 or later. Checking if service is running requires Mac OS X 10.5 or later. The allowed properties in the `<osxServiceTest>` rule are:

- `<condition>`: Condition to test for
- `<service>`: Name of service

Examples:

Stop OSX service yourservice if it is currently running.

    <stopOSXService>
        <serviceName>yourservice</serviceName>
        <ruleList>
            <osxServiceTest>
                <condition>is_running</condition>
                <service>yourservice</service>
            </osxServiceTest>
        </ruleList>
    </stopOSXService>

`Additional Examples:` Example 1

##### Windows Antivirus Test

Check whether or not antivirus is set up and running. Only available on Windows platform The allowed properties in the `<antivirusTest>` rule are:

- `<product>`: Product to test, or any product
- `<type>`: Type of test

Examples:

Warn your users that a running antivirus may interfere in the installation.

    <showWarning>
      <text>An Antivirus Software is running. You could get errors during the installation process. Please disable it before continuing.</text>
      <ruleList>
        <antivirusTest type="enabled" />
      </ruleList>
    </showWarning>

##### Resource Limit Test

Check if resource limit matches requirements. The allowed properties in the `<resourceLimitTest>` rule are:

- `<limitType>`: Limit type
- `<logic>`: Comparison type
- `<type>`: Resource Type To Check
- `<value>`: Value

Examples:

Throw an error if less than 1024 open files can be opened at once.

    <throwError>
        <text>Port already taken</text>
        <ruleList>
            <resourceLimitTest>
                <type>open_files</type>
                <logic>less</logic>
                <value>1024</value>
            </resourceLimitTest>
        </ruleList>
    </throwError>

##### File Exists

Check for the existence of a given directory or file. The allowed properties in the `<fileExists>` rule are:

- `<path>`: File or directory path for the test, accepts wildcards.

Examples:

Check if the selected directory already contains an installation.

    <throwError text="It seems the selected installation directory
      contains an old installation. Please, choose another one.">
      <ruleList>
        <fileExists>
         <path>${installdir}/uninstall</path>
        </fileExists>
      </ruleList>
    </throwError>

`Additional Examples:` Example 1, Example 2, Example 3

##### Check Free Disk Space

Check whether or not enough free disk space is available The allowed properties in the `<checkFreeDiskSpace>` rule are:

- `<logic>`: Comparison type
- `<path>`: Path to the folder or disk
- `<size>`: Size of free disk space to check for
- `<units>`: Size units for the checked value.

Examples:

Check if the selected installation directory has enough disk space.

    <directoryParameter>
      <name>installdir</name>
      ...
      <validationActionList>
        <throwError>
          <text>You don't have enough disk space to install the application,
          please select another installation directory</text>
          <ruleList>
            <checkFreeDiskSpace>
              <logic>less</logic>
              <path>${installdir}</path>
              <size>${required_diskspace}</size>
            </checkFreeDiskSpace>
          </ruleList>
        </throwError>
      </validationActionList>
    </directoryParameter>

`Additional Examples:` Example 1, Example 2

##### Process Test

Check if a particular process exists in the system. Currently only supported in Windows, Linux, OS X. The allowed properties in the `<processTest>` rule are:

- `<logic>`: Check whether or not the process is running.
- `<name>`: Exact process name that will be checked.

Examples:

Wait for myapp.exe program to exit before continuing.

    <showProgressDialog>
        <title>Waiting for myapp.exe to exit</title>
        <actionList>
            <while>
                <actionList>
                    <wait>
                        <ms>1000</ms>
                    </wait>
                </actionList>
                <conditionRuleList>
                    <processTest>
                        <logic>is_running</logic>
                        <name>myapp.exe</name>
                    </processTest>
                </conditionRuleList>
            </while>
        </actionList>
    </showProgressDialog>

`Additional Examples:` Example 1, Example 2, Example 3

##### Registry Test

Perform tests over a registry entry. You can provide either a key or a key and a name The allowed properties in the `<registryTest>` rule are:

- `<key>`: Registry key
- `<logic>`: Comparison type
- `<name>`: Entry name to test for existence
- `<type>`: Type of the key to check with the is_type or is_not_type logic
- `<wowMode>`: Determines whether we want to access a 32-bit or 64-bit view of the Registry

Examples:

Read previous installation location from registry if it was already installed.

    <registryGet>
        <key>HKEY_LOCAL_MACHINE\SOFTWARE\${project.windowsSoftwareRegistryPrefix}</key>
        <name>Location</name>
        <variable>installdir</variable>
        <ruleList>
            <registryTest>
                <key>HKEY_LOCAL_MACHINE\SOFTWARE\${project.windowsSoftwareRegistryPrefix}</key>
                <logic>exists</logic>
                <name>Location</name>
            </registryTest>
        </ruleList>
    </registryGet>

`Additional Examples:` Example 1, Example 2, Example 3

##### Windows Service Test

Check whether a service exists and whether is running The allowed properties in the `<windowsServiceTest>` rule are:

- `<condition>`: Condition to test for
- `<service>`: Name of service

Examples:

Stop your service if it is running.

    <stopWindowsService>
      <serviceName>yourservice</serviceName>
      <displayName>Your Service</displayName>
      <delay>15000</delay>
      <ruleList>
         <windowsServiceTest>
           <condition>is_running</condition>
           <service>yourservice</service>
         </windowsServiceTest>
      </ruleList>
    </stopWindowsService>

`Additional Examples:` Example 1, Example 2

8. Actions |  | 10. User Interface