Tuesday, May 1, 2012

WiX Research - Building Installer (.msi) using WiX Sharp

This is a part of series of research which I am doing for finding out a better way to create and Installer. Just building an installer is not something I am looking into, I am looking forward to build a installer which is efficient and easy to maintain (Installer as well as source code).

Using WiXSharp build installer (.msi) with following objective fulfilled:
  • Build installer of a folder location specified.
  • Installer should able to upgrade and not allow downgrade.

Set Environment Variable
Before doing anything using WiXSharp need to set environment variables which will ack as beacon for WiX bin. Call this somewhere like while initializing the class.

public void ReBuildInstallerEnvironment()
    Environment.SetEnvironmentVariable("WIXSHARP_WIXDIR", Environment.CurrentDirectory + @"\Wix_bin\bin", EnvironmentVariableTarget.Process);
    Environment.SetEnvironmentVariable("WIXSHARP_DIR", Environment.CurrentDirectory, EnvironmentVariableTarget.Process);

There are quiet a few ways to create .msi using WiXSharp but after doing some research found that rather than directly assigning data in the WiXSharp Project it is better create WixEntity objects are pass it to the Project.

Create WixEntity[] 
To build installer using WiXSharp need to create WixEntity[] of the folder and its files within. To achieve that created following recursive code.

private WixEntity[] BuildDirInfo(string sRootDir, WixEntity[] weDir)
    DirectoryInfo RootDirInfo = new DirectoryInfo(sRootDir);
    if (RootDirInfo.Exists)
        DirectoryInfo[] DirInfo = RootDirInfo.GetDirectories();
        List<string> lMainDirs = new List<string>();
        foreach (DirectoryInfo DirInfoSub in DirInfo)
        int cnt = lMainDirs.Count;
        weDir = new WixEntity[cnt + 1];
        if (cnt == 0)
            weDir[0] = new DirFiles(RootDirInfo.FullName + @"\*.*");
            weDir[cnt] = new DirFiles(RootDirInfo.FullName + @"\*.*");
            for (int i = 0; i < cnt; i++)
                DirectoryInfo RootSubDirInfo = new DirectoryInfo(lMainDirs[i]);
                if (!RootSubDirInfo.Exists) 
                WixEntity[] weSubDir = new WixEntity[0];
                weSubDir = BuildDirInfo(RootSubDirInfo.FullName, weSubDir);
                weDir[i] = new Dir(RootSubDirInfo.Name, weSubDir);
    return weDir;

Build Installer
Now create your own function to build .msi using WiXSharp.
WiXSharp is a very easy to implement utility which has been built over WiX.

void BuildInstaller()
       WixEntity[] weDir = new WixEntity[0];
       weDir = BuildDirInfo(sRootDir, weDir);
       var project = new Project("Test Product", new Dir("TestProduct", weDir))
              GUID = Guid.NewGuid(),
              UI = WUI.WixUI_InstallDir,
              Manufacturer = "TestCompany",
              Version = new Version(12, 1, 1, 0),
              LicenceFile = Directory.GetCurrentDirectory() + @"\EULA.rtf",
              BannerImage = Directory.GetCurrentDirectory() + @"\Banner.bmp",
              BackgroundImage = Directory.GetCurrentDirectory() + @"\Background.bmp",
              UpgradeCode = guidUpgradeCode, // Forwarded if upgrading existing product
              MajorUpgradeStrategy = new MajorUpgradeStrategy
                     UpgradeVersions = VersionRange.OlderThanThis,
                     PreventDowngradingVersions = VersionRange.NewerThanThis,
                     NewerProductInstalledErrorMessage = "Newer version already installed"
       Compiler.BuildMsi(project, sInstLoc + @"\Test Product.msi");

There is nothing much into it just you need to know how to play with WixEntity[] and WixEntity class objects.

I will be working on different aspects if WiX in future...


  1. I like the style of blogger to show this blog. I liked this blog because it is shown in a good manner. and here are many informational thing which is very good to have.thanks for this nice one !!!
    Market Sample

  2. Please upload more wixsharp sample project

  3. I am having trouble compiling when I provide a path to a license file. How do I get passed the Ipsum lorem?