WiX: Writing your own WiX Extension Part 2: Preprocessor
The preprocessor in WiX allows extensibilty at a few levels. In this article I will describe how to add a PreprocessorExtension to your WixExtension and have it handle variables and functions you define in your own namespace.
[This sample assumes you have already gone through Part 1]
1. Add a new class to your project called SamplePreprocessorExtension.
2. If you added a new file for this class, make sure you add: using Microsoft.Tools.WindowsInstallerXml to you file.
3. Make your SamplePreprocessorExtension class implement PreprocessorExtension.
public class SamplePreprocessorExtension : PreprocessorExtension
4. Add your SamplePreprocessorExtension to your SampleWixExtension class and override the PreprocessorExtension property from the base class. This will make it so when WiX asks your extension for your preprocessor extension, you extension will know what to do.
private SamplePreprocessorExtension preprocessorExtension;
public override PreprocessorExtension PreprocessorExtension
{
get
{
if (this.preprocessorExtension == null)
{
this.preprocessorExtension = new SamplePreprocessorExtension();
}
return this.preprocessorExtension;
}
}
5. Now, back in your SamplePreprocessorExtension class, you need to specify what prefixes (or namespaces) your extension will handle. For example, if you want to be able to define a variable $(sample.ReplaceMe) then you need to specify that your extension will handle the "sample" prefix.
private static string[] prefixes = { "sample" };
public override string[] Prefixes { get { return prefixes; } }
6. Now that you have specified your prefixes, you now need to handle variables and functions that are passed to you from WiX. You do this by overriding the GetVariable and EvaluateFunction methods from the PreprocessorExtension base class.
public override string GetVariableValue(string prefix, string name)
{
string result = null;
// Based on the namespace and name, define the resulting string.
switch (prefix)
{
case "sample":
switch (name)
{
case "ReplaceMe":
// This could be looked up from any where you can access from your code.
result = "replaced";
break;
}
break;
}
return result;
}
public override string EvaluateFunction(string prefix, string function, string[] args)
{
string result = null;
switch (prefix)
{
case "sample":
switch (function)
{
case "ToUpper":
if (0 < args.Length)
{
result = args[0].ToUpper();
}
else
{
result = String.Empty;
}
break;
}
break;
}
return result;
}
7. Build
8. With this you can now pass your extension on the command line to candle and expect variables and functions in your namespace to be passed to your extension and be evaluated. To prove this, try adding the following properties your WiX source.
<Property Id="VARIABLETEST" Value="$(sample.ReplaceMe)" />
<Property Id="FUNCTIONTEST" Value="$(sample.ToUpper(lowercase))" />
You resulting msi should have entries in the Property table with the values "replaced" and "LOWERCASE" in the property table.