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
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.