REQUEST A DEMO

Refreshing Component Guids in your Wix XML

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);
            }
        }
    }
}

2 Comments

  • Anonymous

    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.

  • ADD COMMENT

    Your email address will not be published.