Using Wix to modify an XML file

by Nigel Wilks on February 8, 2010 · 2 comments

in Guides

Wix or Windows Installer XML is an Open Source toolset used to create Windows Installer (or MSI) packages, including many of the current Windows Home Server Add-Ins. I’m going to be sharing some of my experiences with Wix and the relevant code snippets to try and make it easier for any of you budding developers. I’m by no means an expert in Wix, having only started using it for WHS Add-Ins as access to commercial products like Wise are not generally affordable for home so I’m learning to do some of the things that are easy in Wise along the way.

Using Wix can feel fairly laborious at times; it often seems to need some heavy duty work to do something relatively simple. However, once you’ve grasped the basics it really does shape up to be quite a powerful toolset!

One of the things that have troubled me recently whilst working on an impending WHS Health Add-In release was updating the Websites.xml file. Wix has an element you can use for this so I thought I’d post the code snippet I used, and explain how it works. It’s a useful feature to do for a WHS Add-In that uses Web Pages, so hopefully it’s some use to someone later.

<WebSites>
<WebSite name="WHS Health" uri="javascript:window.location('http://'+location.hostname+'/health')" imageUrl="/health/images/WHSHealth_Logo.png" absolute="true" />
</WebSites>

If you look at the websites.xml file above, you can see the layout used. The first thing we need to do is add the “Element” called Website. The VerifyPath value is telling the Installer to check the path exists before trying to create it (we don’t want two entries the same!). If it’s there already it will skip it and won’t error. The other major thing here to notice is the Sequence you set, really it’s logical. You need to create the element first, and then create the values. You can see I have assigned that as 1001 and each step after increments by 1 to ensure it does it in the order I want it to. Starting at 1001 means I can go backwards if I really need to at a later date without worrying about renaming each of the current sequences. I’m also specifying that Wix needs to use the UtilExtension with the “xmlns” tag as XmlConfig isn’t part of the standard instruction set, think of it as a plug-in.

<util:XmlConfig On="install" Action="create" Id="CreateRemoteElement" Node="element" File="c:\inetpub\remote\WebSites.xml" ElementPath="/WebSites" Sequence="1001" xmlns:util="http://schemas.microsoft.com/wix/UtilExtension" Name="WebSite" VerifyPath="/WebSites/WebSite[\[]@name='WHS Health'[\]]" />

Next we create the “Name”, cunningly called “name” in this file with a “Value” of “WHS Health” and reference the Element ID above by using “ElementPath”. Notice it matches the Id above. As we reference that “Id”, we don’t need to tell the installer we want to do this action on “install” as we are implying that its part of that element so that action is inherited.

<util:XmlConfig Id="CreateRemoteName" File="c:\inetpub\remote\WebSites.xml" ElementPath="CreateRemoteElement" Sequence="1002" xmlns:util="http://schemas.microsoft.com/wix/UtilExtension" Value="WHS Health" Name="name" />

And now we just repeat the above, changing the Sequence, Value and Name for each of our remaing values.

<util:XmlConfig Id="CreateRemoteUri" File="c:\inetpub\remote\WebSites.xml" ElementPath="CreateRemoteElement" Sequence="1003" xmlns:util="http://schemas.microsoft.com/wix/UtilExtension" Value="javascript:window.location('https://'+location.hostname+'/health')" Name="uri" />

<util:XmlConfig Id="CreateRemoteImageUrl" File="c:\inetpub\remote\WebSites.xml" ElementPath="CreateRemoteElement" Sequence="1004" xmlns:util="http://schemas.microsoft.com/wix/UtilExtension" Value="/health/images/WHSHealth_Logo.png" Name="imageurl" />

<util:XmlConfig Id="CreateRemoteAbsolute" File="c:\inetpub\remote\WebSites.xml" ElementPath="CreateRemoteElement" Sequence="1005" xmlns:util="http://schemas.microsoft.com/wix/UtilExtension" Value="True" Name="absolute" />

Now we create this on install, it’s only polite to make sure we cleanup after ourselves when the Add-In is removed. Removing an XML Element is pretty straightforward, and using the entry for WHS Health we created above, we just need to point to the Element and it will remove the whole entry for us.

<util:XmlConfig On="uninstall" Action="delete" Id="RemoveRemoteElement" Node="element" File="c:\inetpub\remote\WebSites.xml" VerifyPath="/WebSites/WebSite[\[]@name='WHS Health'[\]]" ElementPath="/WebSites" Sequence="2001" xmlns:util="http://schemas.microsoft.com/wix/UtilExtension" />

All that’s left to do is to just duplicate the above code for c:\inetpub\remote\WebSites.xml.


Article by

I'm a Technical Architect based in the UK predominantly working on Windows Server and Active Directory based solutions. I'm also a Microsoft Windows Home Server MVP and moderator/author at http://www.mediasmartserver.net. I've released the FirePlay for Windows Home Server, WHS PHP Installer, MySql Installer for WHS and Wordpress Installer for WHS Add-Ins as well as co-author of the SanEncore and WHS Health Add-Ins with Alex Kuretz.


{ 2 comments }

Sam Wood December 10, 2010 at 10:46 pm

Hey Nigel, great work! This just saved me a ton of time.

Nigel December 11, 2010 at 2:42 am

Thanks Sam. Glad you found it useful, It’s your fault I started on Wix :-)

Comments are closed, visit the forums to continue the discussion.

Previous post:

Next post: