Summary
This article describes Wix# (WixSharp), a managed interface to WiX (Windows Installer XML toolset for building Windows installation packages from the XML source code). Wix# allows building a complete MSI or WiX source code by using script files written with the C# syntax. It uses a C# class structure to mimic WiX entities and their relationships in order to produce a valid deployment model.
Latest Updates
The Wix# functionality described in the article may have slight vary compared to the latest available Wix# version. Though link to downloadables at the start of the article is always "current".
In July 2014 Wix# was rereleased under more liberal MIT licance and it is now hosted on CodePlex.
In August 2014 UI Extensions to Wix# were released and described in this CodeProject article: "Wix# (WixSharp) UI Extensions".
Since the initial release of Wix# the following new functionality/changes has been added:
- Localization
- Configurable directory for Features
- Possibility to specify WiX element ID explicitly
- Simplified bootstrapper for UI deployment scenarios (how to deploy prerequisite with your product)
- Significant improvements in generated WiX file formating
- Support for setup MainIcon in AddRemovePrograms
- Support for conditional installation
- LaunchConditions
- RegistrySearch
- Custom Banner images
- Support for Major Upgrade deployment scenarios
- Adding files by specifying wildcards (e.g. *.dll)
- Naming convention is changed to not to use prefix 'W' for type names (
File
instead of WFile
)
Background
Implementing deployment solutions is a very specific type of software development. It has distinctive nature and usually exhibits little dependency (if any) of the application business logic.
Reasons behind MSI
Deployment approaches are numerous:
- xcopy
- batch file
- self-extracting archive
- binary application
- script
- ....
Sometimes a simple file copying can be an adequate deployment solution. However when the application consists of multiple files or the file set depends on the target system business role or the application needs to support complicated upgrade scenarios, the simple file copying does not work very well. If there is a need for a comprehensive deployment solution it can be achieved effectively by using specialized deployment frameworks.
The script based frameworks have been available for a while (e.g. InstallShield, Wise, Inno, NSIS). They work reasonably well in the majority of development scenarios. However, they all possess same limitations: script based setups are not truly transactional and they are based on the formats, which may be difficult to use for expressing the relationship between setup components.
In order to overcome these (and some other) problems Microsoft has developed an alternative technology, Windows Installer (often referred as MSI). The major difference compared to the script based installations is that the MSI installation engine is a relational database engine. All the information about every single aspect of the installation (installation steps, setup GUI layout etc.) is stored as a table data in the OLE Storage based database file (*.msi). During the setup this file is processed by the installation engine, which generates the installation sequence and then performs the sequence steps.
The change to the underlaying data format opens attractive opportunities for solving some of the fundamental deployment problems. For example, because the installation engine is a database engine, the relationship between components to be installed and setup transactions can be implemented with the minimal effort.
Reasons behind WiX
MSI is a significant improvement comparing to the script based deployment frameworks. However it is far from being perfect. To date Microsoft has not released any proper tool for authoring MSI setups. Instead, they included in SDK multiple utilities for assisting with the individual authoring steps. The utilities were not overly convenient to use, which made the authoring of even a simple setup painful experience.
Things got better when some non-Microsoft alternatives became available. A few vendors (InstallShield, Wise) have released IDE for MSI based setups. These products allowed to build, test and maintain setups within a single development environment. Vast majority of such IDEs were very expensive and had some usability flaws. However, the major drawback was that all these products used a binary format for source files. This made almost impossible to source control such files and the whole maintenance process became a challenging task.
A serious attempt to address these issues has been made by Microsoft when they added support for deployment projects to the .NET family of Visual Studio IDEs. The Visual Studio deployment project is a XML file, which can be easily source controlled and edited by either Visual Studio or any other editor capable of handling the XML format.
Thus, the "source control" issue has been resolved. However, neither project file format nor Visual Studio MSI compiler have been disclosed by Microsoft. This resulted in a quite limited Visual Studio deployment project functionality. Furthermore, deployment projects are not supported by some Visual Studio editions. But, nevertheless, Visual Studio was one of the first maintainable concepts for setup development.
The real breakthrough has come when WiX appeared on the scene. WiX is an Open Source product for MSI setup authoring. It makes possible to compile XML based source files into the MSI setup. In a way, it is a logical equivalent of Visual Studio deployment project but with significant differences: WiX is based on the Open Source protocol and it is not "melted" with any development environment (like Visual Studio IDE).
The WiX team has made a very wise decision to separate the source file protocol from the development environment, which created certain opportunities for development of the third party tools/editors for WiX files (*.wxs).
Of course you can always edit the WiX file with any text editor (after all it is just a text file), but there are some WiX specialized editors already available (e.g WixEdit, WixAware). One of these WiX interfacing tools deserves special mentioning. WixAware is a commercial product which delivers features similar to Wise and InstallShield but it is entirely based on WiX architecture.
Building MSI with Visual Studio.
Building MSI with Wise (WfWI).
Building MSI with WiX.
WiX is definitelly here to stay and it is getting wider acceptance. Even Microsoft has officially recognized WiX as a mature technology and decided to include support for WiX based deployment projects into the next version of Visual Studio.
Reasons behind Wix#
Thus, WiX has everything for creating MSI setups but what are the practical aspects of working with WiX? As I mentioned earlier you have a choice of using third-party specialized editors for WiX source files (*.wxs) or editing wxs files directly. The reality is that Open Source editors usually are not matured enough and commercial ones are not cheap and reliable enough. Things are changing and quite possible the quality and value of the WiX tools will improve in the near future. But nevertheless many developers would prefer to deal with setup source files directly (without any GUI based development environment).
However, working with WiX files directly is not always simple or convenient. Even using XML assisting tools like Votive (WiX add-in for Visual Studio) does not make the editing as simple as many of us would like it to be.
Let's compare fragments of the typical WiX and Inno source files. Why Inno? Inno is a popular script based deployment framework, commonly regarded as one of the simplest and most intuitive setup frameworks. It well deserved its reputation for its clear, readable syntax and overall stability.
Installation of MyApp.exe into "Program Files" directory defined in Inno:
[Setup]
AppName=MyApp
AppVerName=1.0.0
AppPublisher=DreamSoftware
DefaultDirName=C:\program Files\
OutputBaseFilename=MyAppSetup
Compression=zip
SolidCompression=true
...
[Types]
Name: Full; Description: Full installation; MinVersion: 0,5.01.2600sp2
[Components]
Name: MyAppBinariesyield
[Languages]
Name: english; MessagesFile: compiler:Default.isl
[Dirs]
Name: {app}\MyApp\Bin
[Files]
Source: ..\MyApp.exe; DestDir:
{app}\MyApp\Bin; Flags: ignoreversion; Components: MyAppBinaries
...
And the equivalent in WiX:
="1.0"="Windows-1252"
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Product Id="6fe30b47-2577-43ad-9095-1861ba25889b"
Name="MyApp" Language="9" Version="1.0.0.0"
Manufacturer="DreamSoftware" UpgradeCode="e71719d1-a535-40a7-a7a5-da26aa60a216">
<Package InstallerVersion="200" Compressed="yes" />
<Media Id="1" Cabinet="My_Product.cab" EmbedCab="yes" />
<Directory Id="TARGETDIR" Name="SourceDir" >
<Directory Id="ProgramFilesFolder" Name="ProgramFilesFolder">
<Directory Id="ProgramFilesFolder.MyApp" Name="MyAapp">
<Component Id="RemoveMyAppDir"
Guid="f7d84551-ce7d-45c8-9f14-56a08255a60d">
<RemoveFolder Id="ProgramFilesFolder" On="uninstall" />
</Component>
<Directory Id="ProgramFilesFolder.MyApp.Bin" Name="Bin">
<Component Id="MyApp_Bin" Guid="c3e7b727-d512-44f0-abab-ba29c2061224">
<RemoveFolder Id="ProgramFilesFolder.Bin" On="uninstall" />
</Component>
<Component Id="MyApp.exe" Guid="65ae4c58-2387-476d-a81f-59f569b3187c">
<File Id="MyApp.exe" Source="..\MyApp.exe"/>
</Component>
</Directory>
</Directory>
</Directory>
</Directory>
...
</Product>
</Wix>
Despite the code fragments above being simplified beyond any possibility of compilation it is clear that WiX syntax is more verbose and not as expressive as its Inno counterpart.
First of all, WiX source code contains too many details, which are irrelevant to the actual deployment logic (e.g. XML start and end tags). WiX code also contains details (e.g. GUIDs), which are reused throughout the source code. All these details (metadata) are included into WiX code with only one purpose to assist the WiX compiler with parsing the code.
The Wix# concept is quite simple. Wix# source file is an ordinary C# file containing code defining relationships between instances of Wix# classes. Wix# classes represent deployment entities: files, shortcuts, registry values etc. The Wix# source file can be translated by the Wix# engine into the WiX source file, which then (optionally) can be automatically compiled into the MSI file.
Inno code practically does not contain any metadata. It is almost pure expression of deployment logic and as such it is much easier to read and maintain. Thus, WiX files are "sprinkled" with metadata and if you try to implement a more complicated scenario (e.g. features or custom actions), the amount of metadata will only increase.
Metadata decreases clarity of the code, however at the same time it removes any ambiguity and minimizes possibility of missimplementation.
Thus, it would be really convenient to express deployment logic in a simple Inno-like manner, while metadata can be inserted automatically. And this is exactly what Wix# does.
Wix# is a light-weight C# based framework, which allows defining deployment actions and components with C# syntax for later translation into a native WiX source code.
In addition to better readability, the Wix# source code has another advantage. It can be edited with Visual Studio. This means that the developers can take advantage of IntelliSense, code auto-completion, code navigation and code XML documentation. In addition to this any Wix# file can be a part of the Visual Studio project, which would result in the MSI setup file when compiled.
Let's recapture the WiX syntax limitations, which can be addressed with Wix#:
- Absence of IntelliSense (VS WiX add-in has IntelliSense support but it is not complete and is not compatible with some VS editions)
- Not self-documented as the programming languages are (there is nothing like VS "Go to definition")
- Verbose (XML tags)
- Duplicated cross-references (features+components)?
- Presence of default information (GUIDs)
- Duplications (file ID and file source name)
Wix# Overview
The Wix# concept is quite simple. The Wix# source file is an ordinary C# file containing code defining relationships between instances of Wix# classes. Wix# classes represent deployment entities: files, shortcuts, registry values etc. The Wix# source file can be translated by the Wix# engine into the WiX source file, which then (optionally) can be automatically compiled into MSI.
Wix# is nothing else but a syntax translator as it translates from C# syntax into WiX syntax.
Of course some other translation strategies are also possible. For example, deployment logic can be defined in a simple, very lean XML file and then it can be transformed (translated) into WiX XML with appropriate XSL. Such translation is definitely possible to implement, however C#-to-WiX offers a lot more advantages, which are sometimes not so obvious. One of them is self-documented nature of the C# code (in fact this is valid for any programming language code).
If you have a look at the definition of WDir (WiX directory) and WFile (WiX file) classes you will immediately understand the idea of how to define the instances of these classes in the code.
public class Dir : WixObject
{
public Dir(string targetPath, params WixObject[] items)
public File[] Files;
...
}
public class File : WixObject
{
public File(string sourcePath, params Shortcut[] items);
...
}
Consider expressing the directory-file relationship in C# and XML. Even without any knowledge about Wix# the developer can easily define the installation directory MyApp ontaining readme.txt and myApp.exe files (which are to be included in the final MSI from ..\Deployment
directory).
var dir = new Dir("MyApp")
{
Files = new []
{
new File(@"..\Deployment\myApp.exe"),
new File(@"..\Deployment\readme.txt")
}
};
And if you use WDir
/WFile
constructors, the above code can be simplified as follows:
var dir = new Dir("MyApp",
new File(@"..\Deployment\myApp.exe"),
new WFile(@"..\Deployment\readme.txt"));
And this is how the same directory/file relationship would be implemented in WiX:
<Directory Id="MyAppDir" Name="MyApp">
<Component Id="MyAppExeComp" Guid="f7d84551-ce7d-45c8-9f14-56a08255a60d">
<File Id="MyApp.exe" Source="..\Deployment\MyApp.exe"/>
</Component>
<Component Id="readmeComp" Guid="f7d84551-aeaa-45c8-9f14-56a08255a60d">
<File Id="readme.txt" Source="..\Deployment\readme.txt"/>
</Component>
</Directory>
Here is another example. There is a special XML element in WiX syntax: UIRef. It controls the type of UI to be used during setup execution. The syntax for this element is:
<UIRef Id="<ui_type>" />
where <ui_type>
is WixUI_ProgressOnly
,
WixUI_Minimal,
WixUI_InstallDir,
WixUI_FeatureTree
or WixUI_Mondo.
For the person who does not have extensive WiX experience it is impossible to guess how to define this XML element and what the correct values for this are. However, this task is much easier to accomplish in Wix#. Wix# WProject class has the "UI" property of the WUI type:
public enum WUI
{
WixUI_ProgressOnly,
WixUI_Minimal,
WixUI_InstallDir,
WixUI_FeatureTree,
WixUI_Mondo
}
public class WProject : WObject
{
public WUI UI;
...
Thus, it is obvious that if you want your setup to have "progress only" UI you need to set WProject
property UI
as follows:
new project = new Project();
project.UI = WUI.WixUI_ProgressOnly
And, of course, when dealing with Wix# you rely on IntelliSense and code completion rovided by your IDE.
Using Wix#
OK, Wix# is based on the C# syntax. But how exactly do you go from C# to MSI? Actually, it is quite simple. This is what you need to do:
Assuming you have downloaded Wix# and WiX binaries.
- Create the Visual Studio C# Console Application project containing trivial Program.cs with
static Main
. - Add Wix# as a referenced assembly (Wix.dll) or as a linked source file (Wix.cs)
- In
static Main
declare instance of WProject
, add files/shortcuts/registry keys to the project instance and call instance method WProject.BuildMsi
.
If you now compile the project into executable and run it, the MSI file will be generated. You can also create the Visual Studio project post-build event so MSI will be created on a successful build. Thus, such a Wix# Visual Studio project can be part of any software build.
There is also another way of compiling the Wix# source file into MSI. Instead of being included into the Visual Studio project, the Wix# source file (C# file) can be executed as a script by CS-Script engine. This way you can produce the corresponding MSI file directly from the C# code without any need for intermediate infrastructure (e.g. Visual Studio project). CS-Script is my other pet-project, which is described in details in the following CodeProject article C# Script: The Missing Puzzle Piece.
The examples of both Visual Studio and scriptable solutions are included in the article downloadables. Below are just a few of them:
Script for installing Manual.txt and MyApp.exe into <ProgramFiles>\My Company\My Product directory.
class Script
{
static public void Main(string[] args)
{
var project = new Project("MyProduct",
new Dir(@"%ProgramFiles%\My Company\My Product",
new File(@"Files\Docs\Manual.txt"),
new File(@"Files\Bin\MyApp.exe")));
project.Id = new Guid("6f330b47-2577-43ad-9095-1861ba25889b");
Compiler.BuildMsi(project);
}
}
Script for installing MyApp.exe into <ProgramFiles>\My Company\My Product directory; showing a custom license file; creating shortcuts to Install/Uninstall the product and to launch MyApp.exe from <Desktop> and <ProgramMenu>:
using System;
using WixSharp;
class Script
{
static public void Main(string[] args)
{
var project = new Project("MyProduct",
new Dir(@"%ProgramFiles%\My Company\My Product",
new File(@"Files\Bin\MyApp.exe",
new Shortcut(@"%ProgramMenu%\My Company\My Product"),
new Shortcut(@"%Desktop%")),
new Shortcut("Uninstall MyApp", "[System64Folder]msiexec.exe", "/x [ProductCode]")),
new Dir(@"%ProgramMenu%\My Company\My Product",
new Shortcut("Uninstall MyApp", "[System64Folder]msiexec.exe", "/x [ProductCode]"))));
project.Id = new Guid("6f330b47-2577-43ad-9095-1861ba25889b");
project.LicenceFile = @"AppFiles\License.rtf";
Compiler.BuildMsi(project); }
}
Script for installing MyApp.exe into <ProgramFiles>\My Company\My Product directory and showing custom a license file during the installation in FullUI mode (Mondo):
using System;
using WixSharp;
class Script
{
static public void Main(string[] args)
{
var project = new Project("MyProduct",
new Dir(@"%ProgramFiles%\My Company\My Product",
new File(@"Files\Bin\MyApp.exe")));
project.Id = new Guid("6f330b47-2577-43ad-9095-1861ba25889b");
project.UI = WUI.WixUI_Mondo;
Compiler.BuildMsi(project);
}
}
Script for installing readme.txt into <ProgramFiles>\My Company\My Product directory and setting String
and DWORD
registry values:
using System;
using WixSharp;
class Script
{
static public void Main(string[] args)
{
var project = new Project("MyProduct",
new Dir(@"%ProgramFiles%\My Company\My Product",
new File(@"readme.txt")),
new RegValue(RegistryHive.LocalMachine, "Software\\My Company\\My Product", "Message", "Hello"),
new RegValue(RegistryHive.LocalMachine, "Software\\My Company\\My Product", "Count", 777));
project.Id = new Guid("6f330b47-2577-43ad-9095-1861ba25889b");
project.UI = WUI.WixUI_ProgressOnly;
Compiler.BuildMsi(project);
}
}
Script for installing MyService.exe into <ProgramFiles>\My Company\My Product directory and registering it as Windows Service during installation and unregistering during uninstallation:
using System;
using WixSharp;
class Script
{
static public void Main(string[] args)
{
var project = new Project("MyProduct",
new Dir(@"%ProgramFiles%\My Company\My Product",
new File(@"Files\Bin\MyService.exe")),
new Action("MyService.exe", "",
Return.check,
When.After,
Step.InstallFinalize,
Condition.NOT_Installed),
new Action("MyService.exe", "/u",
Return.check,
When.Before,
Step.InstallFinalize,
Condition.Installed));
project.Id = new Guid("6f330b47-2577-43ad-9095-1861ba25889b");
project.UI = WUI.WixUI_ProgressOnly;
Compiler.BuildMsi(project);
}
}
As mentioned, before Wix# is a collection of very simple classes capable of forming relationships between each other and by doing so mimicking relationships between the WiX entities. The only class which exhibits more or less complex behavior is WProject. It has a method Project.BuildWxs
for translating its internal structure into WiX XML document. Another method of this class Project.BuildMsi
launches the WiX compiler and the linker against the previously built WiX file (.wxs) in order to produce MSI.
Strictly speaking it is all you need to know for authoring a valid MSI with Wix#. The rest can be learned by example. The samples for the common deployment scenarios are included in the article downloadables:
- Install file(s) into Program Files directory
- Change installation directory
- Install shortcut to installed file
- Install shortcut to installed file into Desktop directory
- Install "Uninstall Product" shortcut into "Program Menu" directory
- Install registry key
- Show custom licence file during the installation
- Launch installed application after/during the installation with Custom Action
- Execute VBScript Custom Action
- Execute Managed Custom Action
- Execute conditional actions
- Setting/Reading MSI properties during the installation
- Run setup with no/minimal/full UI
Arguably, the most intriguing feature of Wix# is the seamless support for managed Custom Actions. Managed Custom Actions is one of the most controversial features of WiX. After long arguments with WiX developers the MSI team refused to include support for managed Custom Actions in any near future. Thus, the WiX team made a decision to implement a special adapter for launching methods of managed assemblies from non-managed Custom Actions. This is how Deployment Tools Foundation (DTF) was born. Currently DTF is part of the WiX toolset. However, using DTF with raw WiX can sometimes be inconvenient as it requires multiple manual steps:
- Build the assembly containing the method implementing managed Custom Action behavior
- Package the assembly into WiX friendly native dll with MakeSfxCA.exe
- Compile the WiX file containing reference to native DLL with candle.exe
- Link obj files into MSI with candle.exe
But Wix# brings DTF to the ultimate usability level. With Wix# you do not have to use an external assembly for implementing managed Custom Action. You can just define the method implementing CA behavior and mark it with [CustomAction]
attribute and the rest will be handled by Wix# automatically. It will export the method and embed it into the final MSI. Thus you may achieve a single file deployment definition:
Script for installing MyApp.exe and prompting for system reboot at the end of the installation (default ManagedAction
sequence step is After.InstallFinalize
):
using System;
using System.Windows.Forms;
using System.Diagnostics;
using Microsoft.Deployment.WindowsInstaller;
using WixSharp;
class Script
{
static public void Main(string[] args)
{
var project = new Project("MyProduct",
new Dir(@"%ProgramFiles%\My Company\My Product",
new File(@"Files\Bin\MyApp.exe")),
new ManagedAction("PromptToReboot"));
project.Id = new Guid("6f330b47-2577-43ad-9095-1861ba25889b");
Compiler.BuildMsi(project);
}
}
public class CustonActions
{
[CustomAction]
public static ActionResult PromptToReboot(Session session)
{
if (DialogResult.Yes == MessageBox.Show("You need to reboot the system.\n
Do you want to reboot now?",
"ReboolTest Setup",
MessageBoxButtons.YesNo))
{
Process.Start("shutdown.exe",
"-r -t 30 -c \"Reboot has been requested from RebootTest.msi\"");
}
return ActionResult.Success;
}
}
There is an interesting aspect of the installation script above. Of course system reboot under MSI runtime can be implemented in a "traditional way" but with Managed CA you can have full freedom of implementation choices. You can decide what question to ask or even perform reboot in a friendlier manner with timeout.
Limitations
The presented Wix# framework has been developed and tested against WiX 3.0 Beta. Unfortunately, WiX 3.0 samples are not published by the WiX team and you can only download WiX 2.0 samples, which are not completely compatible with the WiX 3.0 engine. At least it was the case at the time when Wix# was developed.
Also Wix# covers only a part of the WiX interface. Even if Wix# evolved over the time, it would unlikely allow to utilize one hundred percent of WiX functionality.
And of course Wix# shares all limitations of WiX itself.
Conclusion
Wix# offers the simple and convenient interface for authoring MSI based setups by using C# syntax. It is up to you how to use it. You can:
- Use it to build complete MSIs.
- Use Wix# to produce a WiX source file, any required intermediate files and the corresponding batch file to build MSI (
Compiler.BuildMsiCmd()
). - Use Wix# engine as a wizard for producing the initial WiX source file.
- Use Wix# distribution as the WiX reference or samples library.
Someone has said "WiX documentation is rarer than gold". This is very true, particularly for code samples. Don't get me wrong, WiX support is great. You can find the answer for practically any technical question if you search WiX forums. You can find plenty of syntax fragments in the documentation. But there is a certain lack of complete code samples covering real deployment scenarios. And this is where Wix# can be particularly useful.
One thing to remember when designing any deployment solution is to keep business logic in the setup application (MSI) as minimal as possible. In other words, the closer your solution to the XCopy style of deployment, the more stable and maintainable it is. Try to keep any complex deployment behavior in the application being installed (or even in a separate application) and exercise this behavior during the installation and on the first use of the installed product.
I do realize how unorthodox this approach may appear to some WiX followers. MSI, especially in combination with WiX, is an extremely powerful framework, which allows implementing virtually any runtime behavior. And this may be the way to go if your company has a full-time MSI/WiX developer. However, heavy MSI/WiX solutions exhibit a number of deficiencies. They are difficult to debug. Their maintenance can be a challenge. The implementation of very complex algorithms using MSI is close to impossible. Thus, complex behavior has to be moved into separate libraries compiled with traditional programming languages.
Another reason for moving business logic outside raw MSI is a need to address deployment constrains imposed by the Vista environment. On Vista, applications should not keep configuration data (e.g. settings) in the application location. Instead, the application should create and maintain the initial set of configuration data in the user profile or public common application folders. A separate application can be a particularly good choice for managing application settings as it can be elevated (Vista Process Elevation) without elevating the primary application.
Wix# roadmap
In my company we've been using Wix# for almost 6 months and it works quite well for us. Nevertheless, Wix# users may encounter some usability problems, which will be handled as part of the post release support. However, as I am not an expert in WiX I cannot provide WiX support. You may find more comprehensive help from the WiX related resources.
What's next? Will the presented Wix# release become a full scale product with new releases, extensions, comprehensive documentation and tutorials?
Well, it will depend on user's feedback. If demand for such a product exists, Wix# will evolve and grow in functionality. Particularly interesting direction is an integration with other development tools. Thus, I will greatly appreciate your feedback.
Points of Interest
- Currently Wix# is available in a form of .cs file to allow quick access to the whole Wix# implementation. This will allow developers to see what exactly is happening under the hood. However, when Wix# functionality is finalized it will most likely be distributed as an assembly.
- WiX v3.0 is still under development, thus WiX binaries are included in the Wix# distribution to avoid any incompatibility. You can download and install any available version of WiX and this will have no conflict with Wix# as long as location of WiX binaries distributed with Wix# is published as the environment variable WIXSHARP_DIR. The install.cmd file in Wix# distribution handles this.
- The CS-Script engine file (cscs.exe) is also distributed with Wix#, however I would encourage you to download and install a full version of CS-Script (www.csscript.net) as this will allow you to open, edit and debug your installation scripts in a Visual Studio with a single mouse right-click.
- Install.cmd file in the Wix# distribution demonstrates how to set the environment variable permanently from a batch file.
- You may have noticed that in this release I avoided using properties in all Wix entities and used the fields instead. This is because I tried to minimize the codebase as much as possible to give better readability. Of course auto-properties can serve the same purpose but they do not allow auto-initialization outside the constructors like fields do.
- You can use different declaration styles when coding your setup. This is demonstrated in the samples within the CodingStyles directory.You can use initializers, which make the code closer to Inno-style coding:
var project = new Project()
{
Name = "MyProduct",
Id = 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")
}
}
}
};
WCompiler.BuildMsiCmd(project);
Alternatively you can use the constructors (my preferred style), which make code look like the XDocument definition routine:
WProject project = new Project("MyProduct",
new Dir(@"%ProgramFiles%\My Company\My Product"),
new File(@"Files\Docs\Manual.txt"),
new File(@"Files\Bin\MyApp.exe")));
project.Id = new Guid("6f330b47-2577-43ad-9095-1861ba25889b");
Compiler.BuildMsi(project);