DovetailConnect Blog

Refreshing Component Guids in your Wix XML

Kevin Miller July 14, 2010

Right now I am working once again with Wix which can be quite shall we put it nicely: freaking traumatic. I promise this post will not entirely be me moaning about Windows Installer crap-titude. Rather, this post may actually help you out of a weird jam some day.

My Windows Installer (.msi based) installed application started to refuse to uninstall with a weird error.

Registry Component\<GUID>\<GUID> could not be found.

The only resulting way for me to get rid of the install was to use the Windows Install Clean Up which is pretty scary because Microsoft doesn’t provide it as a download because:

While the Windows Installer Cleanup utility resolved some installation problems, it sometimes damaged other components installed on the computer. Because of this, the tool has been removed from the Microsoft Download Center.

Yikes! Anyhow. The reason this was happening seems to be related to colliding component Guids . This was likely caused by me doing a cut and paste of existing Wix component XML and leaving the duplicate Guid laying around like a ticking time bomb. Did I mention I dislike Windows Installer?

My colleague Joey Vano ran into this problem and solved it by refreshing his entire project’s component Guids. FYI, this is only OK to do if your doing a “major” upgrade of your installer. Don’t know what that means? Then it is amazing you are this far into this post.

Indeed refreshing the Guids ended up being the fix. However, generating and replacing all the Guids by hand seemed a bad idea and ripe cause for an RSI injury to my wrists as my project had a lot of Guids. Being lazy I wrote a console app which refreshes all the Guids in the .wxs files in the current working directory. Here is the code. I hope you never need to find it useful.

using System;
using System.Linq;
using System.Xml;
using System.Xml.Linq;
using System.Xml.XPath;

namespace reguid
{
    public class WixComponentGuidRefresh
    {
        static void Main(string[] args)
        {
            var files = System.IO.Directory.EnumerateFiles(".", "*.wxs");

            var nsmgr = new XmlNamespaceManager(new NameTable());
            nsmgr.AddNamespace("w", "http://schemas.microsoft.com/wix/2006/wi");

            foreach (var file in files)
            {
                Console.WriteLine("Opening file {0}.", file);

                var document = XDocument.Load(file);

                var components = document.XPathSelectElements("//w:Component", nsmgr);

                Console.WriteLine("Found {0} components.", components.Count());

                foreach (var component in components)
                {
                    var id = component.Attribute("Id").Value;
                    var guidString = "{" + Guid.NewGuid() + "}";

                    Console.WriteLine("Setting guid for component {0} to {1}.", id, guidString);
                    
                    component.Attribute("Guid").SetValue(guidString);
                }

                document.Save(file);
            }
        }
    }
}
share

Tags:

Comments

Re: Refreshing Component Guids in your Wix XML

omg yet another DEV that has no idea about deployment. windows installer crap-titude as you put it is actually your complete lack of understanding of a very clever technology. what you have done here is absolutely stupid and clearly shows you have no idea about deployment. if you actually bothered to work out what your cause is in the first place you would realise this functionity known as component reference counting was put in place to fix something created by the silly devs that need deployment in the first place. learn your tech before you bag out completely excellent technologies such as WiX and Windows installer.

omg yet another DEV that has

Thank you for your calm and considerate comment Anonymous. :) I understand Windows Installer very well. Please see my series of Wix posts. The reason behind what I did was perfectly OK as I am taking about Major upgrade scenarios and a situation where I don't really care to share installed components across install boundaries. I apologize if my post did not make that clear.

Post new comment

The content of this field is kept private and will not be shown publicly.
CAPTCHA
This question is for testing whether you are a human visitor and to prevent automated spam submissions.