How to set a check box to “unchecked” from the msi

2019-01-26 10:33发布

问题:

I have an msi (authored with WIX) that has a check box bound to a custom property (call it MY_PROPERTY). I would like to run this msi from the command line, specifying 0 (unchecked) or 1 (checked) for this property. My script will determine the appropriate value (based on the environment) and inject that value into the msiexec command line. My command line looks something like this:

msiexec /i my_installer.msi MY_PROPERTY=$value

Where $value is 1 or 0, depending on the environment. The problem is that no matter what value I supply for MY_PROPERTY at the command line, the check box is always checked (and the property will always be set to 1). The only way to make the checkbox unchecked is to not specify the property (leave it undefined). It should be noted that this behavior occurs regardless of whether or not the UI is showing (adding "/quiet" to the above command line doesn't change this behavior).

This msdn post seems to indicate that this is a known "bug" in windows installer (or more accurately, whatever authoring system wrote the msi). A post-build msi hack is proposed as the solution. I'm wondering if anyone has encountered this issue and come up with a better workaround/solution. Thanks!

Update

I see three solutions to this problem:

  1. From @Damien, have the wrapper script not pass the property to msiexec when its value is 0. This makes the script more complex and would probably prevent me from being able to override the value of a check box that defaults to "checked".
  2. From @Michael Urman, add a custom action that clears the property if its value is zero. This makes the msi more complex, and I would have to add such a custom action for every check box in the UI.
  3. Another idea is to simply disallow the use of check boxes in our msi installers, and use radio boxes or drop-downs for "true/false" questions instead. While this restricts the UI options for our installers, it woudl allow the wrapper scripts to remain simple, and does not require custom actions to "hack" the properties.

I'm currently leaning towards option 3, although option 1 is probably the best answer to my original question. Any thoughts?

回答1:

This is how it is "supposed" to work - basically, the property doesn't exist until a user checks the checkbox, then it is "set" (exists). So if you want to do a custom action when a checkbox is checked, you test for the existence of the property as a condition for running the custom action, instead of checking for the value that the custom prop is set to.

I think the best way to handle this from the command line is what you have already mentioned: if you want the checkbox to be selected, specifiy the custom prop on the command line, otherwise, don't and the checkbox will not be selected.



回答2:

As you've discovered, checkboxes are true (checked) when the property is defined (non-blank) and false (unchecked) when the property is undefined (blank). It sounds like you need to convert an environment 1 or 0 string to a checkbox true/false, where the 1 or 0 is passed in at the command line. Try using a set-property custom action that sets your property to {} (blank) with a condition of when the property is already "0". Schedule it early in both the Install UI and Install Execute sequences.

Late Update: Regarding the need for multiple custom actions to handle this for multiple checkboxes, you have a choice. You can either create multiple set-property actions (benefit: easy to tell what they're doing; cost: many of them), or you can create a single code-based custom action which walks the Checkbox table for a list of properties to convert from 0 to blank (benefit: one action; cost: poorly documented, custom code). A secondary advantage to the latter approach is that you can handle unusual Value settings, such a check box that should set the property to 0 when checked.