From dc9f4c329e6f55ce7595970463e0caf148096f4b Mon Sep 17 00:00:00 2001 From: Rob Mensching Date: Thu, 21 Dec 2017 13:42:52 -0800 Subject: Support wixout and extract Resolve and Layout from Binder --- src/WixToolset.Core/Layout.cs | 188 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 188 insertions(+) create mode 100644 src/WixToolset.Core/Layout.cs (limited to 'src/WixToolset.Core/Layout.cs') diff --git a/src/WixToolset.Core/Layout.cs b/src/WixToolset.Core/Layout.cs new file mode 100644 index 00000000..d7322a12 --- /dev/null +++ b/src/WixToolset.Core/Layout.cs @@ -0,0 +1,188 @@ +// 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.Core +{ + using System; + using System.Collections.Generic; + using System.IO; + using System.Linq; + using WixToolset.Core.Bind; + using WixToolset.Data; + using WixToolset.Data.Bind; + using WixToolset.Data.Tuples; + using WixToolset.Extensibility; + using WixToolset.Extensibility.Services; + + /// + /// Layout for the WiX toolset. + /// + public sealed class Layout + { + public Layout(IServiceProvider serviceProvider, IEnumerable fileTransfers, IEnumerable contentFilePaths, string contentsFile, string outputsFile, string builtOutputsFile, bool suppressAclReset) + { + this.ServiceProvider = serviceProvider; + this.FileTransfers = fileTransfers; + this.ContentFilePaths = contentFilePaths; + this.ContentsFile = contentsFile; + this.OutputsFile = outputsFile; + this.BuiltOutputsFile = builtOutputsFile; + this.SuppressAclReset = suppressAclReset; + this.Messaging = this.ServiceProvider.GetService(); + } + + private IServiceProvider ServiceProvider { get; } + + private IEnumerable FileTransfers { get; } + + private IEnumerable ContentFilePaths { get; } + + private string ContentsFile { get; } + + private string OutputsFile { get; } + + private string BuiltOutputsFile { get; } + + private bool SuppressAclReset { get; } + + private IMessaging Messaging { get; } + + public void Execute() + { + var extensionManager = this.ServiceProvider.GetService(); + + var context = this.ServiceProvider.GetService(); + context.Messaging = this.Messaging; + context.Extensions = extensionManager.Create(); + context.FileSystemExtensions = extensionManager.Create(); + context.FileTransfers = this.FileTransfers; + context.ContentFilePaths = this.ContentFilePaths; + context.ContentsFile = this.ContentsFile; + context.OutputPdbPath = this.OutputsFile; + context.BuiltOutputsFile = this.BuiltOutputsFile; + context.SuppressAclReset = this.SuppressAclReset; + + // Pre-layout. + // + foreach (var extension in context.Extensions) + { + extension.PreLayout(context); + } + + try + { + // Final step in binding that transfers (moves/copies) all files generated into the appropriate + // location in the source image. + if (context.FileTransfers?.Any() == true) + { + this.Messaging.Write(VerboseMessages.LayingOutMedia()); + + var command = new TransferFilesCommand(context.Messaging, context.FileSystemExtensions, context.FileTransfers, context.SuppressAclReset); + command.Execute(); + } + } + finally + { + if (!String.IsNullOrEmpty(context.ContentsFile) && context.ContentFilePaths != null) + { + this.CreateContentsFile(context.ContentsFile, context.ContentFilePaths); + } + + if (!String.IsNullOrEmpty(context.OutputsFile) && context.FileTransfers != null) + { + this.CreateOutputsFile(context.OutputsFile, context.FileTransfers, context.OutputPdbPath); + } + + if (!String.IsNullOrEmpty(context.BuiltOutputsFile) && context.FileTransfers != null) + { + this.CreateBuiltOutputsFile(context.BuiltOutputsFile, context.FileTransfers, context.OutputPdbPath); + } + } + + // Post-layout. + foreach (var extension in context.Extensions) + { + extension.PostLayout(); + } + } + + /// + /// Writes the paths to the content files to a text file. + /// + /// Path to write file. + /// Collection of paths to content files that will be written to file. + private void CreateContentsFile(string path, IEnumerable contentFilePaths) + { + var directory = Path.GetDirectoryName(path); + Directory.CreateDirectory(directory); + + using (var contents = new StreamWriter(path, false)) + { + foreach (string contentPath in contentFilePaths) + { + contents.WriteLine(contentPath); + } + } + } + + /// + /// Writes the paths to the output files to a text file. + /// + /// Path to write file. + /// Collection of files that were transferred to the output directory. + /// Optional path to created .wixpdb. + private void CreateOutputsFile(string path, IEnumerable fileTransfers, string pdbPath) + { + var directory = Path.GetDirectoryName(path); + Directory.CreateDirectory(directory); + + using (var outputs = new StreamWriter(path, false)) + { + foreach (FileTransfer fileTransfer in fileTransfers) + { + // Don't list files where the source is the same as the destination since + // that might be the only place the file exists. The outputs file is often + // used to delete stuff and losing the original source would be bad. + if (!fileTransfer.Redundant) + { + outputs.WriteLine(fileTransfer.Destination); + } + } + + if (!String.IsNullOrEmpty(pdbPath)) + { + outputs.WriteLine(Path.GetFullPath(pdbPath)); + } + } + } + + /// + /// Writes the paths to the built output files to a text file. + /// + /// Path to write file. + /// Collection of files that were transferred to the output directory. + /// Optional path to created .wixpdb. + private void CreateBuiltOutputsFile(string path, IEnumerable fileTransfers, string pdbPath) + { + var directory = Path.GetDirectoryName(path); + Directory.CreateDirectory(directory); + + using (var outputs = new StreamWriter(path, false)) + { + foreach (FileTransfer fileTransfer in fileTransfers) + { + // Only write the built file transfers. Also, skip redundant + // files for the same reason spelled out in this.CreateOutputsFile(). + if (fileTransfer.Built && !fileTransfer.Redundant) + { + outputs.WriteLine(fileTransfer.Destination); + } + } + + if (!String.IsNullOrEmpty(pdbPath)) + { + outputs.WriteLine(Path.GetFullPath(pdbPath)); + } + } + } + } +} -- cgit v1.2.3-55-g6feb