Authoring MSI

<Wix# Samples>\CodingStyles

Authoring MSI with Wix# consist of three distinctive steps: declaring an instance of the WixSharp.Project, defining the compilation action with WixSharp.Compiler and executing the build script.

Defining Wix# project

Instantiating the Wix# project is as simple as instantiating any C# class. And as with any trivial class declaration it can done in various ways/styles:

Traditional (plain C# routine)

var docFile = new File(@"Files\Docs\Manual.txt");
var exeFile = new File(@"Files\Bin\MyApp.exe");
var dir = new Dir(@"%ProgramFiles%\My Company\My Product");
dir.Files = new[] { docFile, exeFile };
var project = new Project();
project.Dirs = new[] { dir };
project.Name = "MyProduct";

Class initializers

var project =   
    new Project()
        Name = "MyProduct",
        GUID = new Guid("6f330b47-2577-43ad-9095-1861ba25889b"),
        Dirs = new[]
            new Dir(@"%ProgramFiles%\My Company\My Product")
                Files = new []
                    new File(@"Files\Docs\Manual.txt"),
                    new File(@"Files\Bin\MyApp.exe")

XDocument style constructors

var project =
    new Project("MyProduct",
        new Dir(@"%ProgramFiles%\My Company\My Product",
            new File(@"Files\Docs\Manual.txt"),
            new File(@"Files\Bin\MyApp.exe")));

XDocument style deserves special attention. WixSharp Project, Dir and File constructors are extremely similar to the XDocument/XElement constructors accepting an open end lists parameters of the generic base type.

System.Xml.Linq.XElement(XName name, params Object[])
WixSharp.File(string name, params WixEntity[])

This stile of the instantiation has been proven successful for the definition of the XML structure (LINQ for XML). And it has been chosen as a default instantiation style for all Wix# samples.

Usually all Wix# types have multiple overloads allowing passing some specific parameters.

XDocument style declarations represent some minor challenges when you need to access constructor parameters outside of the constructor.

project.FindFile(f => f.Name.EndsWith("MyApp.exe"))
       .Shortcuts = new[] 
                        new FileShortcut("MyApp.exe""INSTALLDIR"),
                        new FileShortcut("MyApp.exe""%Desktop%")

And of course (when it is possible) it can be done in a more conventional way:

File mainExe;
new Dir(@"%ProgramFiles%\My Company\My Product",
    mainExe = new File(@"Files\Bin\MyApp.exe")),  ...
mainExe.Shortcuts = ...


Compiling Wix# project

Building Wix# project into MSI or MSM can be accomplished by invoking one of the WixSharp.Compiler.Build* major methods:

  • Compiler.BuildMsi()
    Will build MSI setup from the project definition
  • Compiler.BuildMsm()
    Will build MSM setup package from the project definition
  • Compiler.BuildWxs()
    Will build WiX source code that can be used to build MSI/MSM setup package.
  • Compiler.BuildMsiCmd()
    Will build WiX source code and create batch file (*.cmd) that can be used to build MSI/MSM setup by invoking WiX tools directly (from batch file).

BuildMsiCmd is particularly useful for troubleshooting as it allows manual adjustments of the generated WiX source file (*.wxs) before it is passed into the WiX compiler/linker.

It can also be useful to preserve .wxs file for further inspections after the build. This can be done by setting the corresponding compiler flag:

Compiler.PreserveTempFiles = true;

Building MSI file

<Wix# Samples>\Building without Visual Studio
The Wix# Project definition and the compilation are typically placed in a single C# file (build script). Building the final MSI can be accomplished either by executing the build script with Visual Studio/MSBuild or with CS-Script script engine. All Wix# samples are distributed with a copy if the script engine (cscs.exe) and the corresponding batch file (build.cmd) for building the sample .msi.

<Wix# Samples>\Building with Visual Studio
The build script can also be executed with Visual Studio. You just need to include it as an source .cs file to the C# Console Application project and add the reference to WixSharp.dll. You may also need to adjust the working directory in the Debug tab of the project settings.

The actual building of the .msi file will be triggered by the execution (F5) of the project build output file

All this can also be accomplished in a single step by adding the WixSharp NuGet package to the C# Console Application project


NuGet package integration also includes injection of the custom target for to the project build sequence. Thus you don't have to execute the build script. It will be done automatically at the end of the project build.


Admin install

XElement installExec = document.Descendants("InstallExecuteSequence")
XElement adminAction = installExec.Elements()
                                    //.Where(e => e.HasAttribute("Action") && e.Attribute("Action").Value.EndsWith("MyAdminAction"))
                                    .Where(e => e.HasAttribute("Action"
value=>value.EndsWith("MyAdminAction")))                                     .First(); adminAction.Remove(); installExec.Parent.SelectOrCreate("AdminExecuteSequence").Add(adminAction);

Last edited Jan 28, 2015 at 2:00 AM by oleg_s, version 56