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

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

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 158749 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 158749 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 158749 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 158744 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
murrayPug
Posts: 1
Joined: Wed Sep 13, 2023 8:05 am

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

Hi Catalin,
Great example of how to use the combo and list box features.! Thank you!

Please can you advise how i can modify this example to show additional properties based on the value selected in the combo box.
In my example project (attached).

The combo box in my example lists certificates install on the machine. When selecting a certificate from the combo box list, on the same dialog page, i want to show some properties of the selected certificate like 'expiry date' and 'Self signed'. And if the certificate selection is changed in the combo list, the properties being displayed should also.

Thanks for your help
Attachments
Populate CheckList control with values from PSScript.aip
Includes 'GetCerts' custom action
(38.46 KiB) Downloaded 960 times
Combo box - list certificates
Combo box - list certificates
AdvInstaller-certlist.png (113.2 KiB) Viewed 46691 times
Selected Certificate - show additional properties
Selected Certificate - show additional properties
AdvInstaller-certlist-withprops.png (61.95 KiB) Viewed 46691 times
Catalin
Posts: 6796
Joined: Wed Jun 13, 2018 7:49 am

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

Hello and welcome to our forums,

First of all, thank you for your kind words!

I am glad to hear my article was of help for you.

From what I can see, you have an ongoing thread with one of my colleagues over the email.

If possible, please continue the thread there so we don't have more people working on the same ticket.

Thank you for your understanding!

Best regards,
Catalin
Catalin Gheorghe - Advanced Installer Team
Follow us: Twitter - Facebook - YouTube
Iryna
Posts: 6
Joined: Wed Jun 12, 2024 7:15 am

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

Hello! I downloaded your sample Populate CheckList control with values from PSScript.aip. And I changed it. I created Visual studio project C# Custom Action (.Net framework)
The code of the project:

Code: Select all

namespace MyNamespace
{
	public class CustomActions
	{
		public static int CustomAction1(string aMsiHandle)
		{
            MsiSession session = new MsiSession(aMsiHandle);
            session.SetProperty("AI_LISTBOX_DATA", "CHECKLIST_1_PROP|1#Text1|2#Text2|3#Text3|");
            return 0;
        }
	}
I got dll and created new active action. (Call Function from Attached native dll - Add custom action without sequence - selected my dll for custom action -
I specified as a function MyNamespace.CustomActions.CustomAction1). Then I selected CheckList on CheckListDlg and changed powerShellScriptInline to my Custom Action from the list. But now I have an error "There is a problem with this Windows installer package. A dll required for this install to complete could not be run. Contact you support personnel or package vendor". If I back script then all work fine. Possible do you have an idea what wrong with my code or do you have another sample with dll to fill a checkList?
Catalin
Posts: 6796
Joined: Wed Jun 13, 2018 7:49 am

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

Hello and welcome to our forums,

That is happening because the custom action is executing before your DLL is copied on the disk.

A possible way to avoid this is by using temporary files.

Temporary Files Operations in the Files and Folders Page

These files are copied on the machine much earlier, during the CostFinalize standard action.

"CostFinalize" is part of "Paths Resolution" action group so your C# custom action should therefore be scheduled after "Paths Resolution".

In your case, since the action is executed on a dialog, this should work just fine.

Best regards,
Catalin
Catalin Gheorghe - Advanced Installer Team
Follow us: Twitter - Facebook - YouTube
Iryna
Posts: 6
Joined: Wed Jun 12, 2024 7:15 am

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

Hello, Catalin! Thank you very much for your help!
I understood what the problem was. I translated my code to Power Shell script. But now I have another problem. I have a checklist populated by a Power Shell script. I need to write an expression that checks whether the value 2025 is contained in the checked checklist items. The checklist property has name CHECKLIST_1_PROP. The expression CHECKLIST_1_PROP=2025 works if the value 2025 is checked only , but if more items are checked, for example 2023 and 2025, then this expression does not work. How to create correct condition to check the item 2025 is checked?
Catalin
Posts: 6796
Joined: Wed Jun 13, 2018 7:49 am

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

Hello,

You are always welcome! :)

Now, if the property contains more values, they are most likely separated somehow (using a separator such as "," or perhaps "|").

What we need to do here is retrieve the entire property and using the separator, find our value. If the property contains our value, we can set another property to either TRUE or FALSE.

Hope this helps!

Best regards,
Catalin
Catalin Gheorghe - Advanced Installer Team
Follow us: Twitter - Facebook - YouTube
Iryna
Posts: 6
Joined: Wed Jun 12, 2024 7:15 am

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

Hello! Thank you Catalin for your help! I would like to report my results.
Correct expression to check value 2025 contains in CHECKLIST_1_PROP is CHECKLIST_1_PROP><"2025".
Unfortunately, I was unable to get values ​​from the property programmatically and I was unable to get the checked from checklist values ​​programmatically. If you have example how to do it then share it please.
Since I could not solve my problems programmatically, I solved them in a different way.
I needed to set all default items ​​in the checklist to checked. I created an InitEvent for my checklist(set installer property value - property:CHECKLIST_1_PROP , argument : Prop). Prop is my global property. I created Prop on the property tab. But I set it in active action for populate Checklist.
Catalin
Posts: 6796
Joined: Wed Jun 13, 2018 7:49 am

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

Hello Iryna,

Thank you for your followup on this.

Indeed, your solution is much more elegant than mine.

Thank you for sharing that with us, I'm sure this will be of help for further users facing a similar scenario. :)

Please let me know if you have any other questions and I will gladly assist.

Best regards,
Catalin
Catalin Gheorghe - Advanced Installer Team
Follow us: Twitter - Facebook - YouTube
Iryna
Posts: 6
Joined: Wed Jun 12, 2024 7:15 am

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

Hello again! I have a question. When I change the Package type from exe to msi, the checkboxes in the checklist are not visible and I cannot check the boxes. It turns out that I can work with checklist only when Package type is exe, right?
Catalin
Posts: 6796
Joined: Wed Jun 13, 2018 7:49 am

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

Hello Iryina,

When you add the CheckList control to a new project, you will see a note that it enables the "Enhanced User Interface" option by default. This option can only be used if the output is an EXE, so your assumption is indeed correct.

Best regards,
Catalin
Catalin Gheorghe - Advanced Installer Team
Follow us: Twitter - Facebook - YouTube
Iryna
Posts: 6
Joined: Wed Jun 12, 2024 7:15 am

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

Catalin, thank you very much for your help!
Catalin
Posts: 6796
Joined: Wed Jun 13, 2018 7:49 am

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

You are always welcome, Iryna!

Glad I was able to help.

Best regards,
Catalin
Catalin Gheorghe - Advanced Installer Team
Follow us: Twitter - Facebook - YouTube

Return to “Sample Projects”