3

I am maintaining an old application in which the users configuration is stored in registry. It is left behind when uninstalling. I am now re-writing the installer in WiX.

The installer should add a default value in the registry if there are none there, otherwise the existing value should be left alone.

I was thinking on how to do this in WiX. And the solution I came up with is somewhat cumbersome:

 <Property Id="MY_PROPERTY">
      <RegistrySearch Root="HKLM" Key="SOFTWARE\MyProduct" Name="MyProperty" Type="raw" />
  </Property>

  <CustomAction Id="ca.SetDefaultValue" Property="MY_PROPERTY" Value="DefaultValue" />

  <InstallExecuteSequence>
      <Custom After="RegistrySearch" Action="ca.SetDefaultValue">Not MY_PROPERTY</Custom>
  </InstallExecuteSequence>

  <Component Id="c.Registry">
      <RegistryValue Root="HKLM" Key="SOFTWARE\MyProduct" Name="MyProperty" Type="string" Value="[MY_PROPERTY]" />
  </Component>

So do a registry search to find old value. If not set, set to default value using a scheduled custom action. Then create the value "as usual".

Anyone who can think up a smoother way to do this?

Note that I cannot use convenient variables like Installed since values might be there, left behind by a previous, now uninstalled, version.

leiflundgren
  • 2,876
  • 7
  • 35
  • 53

2 Answers2

8

Start with the Wix Remember Property pattern but take it one step farther. After AppSearch runs and the REMEMBERME property does or doesn't get a value, use a SetProperty custom action to assign a default value if REMEMBERME="".

I take it one step farther though. I have a concept I call "property precedence". Basically it's a list of priorities for how a property should get it's value.

Highest to lowest:

  1. properties inputted during the UI
  2. public properties passed in at the command line
  3. Properties found during AppSearch
  4. Default values defined in the Property table

In other words, during a first time silent install with no properties passed at the command line the default value in the property table should be used.

During a second time silent install with no properties passed at the command line, the remembered value should take priority over the default value. (If different)

During a first of second silent install, a property passed at the command line should be considered an override value and take priority over both the default and remembered value.

During an interactive install the above rules take place and the UI should display that value. If the user changes the value then this is the ultimate value.

I'll leave it up to you of how to implement the various custom actions to do this. It generally involves a temp prop and a real prop and a series of Set Property CA's with the right execution scheduling and conditions to do what you want it to do.

Yan Sklyarenko
  • 31,557
  • 24
  • 104
  • 139
Christopher Painter
  • 54,556
  • 6
  • 63
  • 100
  • 2
    Do you have an example implementation of "property precedence" somewhere? I'm struggling with the same as OP right now, plus hoping to implement exactly what you suggest. – Johny Skovdal Sep 10 '14 at 06:41
1

You haven't explicitly set keypath=yes on the registry value in your component. However, in that case wix will select the first child item which can serve as the keypath. From the wix component element documentation:

If KeyPath is not set to 'yes' for the Component or for a child Registry value or File, WiX will look at the child elements under the Component in sequential order and try to automatically select one of them as a key path.

Therefore, your registry value is the keypath of the component which installs it. This means that the component will not be installed if the registry value already exists. As far as I can tell, that's the behavior you want.

Community
  • 1
  • 1
Wim Coenen
  • 66,094
  • 13
  • 157
  • 251