Question: How can we populate a CheckList / ComboBox / ListBox control with values received from a custom script?
Particular scenario: How can we get all the available drives and show them as checkboxes in a custom dialog?
License required: Enterprise or above!
Here, we will focus on the particular question. With that as a starting point, I believe it will be much easier for you to achieve this in your own custom scenario.
For scenarios like this one, PowerShell is my go-to language. However, please feel free to use any other custom action type, such as: VBScript, JScript, C# executable/.DLL or a C++ executable/.DLL
Let's get this started!
First of all, in order to get a list of all drives on a machine, the "Get-PSDrive" cmdlet can be used. This cmdlet returns something similar to this:
From that, we would like to further parse the content and get only the root letters (e.g. A:\) when the Provider property is of "FileSystem" type. To do so, we can use the following:
Code: Select all
$drives = Get-PSDrive -PSProvider FileSystem | Select Root
As it can be seen in the above screenshot, we save the return value of our cmdlet in a variable called $drives, which is an array.
Now, the rest of our script will be related to populating a CheckList / ComboBox / ListBox control. For more information about this, please refer to our "Working with Windows Installer ComboBox and ListBox controls" which explains how this can be achieved. Populating a CheckList control is identical to populating a ListBox control.
Short explanation:
Let's consider we have a dialog with a CheckList control in it:
As any other control, this dialog has a property assigned to it - in our case "CHECKLIST_1_PROP". In order to populate it, we will need to do the following:
1. Set the AI_LISTBOX_DATA property to the following:
Code: Select all
CHECKLIST_1_PROP|Value 1|Value 2|Value 3|...
For more information about this, please refer to the above linked article.
While developing the script, I have commented every line of it, therefore I will no longer explain it here. Here is the script:
Code: Select all
# Block for declaring the script parameters.
Param()
# Your code goes here.
# Get the drives by their root property and save them into a variable
$drives = Get-PSDrive -PSProvider FileSystem | Select Root
# The result is an array of elements. We will have to browse it and create a string composed of the array elements,
# separated by a pipe character ("|")
for($i = 0; $i -lt $drives.Count; $i++){
$temp = -join ($drives[$i].Root,'|')
# Creating a string containing the elements of the array separated by a pipe
$new += $temp
# For instance, on my machine, the $new variable looks like this: A:\|C:\|D:\|
# As it can be seen, one more pipe character is added at the end of the string. We will have to remove that
}
# Here, we will replace the "\" from our path with "\\". We need to escape the "\" character
# with another "\", otherwise the "PopulateListBox" cutsom action will ignore it (this is most probably
# a limitation of our "PopulateListBox" custom action)
$final = $new.Replace("\","\\")
# The AI_LISTBOX_DATA must be set like this: CHECKLIST_1_PROP|Value 1|Value 2| Value 3|...
# We will concatenate our strings in order to obtain that form.
$conc = -join("CHECKLIST_1_PROP|",$final.Substring(0,$final.Length-2))
# Setting the AI_LISTBOX_DATA property as discussed above
AI_SetMsiProperty AI_LISTBOX_DATA $conc
How to implement this in Advanced Installer:
1. First, we will need to add the custom actions. To do so, please go to "Custom Actions" page and add the following custom actions, without sequence (press the "Add custom action without sequence" button which is placed to the right side of the custom action's name):
- PowerShellScriptInline
- PopulateListBox
In the inline script, please copy the script's content provided above.
2. Now, it is time to execute our custom actions. We have specifically added them as custom actions without sequence so we can trigger them as dialog events. We will execute them when our custom dialog is initialized - meaning we will add the custom actions as "Init Events". To do so, please go to "Dialogs" page and add add two events as it follows:
- Event: Execute custom action
Argument: PowerShellScriptInline
Condition: leave unchanged
- Event: Execute custom action
Argument: PopulateListBox
Condition: leave unchanged
This way, the events will be triggered when our custom dialog will be initialized.
Additionally, for your reference, you can find attached to this thread a .AIP file which you can download, build & run on your machine:
Hope this helps!
Best regards,
Catalin