I am trying to edit an XML file with Wix. I am using the WixUtilExtension bundled with Wix 3.7. The xml file is a settings file created in Visual Studio 2010 for a C# application. In this file, I am using an element which is used to store multiple string values in an array. This is the content of the unaltered settings file:
<configuration>
<applicationSettings>
<AppName.Properties.Settings>
<setting name="StringArray" serializeAs="Xml">
<value>
<ArrayOfString xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
</ArrayOfString>
</value>
</setting>
</AppName.Properties.Settings>
</applicationSettings>
</configuration>
I want to add <string>
elements to the <ArrayOfString>
element in this file. One way to do this is by using an <XmlConfig>
element from the wix/UtilExtension namespace. I have added this element to the component which holds the config file like this:
<Component Id="ProductComponent" Guid="$(var.ConfigGuid)">
<File Source="SettingsFile.exe.config" KeyPath="yes" Id="FILE_config" />
<util:XmlConfig
Name="string"
Value="My value"
File="[INSTALLFOLDER]SettingsFile.exe.config"
Id="String1"
On="install"
Action="create"
Node="element"
ElementPath="/configuration/applicationSettings/AppName.Properties.Settings/setting[\[]@name='StringArray'[\]]/value/ArrayOfString"
Sequence="100"
/>
</Component>
This results in the addition of one <string>
element to the <ArrayOfString>
element. To add another <string>
element to the settings file, another XmlConfig element has to be added to the <Component>
element of the setup project with a different Id attribute and a higher value for the Sequence attribute like this:
<util:XmlConfig
Name="string"
Value="My second value"
File="[INSTALLFOLDER]SettingsFile.exe.config"
Id="String2"
On="install"
Action="create"
Node="element"
ElementPath="/configuration/applicationSettings/AppName.Properties.Settings/setting[\[]@name='StringArray'[\]]/value/ArrayOfString"
Sequence="101"
/>
After installation of the msi, the <ArrayOfString>
element in the settings file looks like this:
<ArrayOfString xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<string>My value</string><string>My second value</string></ArrayOfString>
I have found out that it is possible to set the Value attribute of an <XmlConfig>
attribute to the value of a property like this:
<Property Id="STRING1VALUE" Value="My value" />
<util:XmlConfig Value="[STRING1VALUE]" ... />
This is good. I would like the user to be able to add multiple values in the installation process dynamically so that a variable amount of <string>
elements can be added to the settings file.
My first approach was to use a <?foreach?>
statement like this:
<?define values="My value;My second value"?>
<?foreach value in $(var.values)?>
<util:XmlConfig
Name="string"
Value="$(var.value)"
File="[INSTALLFOLDER]SettingsFile.exe.config"
Id="String$(var.value)"
On="install"
Action="create"
Node="element"
ElementPath="/configuration/applicationSettings/AppName.Properties.Settings/setting[\[]@name='StringArray'[\]]/value/ArrayOfString"
Sequence="101"
/>
<?endforeach?>
There are a few problems with this approach:
- The foreach statement uses a preprocessor variable which cannot be set to the value of a property.
- The value of the Sequence attribute stays the same.
I would like the user to store the values for the string elements in a Property which separates the values by semicolons and then parse them in a foreach statement like this:
<Property Id="VALUES" Value="My value;My second value" />
<?foreach value in [VALUES]?>
<util:XmlConfig
Name="string"
Value="$(var.value)"
File="[INSTALLFOLDER]SettingsFile.exe.config"
Id="String$(var.value)"
On="install"
Action="create"
Node="element"
ElementPath="/configuration/applicationSettings/AppName.Properties.Settings/setting[\[]@name='StringArray'[\]]/value/ArrayOfString"
Sequence="101"
/>
<?endforeach?>
This throws the following error:
The util:XmlConfig/@Id attribute's value, 'String[VALUES]', is not a legal identifier.
Identifiers may contain ASCII characters A-Z, a-z, digits, underscores (_), or periods (.).
Every identifier must begin with either a letter or an underscore.
Is there any way I can create a variable amount of elements with the XmlFile or the XmlConfig element? Is the only solution to this problem a CustomAction?