Click here to Skip to main content
Click here to Skip to main content
Articles » Languages » C# » General » Downloads
 
Add your own
alternative version

A WIX web setup

, 9 May 2007
Create WIX web setup using VS2005 and Wix 3.0
componentwriter.zip
ComponentWriter
bin
Debug
Djans.ComponentWriter.exe
Djans.ComponentWriter.pdb
Release
Djans.ComponentWriter.exe
Djans.ComponentWriter.suo
obj
Debug
Djans.ComponentWriter.exe
Djans.ComponentWriter.pdb
TempPE
Release
Djans.ComponentWriter.exe
LogicaCMG.ComponentWriter.exe
Refactor
TempPE
Properties
app.manifest
wixwebsetup.zip
WixWebSetup
SolutionItems
Djans.ComponentWriter.exe
Djans.CustomInstaller.dll
WebApplication1.csproj_deploy
Debug
Release
bin
Djans.CustomInstaller.dll
WebApplication1.dll
Properties
WebApplication1.csproj_deploy.wdproj
WebApplication1
bin
WebApplication1.dll
WebApplication1.pdb
obj
Debug
TempPE
WebApplication1.dll
WebApplication1.pdb
Release
TempPE
WebApplication1.dll
WebApplication1.pdb
Properties
WebApplication1.csproj.user
WixSetup
Actions.wxs
bin
Debug
Release
WixSetup.msi
Binary
DefBannerBitmap.ibd
InstallUtil.ibd
InstallUtilLib.dll
MSVBDPCADLL.ibd
NewFldrBtn.ibd
UpFldrBtn.ibd
VSDNETCFG.ibd
Components.wxs
obj
Release
Actions.wixobj
Components.wixobj
Properties.wixobj
UserInterface.wixobj
WixSetup.wixobj
Properties.wxs
UserInterface.wxs
WixSetup.wixproj
WixSetup.wxs
WixWebSetup.suo
#region Using sourceDirrectives
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Xml;
using System.Reflection;
using System.Diagnostics;
using System.Configuration;
using System.Net;
using System.Security.AccessControl;
using System.Security.Principal;

#endregion

namespace Djans.ComponentWriter
{
    /// <summary>
    /// This class has the functionality to do the actual job of writing wix component file.
    /// </summary>
    class ComponentWriter
    {
        #region Private members
        static string sourceDirectory = string.Empty;
        static string componentFile = string.Empty;
        static string upgradeFile = string.Empty;
        static StringBuilder structure = new StringBuilder(string.Empty);
        static StringBuilder feature = new StringBuilder(string.Empty);
        #endregion

        /// <summary>
        /// Writes the wix files
        /// </summary>
        /// <param name="Config">Input values</param>
        /// <returns>Success or Failure</returns>
        public bool Write(ComponentWriterConfig Config)
        {
            // Set values
            sourceDirectory = Config.SourceDirectory;
            componentFile = Config.OutputFile;
            upgradeFile = Config.UgradeFile;

            // Start Writing: 
            // (i) Component.wxs 
            WriteComponents();

            // (ii) Update version number 
            if (!upgradeFile.Equals("-skip"))
                UpdateUpgradation();

            // Clear static variables
            ClearStaticVariables();

            return true;
        }

        #region Helper Functions

        /// <summary>
        /// Clears static variables after the writing is finished.        /// 
        /// </summary>
        private void ClearStaticVariables()
        {
            sourceDirectory = string.Empty;
            componentFile = string.Empty;
            upgradeFile = string.Empty;

            structure = new StringBuilder();
            feature = new StringBuilder();
        }

        /// <summary>
        /// Upgrades the version
        /// Updates only first 3 parts. The 4th part is always 0.
        /// </summary>
        /// <param name="version">Version number</param>
        private static void ChangeVersion(ref string version)
        {
            if (!String.IsNullOrEmpty(version))
            {
                string[] max = new string[4];
                max = version.Split('.');
                max[1] = ((Convert.ToInt32(max[1]) == 9) ? ("0") : (Convert.ToString(Convert.ToInt32(max[1]) + 1)));
                max[0] = ((Convert.ToInt32(max[1]) == 0) ? (Convert.ToString(Convert.ToInt32(max[0]) + 1)) : (max[0]));
                version = max[0] + "." + max[1] + "." + max[2] + ((max.Length > 3) ? ("." + max[3]) : (""));
            }
        }


        /// <summary>
        /// Provide New GUID
        /// </summary>
        /// <returns remarks="string">GUID</returns>
        private static string GetNewGUID()
        {
            return Guid.NewGuid().ToString().ToUpper();
        }
        #endregion

        #region WXS Generation

        /// <summary>
        /// Write component file
        /// </summary>
        private static void WriteComponents()
        {
            DirectoryInfo sourceDir = new DirectoryInfo(sourceDirectory);
            FileInfo[] sourceFiles = sourceDir.GetFiles("*.*");

            FileInfo componentFileInfo = new FileInfo(componentFile);
            if (componentFileInfo.Exists)
            {
                componentFileInfo.IsReadOnly = false;
            }

            StreamWriter w = new StreamWriter(componentFile, false);
            w.WriteLine(string.Format("<?xml version='1.0' encoding='utf-8'?>").Replace('\'', '"'));
            w.WriteLine(string.Format("<Wix xmlns='http://schemas.microsoft.com/wix/2006/wi'>{0}<Fragment Id='ComponentFragment'>", Environment.NewLine).Replace('\'', '"'));
            w.WriteLine(string.Format("<Directory Id='TARGETDIR' Name='SourceDir'>").Replace('\'', '"'));
            w.WriteLine(string.Format("<Component Id='C__{0}' Guid='{1}' >", sourceDir.Name, Guid.NewGuid().ToString().ToUpper()).Replace('\'', '"'));

            feature.AppendLine(string.Format("<Feature Id='DefaultFeature' ConfigurableDirectory='TARGETDIR' Level='1'>").Replace('\'', '"'));
            feature.AppendLine(string.Format("<ComponentRef Id='C__{0}' />", sourceDir.Name).Replace('\'', '"'));

            foreach (FileInfo file in sourceFiles)
            {
                w.WriteLine(string.Format("<File Id='" + file.Name
                                          + "' Name='" + file.Name
                                          + "' Vital='yes' DiskId='1' Source='"
                                          + file.FullName
                                          + "' />").Replace('\'', '"'));
            }

            w.WriteLine("</Component>");
            GetDirectoryStructure(sourceDir);
            w.WriteLine(structure.ToString().Trim());
            w.WriteLine("</Directory>");

            // Add Feature            
            feature.AppendLine("</Feature>");
            w.WriteLine(feature.ToString().Trim());
            w.WriteLine("</Fragment></Wix>");

            // Close Writer
            w.Close();
        }

        /// <summary>
        /// Creates the directory structure based on the Source directory
        /// </summary>
        /// <param name="sourceDirectory">Source Directory</param>
        private static void GetDirectoryStructure(DirectoryInfo sourceDirectory)
        {
            StringBuilder subDirectoryStructure;
            DirectoryInfo[] subDirectories = sourceDirectory.GetDirectories("*", SearchOption.TopDirectoryOnly);
            foreach (DirectoryInfo subDir in subDirectories)
            {
                string id = string.Empty;
                if (structure.ToString().Contains(subDir.Name))
                    id = subDir.Parent.Name + "_" + subDir.Name;
                else
                    id = subDir.Name;

                subDirectoryStructure = new StringBuilder(string.Empty);
                subDirectoryStructure.AppendLine(string.Format("<Directory Id='DIR__{0}' Name='{1}'>", id, subDir.Name).Replace('\'', '"'));
                structure.Append(subDirectoryStructure.ToString());

                StringBuilder wixFileList;
                GetWixFormattedFilesList(subDir.GetFiles("*.*"), subDir, out wixFileList);
                if (wixFileList.Length > 0)
                    structure.Append(wixFileList.ToString().Trim());

                if (subDir.GetDirectories().Length > 0)
                {
                    GetDirectoryStructure(subDir);
                    structure.Append("</Directory>");
                }
                else
                {
                    structure.Append("</Directory>");
                }
            }
        }

        /// <summary>
        /// Lists the files in Wix Format
        /// </summary>
        /// <param name="files"></param>
        /// <param name="sourceDirectoryInfo"></param>
        /// <param name="wixFileList"></param>
        private static void GetWixFormattedFilesList(FileInfo[] files, DirectoryInfo sourceDirectoryInfo, out StringBuilder wixFileList)
        {
            wixFileList = new StringBuilder(string.Empty);
            StringBuilder wixCustomFile = new StringBuilder(string.Empty);
            if (files.Length > 0)
            {
                string id = string.Empty;
                string fileId = string.Empty;
                if (structure.ToString().Contains(sourceDirectoryInfo.Name))
                    id = sourceDirectoryInfo.Parent.Name + "_" + sourceDirectoryInfo.Name.Replace('-', '_');
                else
                    id = sourceDirectoryInfo.Name.Replace('-', '_');

                wixFileList.AppendLine(string.Format("<Component Id='C__{0}' Guid='{1}' >", id, Guid.NewGuid().ToString().ToUpper()).Replace('\'', '"'));
                feature.AppendLine(string.Format("<ComponentRef Id='C__{0}' />", id).Replace('\'', '"'));

                foreach (FileInfo file in files)
                {
                    if (structure.ToString().Contains(file.Name))
                        fileId = file.Directory.Name + "_" + file.Name.Replace('-', '_').Replace('.', '_');
                    else
                        fileId = file.Name.Replace('-', '_').Replace('.', '_');

                    //if (sourceDirr.Name == "bin")
                    if ((file.Name.Contains("Installer") || file.Name.Contains("Config_")) && (sourceDirectoryInfo.Name == "bin"))
                    {
                        feature.AppendLine(string.Format("<ComponentRef Id='C__{0}' />", file.Name.Replace('-', '_').Replace('.', '_')));
                        wixCustomFile.AppendLine(string.Format("<Component Id='C__{0}' Guid='{1}' >", file.Name.Replace('-', '_').Replace('.', '_').Replace('\'', '"'), Guid.NewGuid().ToString().ToUpper()).Replace('\'', '"'));
                        wixCustomFile.AppendLine(string.Format("<File Id='" + file.Name.Replace('-', '_').Replace('.', '_')
                                                  + "' Name='" + file.Name
                                                  + "' Vital='yes' DiskId='1"
                                                  + "' Source='" + file.FullName
                                                  + "' />").Replace('\'', '"'));
                        wixCustomFile.AppendLine("</Component>");                        
                    }
                    else
                    {
                        wixFileList.AppendLine(string.Format("<File Id='" + fileId.Replace('-', '_').Replace('#', '_').Replace('~', '_')
                                                  + "' Name='" + file.Name.Replace('-', '_').Replace('#', '_').Replace('~', '_')
                                                  + "' Vital='yes' DiskId='1"
                                                  + "' Source='" + file.FullName
                                                  + "' />").Replace('\'', '"'));
                    }

                }
                wixFileList.AppendLine("</Component>");
            }
            wixFileList.AppendLine(wixCustomFile.ToString());
        }

        /// <summary>
        /// Updates Version number in Upgrade code
        /// </summary>
        private static void UpdateUpgradation()
        {
            string newGuid = GetNewGUID();
            if (!String.IsNullOrEmpty(upgradeFile))
            {
                XmlDocument upgradeDoc = new XmlDocument();
                upgradeDoc.Load(upgradeFile);

                FileInfo file = new FileInfo(upgradeFile);
                if (file.Exists)
                    file.IsReadOnly = false;

                XmlNode node = upgradeDoc.SelectSingleNode("/*[local-name()='Wix' and namespace-uri()='http://schemas.microsoft.com/wix/2006/wi']/*[local-name()='Product' and namespace-uri()='http://schemas.microsoft.com/wix/2006/wi'][1]");
                node.Attributes["UpgradeCode"].Value = newGuid;
                node.Attributes["Id"].Value = GetNewGUID();
                string version = node.Attributes["Version"].Value;
                ChangeVersion(ref version);
                node.Attributes["Version"].Value = version;

                XmlNode upgradeChild = upgradeDoc.SelectSingleNode("/*[local-name()='Wix' and namespace-uri()='http://schemas.microsoft.com/wix/2006/wi']/*[local-name()='Product' and namespace-uri()='http://schemas.microsoft.com/wix/2006/wi'][1]/*[local-name()='Upgrade' and namespace-uri()='http://schemas.microsoft.com/wix/2006/wi'][1]");
                upgradeChild.Attributes["Id"].Value = newGuid;

                foreach (XmlNode child in upgradeChild.ChildNodes)
                {
                    if (child.LocalName.Equals("UpgradeVersion"))
                    {
                        string minVersion = string.Empty;
                        string maxVersion = string.Empty;
                        minVersion = child.Attributes["Minimum"].Value;
                        maxVersion = ((child.Attributes["Maximum"] == null) ? (string.Empty) : (child.Attributes["Maximum"].Value));
                        ChangeVersion(ref minVersion);
                        ChangeVersion(ref maxVersion);
                        child.Attributes["Minimum"].Value = minVersion;
                        if (child.Attributes["Maximum"] != null)
                            child.Attributes["Maximum"].Value = maxVersion;
                    }
                }

                upgradeDoc.SelectSingleNode("/*[local-name()='Wix' and namespace-uri()='http://schemas.microsoft.com/wix/2006/wi']/*[local-name()='Product' and namespace-uri()='http://schemas.microsoft.com/wix/2006/wi'][1]/*[local-name()='Upgrade' and namespace-uri()='http://schemas.microsoft.com/wix/2006/wi'][1]").InnerXml = upgradeChild.InnerXml;
                upgradeDoc.Save(upgradeFile);
            }
        }

        #endregion

    }
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

Share

About the Author

JannuD
Architect
India India
No Biography provided

| Advertise | Privacy | Terms of Use | Mobile
Web02 | 2.8.150331.1 | Last Updated 10 May 2007
Article Copyright 2007 by JannuD
Everything else Copyright © CodeProject, 1999-2015
Layout: fixed | fluid