Catalin
Posts: 4206
Joined: Wed Jun 13, 2018 7:49 am

Populate CheckList / ComboBox / ListBox controls with values received from a custom script

Tue Feb 25, 2020 2:26 pm

Hello guys,

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:
getpsdrive.png
getpsdrive.png (32.74 KiB) Viewed 10502 times

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
getpsdrive_extended.png
getpsdrive_extended.png (16.22 KiB) Viewed 10502 times

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:
checklist.png
checklist.png (108.72 KiB) Viewed 10502 times

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|...
2. Use the predefined "Populate ListBox" custom action

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


checklist_events.png
checklist_events.png (122.02 KiB) Viewed 10497 times


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
Catalin Gheorghe - Advanced Installer Team
Follow us: Twitter - Facebook - YouTube

Return to “Sample Projects”