vpodans
Posts: 35
Joined: Tue Dec 27, 2011 3:03 pm

Weird behavior in property retrieval in custom actions

I have a custom action (UI sequence) that writes some property, say PROP1:

Code: Select all

AI_SetMsiProperty PROP1 "Some value"
Then in some UI dialog in init actions, I have another custom action (no sequence) which reads same property:

Code: Select all

$PropName = "PROP1"
$PropValue = AI_GetMsiProperty $PropName
Note that property name is set inside variable (in fact, its name is built in runtime, but final property name is exactly the same) not as literal. And in this case, $PropValue receives empty value, rather than the one set by previous custom action. What is the weirdest thing here is if I put:

Code: Select all

# AI_GetMsiProperty PROP1
which is a comment in PowerShell so has to be ignored, but then property value is retrieved correctly. I've attached a minimal repro project. Look at custom actions: Write is setting some value to PROP1 in UI sequence. Then Read is configured in Init Actions in Welcome dialog. I set property name in variable then read. And in the end I added pointless (from PowerShell perspective) line which reads property as literal. This makes the code above to work. When you remove this line, PROP1 won't be retrieved by a script above.

I suspect that you do some static script parsing before actually execute it, but it doesn't make my life easier.

Just to make a point: I have a custom action which contains some common logic to process properties and I determine actual property name to read in runtime, say:

Code: Select all

$context = AI_GetMsiProperty
$PropName = switch ($context) {
  # do case statements to figure out which property to read
}

$PropValue = AI_GetMsiProperty $PropName
# do whatever logic needed to handle requested property value
which doesn't allow me to use constants or literals in the script, without duplicating scripts which is a no go for me.

Any way to overcome this issue? Maybe, there is a better way to handle dynamic (determined in runtime) MSI properties?
Attachments
Your Application.aip
(15.37 KiB) Downloaded 6 times
®
Liviu
Posts: 1325
Joined: Tue Jul 13, 2021 11:29 am
Contact: Website

Re: Weird behavior in property retrieval in custom actions

Hello,

The problem comes from the following lines:

Code: Select all

$PropName = "PROP1"
$PropValue = AI_GetMsiProperty $PropName

You can use this instead:

$PropValue = AI_GetMsiProperty PROP1
write-host "$PropName = $PropValue"

[System.Reflection.Assembly]::LoadWithPartialName('System.Windows.Forms')
[System.Windows.Forms.MessageBox]::Show($PropValue)


Our AI_GetMsiProperty function cannot process parameters there, you will need to add the property name directly.

Let us know if you have any questions.

Best regards,
Liviu
________________________________________
Liviu Sandu - Advanced Installer Team
Follow us: Twitter - Facebook - YouTube
vpodans
Posts: 35
Joined: Tue Dec 27, 2011 3:03 pm

Re: Weird behavior in property retrieval in custom actions

You can use this instead:

$PropValue = AI_GetMsiProperty PROP1
write-host "$PropName = $PropValue"
And this is the whole problem: I don't know exact property name to read at compile time, it is determined in runtime based on other properties. Here is an example:

I have a bunch of properties, PROP1-PROP9. In the script, I know "PROP" part at compile time, but last character is determined based on another property, say "MY_INDEX":

Code: Select all

$PropIndex = AI_GetMsiProperty MY_INDEX
$PropName = "PROP" + $PropIndex
$PropValue = AI_GetMsiProperty $PropName
as you can see, I can't use your approach, because exact property name is not known.
®
Liviu
Posts: 1325
Joined: Tue Jul 13, 2021 11:29 am
Contact: Website

Re: Weird behavior in property retrieval in custom actions

Hello,

In this case, you will need to add the if condition to your script and use the property name directly in the if statement.

Something like this:

Code: Select all

$PropName = "PROP2"


if ($PropName -eq "PROP1") {
    $PropValue = AI_GetMsiProperty "PROP1"
    [System.Reflection.Assembly]::LoadWithPartialName('System.Windows.Forms')
    [System.Windows.Forms.MessageBox]::Show($PropValue)
}
elseif ($PropName -eq "PROP2") {
    $PropValue = AI_GetMsiProperty "PROP2"
    [System.Reflection.Assembly]::LoadWithPartialName('System.Windows.Forms')
    [System.Windows.Forms.MessageBox]::Show($PropValue)
}
elseif ($PropName -eq "PROP3") {
    $PropValue = AI_GetMsiProperty "PROP3"
    [System.Reflection.Assembly]::LoadWithPartialName('System.Windows.Forms')
    [System.Windows.Forms.MessageBox]::Show($PropValue)
}
else {
    Write-Host "Unknown property: $PropName"
}

This is the only solution I can think of in your scenario.

Also, keep in mind that these properties must already be created on the Properties page.

Let us know if you have any questions.

Best regards,
Liviu
________________________________________
Liviu Sandu - Advanced Installer Team
Follow us: Twitter - Facebook - YouTube

Return to “Common Problems”