// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information.
namespace WixToolset.BuildTasks
{
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.IO;
using System.Text;
using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;
///
/// An MSBuild task to run the WiX linker.
///
public sealed class Light : WixToolTask
{
private const string LightToolName = "Light.exe";
private string additionalCub;
private bool allowIdenticalRows;
private bool allowUnresolvedReferences;
private string[] baseInputPaths;
private ITaskItem[] bindInputPaths;
private bool backwardsCompatibleGuidGeneration;
private bool bindFiles;
private ITaskItem builtOutputsFile;
private string cabinetCachePath;
private int cabinetCreationThreadCount = WixCommandLineBuilder.Unspecified;
private ITaskItem contentsFile;
private string cultures;
private string customBinder;
private string defaultCompressionLevel;
private ITaskItem[] extensions;
private string[] ices;
private bool leaveTemporaryFiles;
private ITaskItem[] localizationFiles;
private ITaskItem[] objectFiles;
private bool outputAsXml;
private ITaskItem outputsFile;
private ITaskItem outputFile;
private ITaskItem pdbOutputFile;
private ITaskItem wixProjectFile;
private bool pedantic;
private bool reuseCabinetCache;
private bool suppressAclReset;
private bool suppressAssemblies;
private bool suppressDefaultAdminSequenceActions;
private bool suppressDefaultAdvSequenceActions;
private bool suppressDefaultUISequenceActions;
private bool dropUnrealTables;
private bool exactAssemblyVersions;
private bool suppressFileHashAndInfo;
private bool suppressFiles;
private bool suppressIntermediateFileVersionMatching;
private string[] suppressIces;
private bool suppressLayout;
private bool suppressLocalization;
private bool suppressMsiAssemblyTableProcessing;
private bool suppressPdbOutput;
private bool suppressSchemaValidation;
private bool suppressValidation;
private bool suppressTagSectionIdAttributeOnTuples;
private ITaskItem unreferencedSymbolsFile;
private string[] wixVariables;
private string extensionDirectory;
private string[] referencePaths;
///
/// Creates a new light task.
///
///
/// Defaults to running the task as a separate process, instead of in-proc
/// which is the default for WixToolTasks. This allows the Win32 manifest file
/// embedded in light.exe to enable reg-free COM interop with mergemod.dll.
///
public Light()
{
}
public string AdditionalCub
{
get { return this.additionalCub; }
set { this.additionalCub = value; }
}
public bool AllowIdenticalRows
{
get { return this.allowIdenticalRows; }
set { this.allowIdenticalRows = value; }
}
public bool AllowUnresolvedReferences
{
get { return this.allowUnresolvedReferences; }
set { this.allowUnresolvedReferences = value; }
}
// TODO: remove this property entirely in v4.0
[Obsolete("Use BindInputPaths instead of BaseInputPaths.")]
public string[] BaseInputPaths
{
get { return this.baseInputPaths; }
set { this.baseInputPaths = value; }
}
public ITaskItem[] BindInputPaths
{
get { return this.bindInputPaths; }
set { this.bindInputPaths = value; }
}
public bool BackwardsCompatibleGuidGeneration
{
get { return this.backwardsCompatibleGuidGeneration; }
set { this.backwardsCompatibleGuidGeneration = value; }
}
public bool BindFiles
{
get { return this.bindFiles; }
set { this.bindFiles = value; }
}
public string CabinetCachePath
{
get { return this.cabinetCachePath; }
set { this.cabinetCachePath = value; }
}
public int CabinetCreationThreadCount
{
get { return this.cabinetCreationThreadCount; }
set { this.cabinetCreationThreadCount = value; }
}
public ITaskItem BindBuiltOutputsFile
{
get { return this.builtOutputsFile; }
set { this.builtOutputsFile = value; }
}
public ITaskItem BindContentsFile
{
get { return this.contentsFile; }
set { this.contentsFile = value; }
}
public ITaskItem BindOutputsFile
{
get { return this.outputsFile; }
set { this.outputsFile = value; }
}
public string Cultures
{
get { return this.cultures; }
set { this.cultures = value; }
}
public string CustomBinder
{
get { return this.customBinder; }
set { this.customBinder = value; }
}
public string DefaultCompressionLevel
{
get { return this.defaultCompressionLevel; }
set { this.defaultCompressionLevel = value; }
}
public bool DropUnrealTables
{
get { return this.dropUnrealTables; }
set { this.dropUnrealTables = value; }
}
public bool ExactAssemblyVersions
{
get { return this.exactAssemblyVersions; }
set { this.exactAssemblyVersions = value; }
}
public ITaskItem[] Extensions
{
get { return this.extensions; }
set { this.extensions = value; }
}
public string[] Ices
{
get { return this.ices; }
set { this.ices = value; }
}
public bool LeaveTemporaryFiles
{
get { return this.leaveTemporaryFiles; }
set { this.leaveTemporaryFiles = value; }
}
public ITaskItem[] LocalizationFiles
{
get { return this.localizationFiles; }
set { this.localizationFiles = value; }
}
[Required]
public ITaskItem[] ObjectFiles
{
get { return this.objectFiles; }
set { this.objectFiles = value; }
}
public bool OutputAsXml
{
get { return this.outputAsXml; }
set { this.outputAsXml = value; }
}
[Required]
[Output]
public ITaskItem OutputFile
{
get { return this.outputFile; }
set { this.outputFile = value; }
}
[Output]
public ITaskItem PdbOutputFile
{
get { return this.pdbOutputFile; }
set { this.pdbOutputFile = value; }
}
public bool Pedantic
{
get { return this.pedantic; }
set { this.pedantic = value; }
}
public bool ReuseCabinetCache
{
get { return this.reuseCabinetCache; }
set { this.reuseCabinetCache = value; }
}
public bool SuppressAclReset
{
get { return this.suppressAclReset; }
set { this.suppressAclReset = value; }
}
public bool SuppressAssemblies
{
get { return this.suppressAssemblies; }
set { this.suppressAssemblies = value; }
}
public bool SuppressDefaultAdminSequenceActions
{
get { return this.suppressDefaultAdminSequenceActions; }
set { this.suppressDefaultAdminSequenceActions = value; }
}
public bool SuppressDefaultAdvSequenceActions
{
get { return this.suppressDefaultAdvSequenceActions; }
set { this.suppressDefaultAdvSequenceActions = value; }
}
public bool SuppressDefaultUISequenceActions
{
get { return this.suppressDefaultUISequenceActions; }
set { this.suppressDefaultUISequenceActions = value; }
}
public bool SuppressFileHashAndInfo
{
get { return this.suppressFileHashAndInfo; }
set { this.suppressFileHashAndInfo = value; }
}
public bool SuppressFiles
{
get { return this.suppressFiles; }
set { this.suppressFiles = value; }
}
public bool SuppressIntermediateFileVersionMatching
{
get { return this.suppressIntermediateFileVersionMatching; }
set { this.suppressIntermediateFileVersionMatching = value; }
}
public string[] SuppressIces
{
get { return this.suppressIces; }
set { this.suppressIces = value; }
}
public bool SuppressLayout
{
get { return this.suppressLayout; }
set { this.suppressLayout = value; }
}
public bool SuppressLocalization
{
get { return this.suppressLocalization; }
set { this.suppressLocalization = value; }
}
[SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly")]
public bool SuppressMsiAssemblyTableProcessing
{
get { return this.suppressMsiAssemblyTableProcessing; }
set { this.suppressMsiAssemblyTableProcessing = value; }
}
public bool SuppressPdbOutput
{
get { return this.suppressPdbOutput; }
set { this.suppressPdbOutput = value; }
}
public bool SuppressSchemaValidation
{
get { return this.suppressSchemaValidation; }
set { this.suppressSchemaValidation = value; }
}
public bool SuppressValidation
{
get { return this.suppressValidation; }
set { this.suppressValidation = value; }
}
public bool SuppressTagSectionIdAttributeOnTuples
{
get { return this.suppressTagSectionIdAttributeOnTuples; }
set { this.suppressTagSectionIdAttributeOnTuples = value; }
}
[Output]
public ITaskItem UnreferencedSymbolsFile
{
get { return this.unreferencedSymbolsFile; }
set { this.unreferencedSymbolsFile = value; }
}
[SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly")]
public ITaskItem WixProjectFile
{
get { return this.wixProjectFile; }
set { this.wixProjectFile = value; }
}
[SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly")]
public string[] WixVariables
{
get { return this.wixVariables; }
set { this.wixVariables = value; }
}
public string ExtensionDirectory
{
get { return this.extensionDirectory; }
set { this.extensionDirectory = value; }
}
public string[] ReferencePaths
{
get { return this.referencePaths; }
set { this.referencePaths = value; }
}
///
/// Get the name of the executable.
///
/// The ToolName is used with the ToolPath to get the location of light.exe.
/// The name of the executable.
protected override string ToolName
{
get { return LightToolName; }
}
///
/// Get the path to the executable.
///
/// GetFullPathToTool is only called when the ToolPath property is not set (see the ToolName remarks above).
/// The full path to the executable or simply light.exe if it's expected to be in the system path.
protected override string GenerateFullPathToTool()
{
// If there's not a ToolPath specified, it has to be in the system path.
if (String.IsNullOrEmpty(this.ToolPath))
{
return LightToolName;
}
return Path.Combine(Path.GetFullPath(this.ToolPath), LightToolName);
}
///
/// Builds a command line from options in this task.
///
protected override void BuildCommandLine(WixCommandLineBuilder commandLineBuilder)
{
// Always put the output first so it is easy to find in the log.
commandLineBuilder.AppendSwitchIfNotNull("-out ", this.OutputFile);
commandLineBuilder.AppendSwitchIfNotNull("-pdbout ", this.PdbOutputFile);
base.BuildCommandLine(commandLineBuilder);
commandLineBuilder.AppendIfTrue("-ai", this.AllowIdenticalRows);
commandLineBuilder.AppendIfTrue("-au", this.AllowUnresolvedReferences);
commandLineBuilder.AppendArrayIfNotNull("-b ", this.baseInputPaths);
if (null != this.BindInputPaths)
{
Queue formattedBindInputPaths = new Queue();
foreach (ITaskItem item in this.BindInputPaths)
{
String formattedPath = string.Empty;
String bindName = item.GetMetadata("BindName");
if (!String.IsNullOrEmpty(bindName))
{
formattedPath = String.Concat(bindName, "=", item.GetMetadata("FullPath"));
}
else
{
formattedPath = item.GetMetadata("FullPath");
}
formattedBindInputPaths.Enqueue(formattedPath);
}
commandLineBuilder.AppendArrayIfNotNull("-b ", formattedBindInputPaths.ToArray());
}
commandLineBuilder.AppendIfTrue("-bcgg", this.BackwardsCompatibleGuidGeneration);
commandLineBuilder.AppendIfTrue("-bf", this.BindFiles);
commandLineBuilder.AppendSwitchIfNotNull("-cc ", this.CabinetCachePath);
commandLineBuilder.AppendIfSpecified("-ct ", this.CabinetCreationThreadCount);
commandLineBuilder.AppendSwitchIfNotNull("-cub ", this.AdditionalCub);
commandLineBuilder.AppendSwitchIfNotNull("-cultures:", this.Cultures);
commandLineBuilder.AppendSwitchIfNotNull("-binder ", this.CustomBinder);
commandLineBuilder.AppendArrayIfNotNull("-d", this.WixVariables);
commandLineBuilder.AppendSwitchIfNotNull("-dcl:", this.DefaultCompressionLevel);
commandLineBuilder.AppendIfTrue("-dut", this.DropUnrealTables);
commandLineBuilder.AppendIfTrue("-eav", this.ExactAssemblyVersions);
commandLineBuilder.AppendExtensions(this.Extensions, this.ExtensionDirectory, this.referencePaths);
commandLineBuilder.AppendArrayIfNotNull("-ice:", this.Ices);
commandLineBuilder.AppendArrayIfNotNull("-loc ", this.LocalizationFiles);
commandLineBuilder.AppendIfTrue("-notidy", this.LeaveTemporaryFiles);
commandLineBuilder.AppendIfTrue("-pedantic", this.Pedantic);
commandLineBuilder.AppendIfTrue("-reusecab", this.ReuseCabinetCache);
commandLineBuilder.AppendIfTrue("-sa", this.SuppressAssemblies);
commandLineBuilder.AppendIfTrue("-sacl", this.SuppressAclReset);
commandLineBuilder.AppendIfTrue("-sadmin", this.SuppressDefaultAdminSequenceActions);
commandLineBuilder.AppendIfTrue("-sadv", this.SuppressDefaultAdvSequenceActions);
commandLineBuilder.AppendArrayIfNotNull("-sice:", this.SuppressIces);
commandLineBuilder.AppendIfTrue("-sma", this.SuppressMsiAssemblyTableProcessing);
commandLineBuilder.AppendIfTrue("-sf", this.SuppressFiles);
commandLineBuilder.AppendIfTrue("-sh", this.SuppressFileHashAndInfo);
commandLineBuilder.AppendIfTrue("-sl", this.SuppressLayout);
commandLineBuilder.AppendIfTrue("-sloc", this.SuppressLocalization);
commandLineBuilder.AppendIfTrue("-spdb", this.SuppressPdbOutput);
commandLineBuilder.AppendIfTrue("-ss", this.SuppressSchemaValidation);
commandLineBuilder.AppendIfTrue("-sts", this.SuppressTagSectionIdAttributeOnTuples);
commandLineBuilder.AppendIfTrue("-sui", this.SuppressDefaultUISequenceActions);
commandLineBuilder.AppendIfTrue("-sv", this.SuppressIntermediateFileVersionMatching);
commandLineBuilder.AppendIfTrue("-sval", this.SuppressValidation);
commandLineBuilder.AppendSwitchIfNotNull("-usf ", this.UnreferencedSymbolsFile);
commandLineBuilder.AppendIfTrue("-xo", this.OutputAsXml);
commandLineBuilder.AppendSwitchIfNotNull("-contentsfile ", this.BindContentsFile);
commandLineBuilder.AppendSwitchIfNotNull("-outputsfile ", this.BindOutputsFile);
commandLineBuilder.AppendSwitchIfNotNull("-builtoutputsfile ", this.BindBuiltOutputsFile);
commandLineBuilder.AppendSwitchIfNotNull("-wixprojectfile ", this.WixProjectFile);
commandLineBuilder.AppendTextIfNotNull(this.AdditionalOptions);
List objectFilePaths = AdjustFilePaths(this.objectFiles, this.ReferencePaths);
commandLineBuilder.AppendFileNamesIfNotNull(objectFilePaths.ToArray(), " ");
}
}
}