Thursday, May 3, 2012

WiX Research - Building Installer using WiX Sharp partially


Looking beyond WiX Sharp…

Here is another implementation of WiX as a part of on-going research. In the following implementation I have used few features of WiX Sharp and predominantly WiX to build an installer (.msi). This is unlike the previous implementation where I have user WiX Sharp only.

What is the requirement of further refining the implementation? 
And what is the requirement of moving away from WiX Sharp?

I see there are few shortcomings using WiX Sharp:
  • There is a dependency on third party tool (WiX Sharp) which may go against proprietary norms of the company.
  • There are many features implemented or can be tweaked in WiX as per user requirement; which may not possible if we are heavily dependent in WiX Sharp.
  • Having your own middle tier will give more control over your implementation.


Note :- I am really a fan of WiX Sharp and see value it has but on the other hand when thought of it rationally compelled me to look beyond WiX Sharp.

Salient features of the implementation:
  • Building .wxs file using WiX Sharp.
  • Integrating custom installation path using System.XML.LINQ.
  • Executing Candle.exe and Light.exe using System.Diagnostics.Process to build the installer.


Feedback are appreciated to improve implementation and if I am missing out anything.

ExeEXE – Standard function to call System.Diagnostics.Process to execute EXE and get the return value.

public bool ExeEXE(string sApplication, string sAppArgs)
{
    System.Diagnostics.Process AppProcess = new System.Diagnostics.Process();
    AppProcess.StartInfo.FileName = sApplication;
    AppProcess.StartInfo.Arguments = sAppArgs;
    AppProcess.StartInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
    AppProcess.Start();
    AppProcess.WaitForExit();
    if (AppProcess.ExitCode > 0)
        Errorobj = "Error excounter while executing " + sApplication + " in " + this.ToString();
    else
        Errorobj = null;
    return (AppProcess.ExitCode == 0) ? true : false;
}

InsertCustomPath – This function insert Custom action in .wxs file for assigning custom path

private void InsertCustomPath()
{
    XDocument Doc = XDocument.Load(Environment.CurrentDirectory + @"\Test Product.wxs");
    if (Doc.Root != null)
    {
        XNamespace xNS = Doc.Root.GetDefaultNamespace();
        XElement xCustAct = new XElement(xNS + "CustomAction",
                                         new XAttribute("Id", "CustActSetINSTALLDIR"),
                                         new XAttribute("Return", "check"),
                                         new XAttribute("Execute", "firstSequence"),
                                         new XAttribute("Property", "TARGETDIR"),
                                         new XAttribute("Value", sInstDir));
        XElement xUI = new XElement(xNS + "UI",
                                    new XElement(xNS + "InstallUISequence",
                                                 new XElement(xNS + "Custom",
                                                              new XAttribute("Action", "CustActSetINSTALLDIR"),
                                                              new XAttribute("After", "ValidateProductID"), "TARGETDIR=\"\"")));
        XElement xExeSeq = new XElement(xNS + "InstallExecuteSequence",
                                        new XElement(xNS + "Custom",
                                                     new XAttribute("Action", "CustActSetINSTALLDIR"),
                                                     new XAttribute("After", "ValidateProductID"), "TARGETDIR=\"\""));
        XNode Node = Doc.Root.FirstNode;
        while (Node != null)
        {
            if (((XElement)Node).Name.LocalName == "Product")
            {
                XNode ChildNode = ((XElement)Node).FirstNode;
                while (ChildNode != null)
                {
                    if (((XElement)ChildNode).Name.LocalName == "Directory")
                    {
                        ChildNode.AddAfterSelf(xCustAct);
                    }
                    else if (((XElement)ChildNode).Name.LocalName == "Upgrade")
                    {
                        ChildNode.AddAfterSelf(xExeSeq);
                        ChildNode.AddAfterSelf(xUI);
                    }
                    ChildNode = ChildNode.NextNode;
                }
            }
            Node = Node.NextNode;
        }
    }
    Doc.Save(Environment.CurrentDirectory + @"\Test Product.wxs");
}

BuildInstaller – Main function to build .wxs and then execute Candle.exe and Light.exe.

public object BuildInstaller()
{
    try
    {
        WixEntity[] weDir1 = new WixEntity[0];
        weDir1 = BuildDirInfo(sRootDir, weDir1); // Implementation already been described in previous post
        var project = new Project("Test Product", new Dir("Test Product", weDir1))
        {
            GUID = Guid.NewGuid(),
            UI = WUI.WixUI_InstallDir,
            Manufacturer = "Test Company",
            Version = new Version(1, 1, 1, 0),
            LicenceFile = Directory.GetCurrentDirectory() + @"\EULA.rtf",
            BannerImage = Directory.GetCurrentDirectory() + @"\Banner.bmp",
            BackgroundImage = Directory.GetCurrentDirectory() + @"\Background.bmp",
            UpgradeCode = guidUpgradeCode,
            MajorUpgradeStrategy = new MajorUpgradeStrategy
            {
                UpgradeVersions = VersionRange.OlderThanThis,
                PreventDowngradingVersions = VersionRange.NewerThanThis,
                NewerProductInstalledErrorMessage = "Newer version already installed"
            }
        };
        
        // Building .wxs file using WixSharp.dll
        Compiler.BuildWxs(project, Environment.CurrentDirectory + @"\Test Product.wxs");
        
        InsertCustomPath();// Inserting Custom action for setting custom installation path
        
        //Executing Candle.exe and Light.exe using System.Diagnostics.Process
        string sCommandLine = "\"" + Environment.CurrentDirectory + "\\Test Product.wxs\" -out \"" + Environment.CurrentDirectory + "\\Test Product.wixobj\"";
        if (ExeEXE(Environment.CurrentDirectory + @"\wixbin\bin\Candle.exe", sCommandLine))
        {
            System.IO.File.Delete(Environment.CurrentDirectory + "\\Test Product.wxs");
            sCommandLine = "\"" + Environment.CurrentDirectory + "\\Test Product.wixobj\" -ext WixUIExtension -out \"" + sInstLoc + "\\Test Product.msi\"";
            if (!ExeEXE(Environment.CurrentDirectory + @"\wixbin\bin\Light.exe", sCommandLine))
            {
                obRtn = "ERROR: " + (string)Errorobj;
                return obRtn;
            }
            System.IO.File.Delete(Environment.CurrentDirectory + "\\Test Product.wixobj");
            System.IO.File.Delete(sInstLoc + "\\Test Product.wixpdb");
        }
        else
        {
            obRtn = "ERROR: " + (string)Errorobj;
            return obRtn;
        }
        return obRtn;
    }
    catch (Exception w)
    {
        MessageBox.Show(w.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
    }
    return null;
}

2 comments:

  1. Great Article. Thank you for sharing! Really an awesome post for every one.

    IEEE Final Year projects Project Centers in Chennai are consistently sought after. Final Year Students Projects take a shot at them to improve their aptitudes, while specialists like the enjoyment in interfering with innovation. For experts, it's an alternate ball game through and through. Smaller than expected IEEE Final Year project centers ground for all fragments of CSE & IT engineers hoping to assemble. Final Year Project Domains for IT It gives you tips and rules that is progressively critical to consider while choosing any final year project point.

    JavaScript Training in Chennai

    JavaScript Training in Chennai

    ReplyDelete



  2. Our client can choose any of them as per their convenient. We are also open to send our angels any other place of your choice. Russian Escorts in Vasant Kunj are waiting eagerly to meet you. You need to decide whether you want to meet them at home or at any hotel. If you are facing any challenges in arranging any place, let me inform you that we have tie-ups with 3 start hotels as well as 5 start hotels. Check our other services...
    Russian Escorts in Vasant Kunj
    Russian Escorts in Vasant Kunj
    Russian Escorts in Vasant Vihar
    Russian Escorts in Vasant Vihar
    Russian Escorts in Vasant Vihar
    Russian Escorts in Vasant Vihar

    ReplyDelete