From ecf3a0cca5a424a91ab98557d963d2535963d582 Mon Sep 17 00:00:00 2001 From: Rob Mensching Date: Fri, 22 Dec 2017 15:53:01 -0800 Subject: Reintroduce binder extensions and light.exe for binding .wixouts --- src/WixToolset.Core/Binder.cs | 461 ++++++------------------------------------ 1 file changed, 65 insertions(+), 396 deletions(-) (limited to 'src/WixToolset.Core/Binder.cs') diff --git a/src/WixToolset.Core/Binder.cs b/src/WixToolset.Core/Binder.cs index 9db27fec..c442c94d 100644 --- a/src/WixToolset.Core/Binder.cs +++ b/src/WixToolset.Core/Binder.cs @@ -5,10 +5,8 @@ namespace WixToolset.Core using System; using System.Collections.Generic; using System.Diagnostics; - using System.IO; using System.Linq; using System.Reflection; - using WixToolset.Core.Bind; using WixToolset.Data; using WixToolset.Data.Bind; using WixToolset.Data.Tuples; @@ -20,334 +18,110 @@ namespace WixToolset.Core /// public sealed class Binder { - //private BinderCore core; - //private List extensions; - //private List fileManagers; - - public Binder() + public Binder(IServiceProvider serviceProvider) { - //this.DefaultCompressionLevel = CompressionLevel.High; - - //this.BindPaths = new List(); - //this.TargetBindPaths = new List(); - //this.UpdatedBindPaths = new List(); - - //this.extensions = new List(); - //this.fileManagers = new List(); - //this.inspectorExtensions = new List(); - - //this.Ices = new List(); - //this.SuppressIces = new List(); + this.ServiceProvider = serviceProvider; } - private IBindContext Context { get; set; } - - //private TableDefinitionCollection TableDefinitions { get; } + public int CabbingThreadCount { get; set; } - //public IEnumerable BackendFactories { get; set; } + public string CabCachePath { get; set; } - //public string ContentsFile { private get; set; } + public int Codepage { get; set; } - //public string OutputsFile { private get; set; } + public CompressionLevel? DefaultCompressionLevel { get; set; } - //public string BuiltOutputsFile { private get; set; } + public IEnumerable DelayedFields { get; set; } - //public string WixprojectFile { private get; set; } + public IEnumerable ExpectedEmbeddedFiles { get; set; } - /// - /// Gets the list of bindpaths. - /// - //public List BindPaths { get; private set; } + public IEnumerable Ices { get; set; } - /// - /// Gets the list of target bindpaths. - /// - //public List TargetBindPaths { get; private set; } + public string IntermediateFolder { get; set; } - /// - /// Gets the list of updated bindpaths. - /// - //public List UpdatedBindPaths { get; private set; } + public Intermediate IntermediateRepresentation { get; set; } - /// - /// Gets or sets the option to enable building binary delta patches. - /// - /// The option to enable building binary delta patches. - public bool DeltaBinaryPatch { get; set; } + public string OutputPath { get; set; } - /// - /// Gets or sets the cabinet cache location. - /// - public string CabCachePath { get; set; } + public string OutputPdbPath { get; set; } - /// - /// Gets or sets the number of threads to use for cabinet creation. - /// - /// The number of threads to use for cabinet creation. - public int CabbingThreadCount { get; set; } + public IEnumerable SuppressIces { get; set; } - /// - /// Gets or sets the default compression level to use for cabinets - /// that don't have their compression level explicitly set. - /// - //public CompressionLevel DefaultCompressionLevel { get; set; } - - /// - /// Gets and sets the location to save the WixPdb. - /// - /// The location in which to save the WixPdb. Null if the the WixPdb should not be output. - //public string PdbFile { get; set; } - - //public List Ices { get; private set; } - - //public List SuppressIces { get; private set; } - - /// - /// Gets and sets the option to suppress resetting ACLs by the binder. - /// - /// The option to suppress resetting ACLs by the binder. - public bool SuppressAclReset { get; set; } - - /// - /// Gets and sets the option to suppress creating an image for MSI/MSM. - /// - /// The option to suppress creating an image for MSI/MSM. - public bool SuppressLayout { get; set; } - - /// - /// Gets and sets the option to suppress MSI/MSM validation. - /// - /// The option to suppress MSI/MSM validation. - /// This must be set before calling Bind. public bool SuppressValidation { get; set; } - /// - /// Gets and sets the option to suppress adding _Validation table rows. - /// - public bool SuppressAddingValidationRows { get; set; } - - /// - /// Gets or sets the localizer. - /// - /// The localizer. - public Localizer Localizer { get; set; } - - /// - /// Gets or sets the temporary path for the Binder. If left null, the binder - /// will use %TEMP% environment variable. - /// - /// Path to temp files. - public string TempFilesLocation { get; set; } - - /// - /// Gets or sets the Wix variable resolver. - /// - /// The Wix variable resolver. - internal WixVariableResolver WixVariableResolver { get; set; } - - public BindResult Bind(IBindContext context) - { - this.Context = context; + public bool DeltaBinaryPatch { get; set; } - this.WriteBuildInfoTable(this.Context.IntermediateRepresentation, this.Context.OutputPath); + public IServiceProvider ServiceProvider { get; } - var bindResult = this.BackendBind(); - return bindResult; - } - -//// private ResolveResult Resolve() -//// { -//// var buildingPatch = this.Context.IntermediateRepresentation.Sections.Any(s => s.Type == SectionType.Patch); - -//// var filesWithEmbeddedFiles = new ExtractEmbeddedFiles(); - -//// IEnumerable delayedFields; -//// { -//// var command = new ResolveFieldsCommand(); -//// command.Messaging = this.Context.Messaging; -//// command.BuildingPatch = buildingPatch; -//// command.BindVariableResolver = this.Context.WixVariableResolver; -//// command.BindPaths = this.Context.BindPaths; -//// command.Extensions = this.Context.Extensions; -//// command.FilesWithEmbeddedFiles = filesWithEmbeddedFiles; -//// command.IntermediateFolder = this.Context.IntermediateFolder; -//// command.Intermediate = this.Context.IntermediateRepresentation; -//// command.SupportDelayedResolution = true; -//// command.Execute(); - -//// delayedFields = command.DelayedFields; -//// } - -////#if REVISIT_FOR_PATCHING -//// if (this.Context.IntermediateRepresentation.SubStorages != null) -//// { -//// foreach (SubStorage transform in this.Context.IntermediateRepresentation.SubStorages) -//// { -//// var command = new ResolveFieldsCommand(); -//// command.BuildingPatch = buildingPatch; -//// command.BindVariableResolver = this.Context.WixVariableResolver; -//// command.BindPaths = this.Context.BindPaths; -//// command.Extensions = this.Context.Extensions; -//// command.FilesWithEmbeddedFiles = filesWithEmbeddedFiles; -//// command.IntermediateFolder = this.Context.IntermediateFolder; -//// command.Intermediate = this.Context.IntermediateRepresentation; -//// command.SupportDelayedResolution = false; -//// command.Execute(); -//// } -//// } -////#endif - -//// var expectedEmbeddedFiles = filesWithEmbeddedFiles.GetExpectedEmbeddedFiles(); - -//// return new ResolveResult -//// { -//// ExpectedEmbeddedFiles = expectedEmbeddedFiles, -//// DelayedFields = delayedFields, -//// }; -//// } - - private BindResult BackendBind() + public BindResult Execute() { - var extensionManager = this.Context.ServiceProvider.GetService(); + var context = this.ServiceProvider.GetService(); + context.Messaging = this.ServiceProvider.GetService(); + context.CabbingThreadCount = this.CabbingThreadCount; + context.CabCachePath = this.CabCachePath; + context.Codepage = this.Codepage; + context.DefaultCompressionLevel = this.DefaultCompressionLevel; + context.DelayedFields = this.DelayedFields; + context.ExpectedEmbeddedFiles = this.ExpectedEmbeddedFiles; + context.Extensions = this.ServiceProvider.GetService().Create(); + context.Ices = this.Ices; + context.IntermediateFolder = this.IntermediateFolder; + context.IntermediateRepresentation = this.IntermediateRepresentation; + context.OutputPath = this.OutputPath; + context.OutputPdbPath = this.OutputPdbPath; + context.SuppressIces = this.SuppressIces; + context.SuppressValidation = this.SuppressValidation; + + + // Prebind. + // + foreach (var extension in context.Extensions) + { + extension.PreBind(context); + } - var backendFactories = extensionManager.Create(); + // Bind. + // + this.WriteBuildInfoTable(context.IntermediateRepresentation, context.OutputPath, context.OutputPdbPath); - var entrySection = this.Context.IntermediateRepresentation.Sections[0]; + var bindResult = this.BackendBind(context); - foreach (var factory in backendFactories) + if (bindResult != null) { - if (factory.TryCreateBackend(entrySection.Type.ToString(), this.Context.OutputPath, null, out var backend)) + // Postbind. + // + foreach (var extension in context.Extensions) { - var result = backend.Bind(this.Context); - return result; + extension.PostBind(bindResult); } } - // TODO: messaging that a backend could not be found to bind the output type? - - return null; + return bindResult; } - /// - /// Binds an output. - /// - /// The output to bind. - /// The Windows Installer file to create. - /// The Binder.DeleteTempFiles method should be called after calling this method. - /// true if binding completed successfully; false otherwise -#if false - public bool Bind(Output output, string file) + private BindResult BackendBind(IBindContext context) { - // Ensure the cabinet cache path exists if we are going to use it. - if (!String.IsNullOrEmpty(this.CabCachePath)) - { - Directory.CreateDirectory(this.CabCachePath); - } - - //var fileManagerCore = new BinderFileManagerCore(); - //fileManagerCore.CabCachePath = this.CabCachePath; - //fileManagerCore.Output = output; - //fileManagerCore.TempFilesLocation = this.TempFilesLocation; - //fileManagerCore.AddBindPaths(this.BindPaths, BindStage.Normal); - //fileManagerCore.AddBindPaths(this.TargetBindPaths, BindStage.Target); - //fileManagerCore.AddBindPaths(this.UpdatedBindPaths, BindStage.Updated); - //foreach (IBinderFileManager fileManager in this.fileManagers) - //{ - // fileManager.Core = fileManagerCore; - //} - - this.core = new BinderCore(); - this.core.FileManagerCore = fileManagerCore; - - this.WriteBuildInfoTable(output, file); - - // Initialize extensions. - foreach (IBinderExtension extension in this.extensions) - { - extension.Core = this.core; - - extension.Initialize(output); - } - - // Gather all the wix variables. - //Table wixVariableTable = output.Tables["WixVariable"]; - //if (null != wixVariableTable) - //{ - // foreach (WixVariableRow wixVariableRow in wixVariableTable.Rows) - // { - // this.WixVariableResolver.AddVariable(wixVariableRow); - // } - //} - - //BindContext context = new BindContext(); - //context.CabbingThreadCount = this.CabbingThreadCount; - //context.DefaultCompressionLevel = this.DefaultCompressionLevel; - //context.Extensions = this.extensions; - //context.FileManagerCore = fileManagerCore; - //context.FileManagers = this.fileManagers; - //context.Ices = this.Ices; - //context.IntermediateFolder = this.TempFilesLocation; - //context.IntermediateRepresentation = output; - //context.Localizer = this.Localizer; - //context.OutputPath = file; - //context.OutputPdbPath = this.PdbFile; - //context.SuppressIces = this.SuppressIces; - //context.SuppressValidation = this.SuppressValidation; - //context.WixVariableResolver = this.WixVariableResolver; - - BindResult result = null; - - foreach (var factory in this.BackendFactories) - { - if (factory.TryCreateBackend(output.Type.ToString(), file, null, out var backend)) - { - result = backend.Bind(context); - break; - } - } + var extensionManager = context.ServiceProvider.GetService(); - if (result == null) - { - // TODO: messaging that a backend could not be found to bind the output type? + var backendFactories = extensionManager.Create(); - return false; - } + var entrySection = context.IntermediateRepresentation.Sections[0]; - // Layout media - try - { - this.LayoutMedia(result.FileTransfers); - } - finally + foreach (var factory in backendFactories) { - if (!String.IsNullOrEmpty(this.ContentsFile) && result.ContentFilePaths != null) - { - this.CreateContentsFile(this.ContentsFile, result.ContentFilePaths); - } - - if (!String.IsNullOrEmpty(this.OutputsFile) && result.FileTransfers != null) + if (factory.TryCreateBackend(entrySection.Type.ToString(), context.OutputPath, null, out var backend)) { - this.CreateOutputsFile(this.OutputsFile, result.FileTransfers, this.PdbFile); - } - - if (!String.IsNullOrEmpty(this.BuiltOutputsFile) && result.FileTransfers != null) - { - this.CreateBuiltOutputsFile(this.BuiltOutputsFile, result.FileTransfers, this.PdbFile); + var result = backend.Bind(context); + return result; } } - this.core = null; + // TODO: messaging that a backend could not be found to bind the output type? - return Messaging.Instance.EncounteredError; + return null; } -#endif - - /// - /// Populates the WixBuildInfo table in an output. - /// - /// The output. - /// The output file if OutputFile not set. - private void WriteBuildInfoTable(Intermediate output, string outputFile) + + private void WriteBuildInfoTable(Intermediate output, string outputFile, string outputPdbPath) { var entrySection = output.Sections.First(s => s.Type != SectionType.Fragment); @@ -358,117 +132,12 @@ namespace WixToolset.Core buildInfoRow.WixVersion = fileVersion.FileVersion; buildInfoRow.WixOutputFile = outputFile; - if (!String.IsNullOrEmpty(this.Context.WixprojectFile)) - { - buildInfoRow.WixProjectFile = this.Context.WixprojectFile; - } - - if (!String.IsNullOrEmpty(this.Context.OutputPdbPath)) + if (!String.IsNullOrEmpty(outputPdbPath)) { - buildInfoRow.WixPdbFile = this.Context.OutputPdbPath; + buildInfoRow.WixPdbFile = outputPdbPath; } entrySection.Tuples.Add(buildInfoRow); } - -#if DELETE_THIS_CODE - /// - /// Binds a bundle. - /// - /// The bundle to bind. - /// The bundle to create. - private void BindBundle(Output bundle, string bundleFile, out IEnumerable fileTransfers, out IEnumerable contentPaths) - { - BindBundleCommand command = new BindBundleCommand(); - command.DefaultCompressionLevel = this.DefaultCompressionLevel; - command.Extensions = this.extensions; - command.FileManagerCore = this.fileManagerCore; - command.FileManagers = this.fileManagers; - command.Output = bundle; - command.OutputPath = bundleFile; - command.PdbFile = this.PdbFile; - command.TableDefinitions = this.core.TableDefinitions; - command.TempFilesLocation = this.TempFilesLocation; - command.WixVariableResolver = this.WixVariableResolver; - command.Execute(); - - fileTransfers = command.FileTransfers; - contentPaths = command.ContentFilePaths; - } - - /// - /// Binds a databse. - /// - /// The output to bind. - /// The database file to create. - private void BindDatabase(Output output, string databaseFile, out IEnumerable fileTransfers, out IEnumerable contentPaths) - { - Validator validator = null; - - // tell the binder about the validator if validation isn't suppressed - if (!this.SuppressValidation && (OutputType.Module == output.Type || OutputType.Product == output.Type)) - { - validator = new Validator(); - validator.TempFilesLocation = Path.Combine(this.TempFilesLocation, "validate"); - - // set the default cube file - string lightDirectory = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); - string cubePath = (OutputType.Module == output.Type) ? Path.Combine(lightDirectory, "mergemod.cub") : Path.Combine(lightDirectory, "darice.cub"); - validator.AddCubeFile(cubePath); - - // by default, disable ICEs that have equivalent-or-better checks in WiX - this.SuppressIces.Add("ICE08"); - this.SuppressIces.Add("ICE33"); - this.SuppressIces.Add("ICE47"); - this.SuppressIces.Add("ICE66"); - - // set the ICEs - validator.ICEs = this.Ices.ToArray(); - - // set the suppressed ICEs - validator.SuppressedICEs = this.SuppressIces.ToArray(); - } - - BindDatabaseCommand command = new BindDatabaseCommand(); - command.CabbingThreadCount = this.CabbingThreadCount; - command.Codepage = this.Localizer == null ? -1 : this.Localizer.Codepage; - command.DefaultCompressionLevel = this.DefaultCompressionLevel; - command.Extensions = this.extensions; - command.FileManagerCore = this.fileManagerCore; - command.FileManagers = this.fileManagers; - command.InspectorExtensions = this.inspectorExtensions; - command.Localizer = this.Localizer; - command.PdbFile = this.PdbFile; - command.Output = output; - command.OutputPath = databaseFile; - command.SuppressAddingValidationRows = this.SuppressAddingValidationRows; - command.SuppressLayout = this.SuppressLayout; - command.TableDefinitions = this.core.TableDefinitions; - command.TempFilesLocation = this.TempFilesLocation; - command.Validator = validator; - command.WixVariableResolver = this.WixVariableResolver; - command.Execute(); - - fileTransfers = command.FileTransfers; - contentPaths = command.ContentFilePaths; - } - - /// - /// Binds a transform. - /// - /// The transform to bind. - /// The transform to create. - private void BindTransform(Output transform, string outputPath) - { - BindTransformCommand command = new BindTransformCommand(); - command.Extensions = this.extensions; - command.FileManagers = this.fileManagers; - command.TableDefinitions = this.core.TableDefinitions; - command.TempFilesLocation = this.TempFilesLocation; - command.Transform = transform; - command.OutputPath = outputPath; - command.Execute(); - } -#endif } } -- cgit v1.2.3-55-g6feb