From 860676fa5b40a1904478151e9b4934c004e7db63 Mon Sep 17 00:00:00 2001 From: Rob Mensching Date: Mon, 7 Oct 2019 11:18:13 -0700 Subject: Implement Bundle build --- src/WixToolset.Core/Bind/ExtractEmbeddedFiles.cs | 8 +- src/WixToolset.Core/Bind/FileResolver.cs | 8 +- .../Bind/ResolveDelayedFieldsCommand.cs | 2 +- src/WixToolset.Core/BindContext.cs | 4 +- src/WixToolset.Core/CommandLine/BuildCommand.cs | 11 +- src/WixToolset.Core/Compiler.cs | 2 +- src/WixToolset.Core/Compiler_Bundle.cs | 139 +++++++++------------ .../ExtensibilityServices/BackendHelper.cs | 11 +- .../ExtensibilityServices/PathResolver.cs | 91 ++++++++++++++ .../ExtensibilityServices/ResolvedDirectory.cs | 15 +++ .../WindowsInstallerBackendHelper.cs | 32 ++--- src/WixToolset.Core/Link/WixGroupingOrdering.cs | 31 +++-- src/WixToolset.Core/WixToolsetServiceProvider.cs | 4 +- 13 files changed, 237 insertions(+), 121 deletions(-) create mode 100644 src/WixToolset.Core/ExtensibilityServices/PathResolver.cs create mode 100644 src/WixToolset.Core/ExtensibilityServices/ResolvedDirectory.cs (limited to 'src/WixToolset.Core') diff --git a/src/WixToolset.Core/Bind/ExtractEmbeddedFiles.cs b/src/WixToolset.Core/Bind/ExtractEmbeddedFiles.cs index c6e21973..644e5c63 100644 --- a/src/WixToolset.Core/Bind/ExtractEmbeddedFiles.cs +++ b/src/WixToolset.Core/Bind/ExtractEmbeddedFiles.cs @@ -30,10 +30,10 @@ namespace WixToolset.Core.Bind { // If the uri to the file that contains the embedded file does not already have embedded files // being extracted, create the dictionary to track that. - if (!filesWithEmbeddedFiles.TryGetValue(uri, out var extracts)) + if (!this.filesWithEmbeddedFiles.TryGetValue(uri, out var extracts)) { extracts = new SortedList(); - filesWithEmbeddedFiles.Add(uri, extracts); + this.filesWithEmbeddedFiles.Add(uri, extracts); } // If the embedded file is not already tracked in the dictionary of extracts, add it. @@ -52,7 +52,7 @@ namespace WixToolset.Core.Bind public IEnumerable GetExpectedEmbeddedFiles() { - foreach (var uriWithExtracts in filesWithEmbeddedFiles) + foreach (var uriWithExtracts in this.filesWithEmbeddedFiles) { foreach (var extracts in uriWithExtracts.Value) { @@ -68,7 +68,7 @@ namespace WixToolset.Core.Bind public IEnumerable GetExtractFilesForUri(Uri uri) { - if (!filesWithEmbeddedFiles.TryGetValue(uri, out var extracts)) + if (!this.filesWithEmbeddedFiles.TryGetValue(uri, out var extracts)) { extracts = new SortedList(); } diff --git a/src/WixToolset.Core/Bind/FileResolver.cs b/src/WixToolset.Core/Bind/FileResolver.cs index a67d784d..b1676fad 100644 --- a/src/WixToolset.Core/Bind/FileResolver.cs +++ b/src/WixToolset.Core/Bind/FileResolver.cs @@ -70,11 +70,17 @@ namespace WixToolset.Core.Bind /// Optional type of source file being resolved. /// Optional source line of source file being resolved. /// The binding stage used to determine what collection of bind paths will be used + /// Optional collection of paths already checked. /// Should return a valid path for the stream to be imported. - public string ResolveFile(string source, IntermediateTupleDefinition tupleDefinition, SourceLineNumber sourceLineNumbers, BindStage bindStage) + public string ResolveFile(string source, IntermediateTupleDefinition tupleDefinition, SourceLineNumber sourceLineNumbers, BindStage bindStage, IEnumerable alreadyCheckedPaths = null) { var checkedPaths = new List(); + if (alreadyCheckedPaths != null) + { + checkedPaths.AddRange(alreadyCheckedPaths); + } + foreach (var extension in this.ResolverExtensions) { var resolved = extension.ResolveFile(source, tupleDefinition, sourceLineNumbers, bindStage); diff --git a/src/WixToolset.Core/Bind/ResolveDelayedFieldsCommand.cs b/src/WixToolset.Core/Bind/ResolveDelayedFieldsCommand.cs index bec03907..22710aca 100644 --- a/src/WixToolset.Core/Bind/ResolveDelayedFieldsCommand.cs +++ b/src/WixToolset.Core/Bind/ResolveDelayedFieldsCommand.cs @@ -113,7 +113,7 @@ namespace WixToolset.Core.Bind } } - public static string ResolveDelayedVariables(SourceLineNumber sourceLineNumbers, string value, IDictionary resolutionData) + private static string ResolveDelayedVariables(SourceLineNumber sourceLineNumbers, string value, IDictionary resolutionData) { var matches = Common.WixVariableRegex.Matches(value); diff --git a/src/WixToolset.Core/BindContext.cs b/src/WixToolset.Core/BindContext.cs index 413be301..7882b22d 100644 --- a/src/WixToolset.Core/BindContext.cs +++ b/src/WixToolset.Core/BindContext.cs @@ -1,4 +1,4 @@ -// 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. +// 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 { @@ -19,6 +19,8 @@ namespace WixToolset.Core public IEnumerable BindPaths { get; set; } + public string BurnStubPath { get; set; } + public int CabbingThreadCount { get; set; } public string CabCachePath { get; set; } diff --git a/src/WixToolset.Core/CommandLine/BuildCommand.cs b/src/WixToolset.Core/CommandLine/BuildCommand.cs index bfee2478..972258fe 100644 --- a/src/WixToolset.Core/CommandLine/BuildCommand.cs +++ b/src/WixToolset.Core/CommandLine/BuildCommand.cs @@ -122,7 +122,7 @@ namespace WixToolset.Core.CommandLine } else { - this.BindPhase(wixipl, wxls, filterCultures, this.commandLine.CabCachePath, this.commandLine.BindPaths); + this.BindPhase(wixipl, wxls, filterCultures, this.commandLine.CabCachePath, this.commandLine.BindPaths, this.commandLine.BurnStubPath); } } } @@ -257,7 +257,7 @@ namespace WixToolset.Core.CommandLine return linker.Link(context); } - private void BindPhase(Intermediate output, IEnumerable localizations, IEnumerable filterCultures, string cabCachePath, IEnumerable bindPaths) + private void BindPhase(Intermediate output, IEnumerable localizations, IEnumerable filterCultures, string cabCachePath, IEnumerable bindPaths, string burnStubPath) { var intermediateFolder = this.IntermediateFolder; if (String.IsNullOrEmpty(intermediateFolder)) @@ -290,6 +290,7 @@ namespace WixToolset.Core.CommandLine { var context = this.ServiceProvider.GetService(); //context.CabbingThreadCount = this.CabbingThreadCount; + context.BurnStubPath = burnStubPath; context.CabCachePath = cabCachePath; context.Codepage = resolveResult.Codepage; //context.DefaultCompressionLevel = this.DefaultCompressionLevel; @@ -399,6 +400,8 @@ namespace WixToolset.Core.CommandLine public List BindPaths { get; } = new List(); + public string BurnStubPath { get; private set; } + public string CabCachePath { get; private set; } public List Cultures { get; } = new List(); @@ -480,6 +483,10 @@ namespace WixToolset.Core.CommandLine } break; } + case "burnstub": + this.BurnStubPath = parser.GetNextArgumentOrError(arg); + return true; + case "cc": this.CabCachePath = parser.GetNextArgumentOrError(arg); return true; diff --git a/src/WixToolset.Core/Compiler.cs b/src/WixToolset.Core/Compiler.cs index 0dade46d..3ee87872 100644 --- a/src/WixToolset.Core/Compiler.cs +++ b/src/WixToolset.Core/Compiler.cs @@ -818,7 +818,7 @@ namespace WixToolset.Core { this.Core.AddTuple(new IconTuple(sourceLineNumbers, id) { - Data = sourceFile + Data = new IntermediateFieldPathValue { Path = sourceFile } }); } diff --git a/src/WixToolset.Core/Compiler_Bundle.cs b/src/WixToolset.Core/Compiler_Bundle.cs index 0ed49fbc..3be7d0c5 100644 --- a/src/WixToolset.Core/Compiler_Bundle.cs +++ b/src/WixToolset.Core/Compiler_Bundle.cs @@ -9,6 +9,7 @@ namespace WixToolset.Core using System.IO; using System.Xml.Linq; using WixToolset.Data; + using WixToolset.Data.Burn; using WixToolset.Data.Tuples; using WixToolset.Extensibility; @@ -17,15 +18,9 @@ namespace WixToolset.Core /// internal partial class Compiler : ICompiler { - public static readonly Identifier BurnUXContainerId = new Identifier(AccessModifier.Private, "WixUXContainer"); - public static readonly Identifier BurnDefaultAttachedContainerId = new Identifier(AccessModifier.Private, "WixAttachedContainer"); - public static readonly Identifier BundleLayoutOnlyPayloads = new Identifier(AccessModifier.Private, "BundleLayoutOnlyPayloads"); - - // The following constants must stay in sync with src\burn\engine\core.h - private const string BURN_BUNDLE_NAME = "WixBundleName"; - private const string BURN_BUNDLE_ORIGINAL_SOURCE = "WixBundleOriginalSource"; - private const string BURN_BUNDLE_ORIGINAL_SOURCE_FOLDER = "WixBundleOriginalSourceFolder"; - private const string BURN_BUNDLE_LAST_USED_SOURCE = "WixBundleLastUsedSource"; + private static readonly Identifier BurnUXContainerId = new Identifier(AccessModifier.Private, BurnConstants.BurnUXContainerName); + private static readonly Identifier BurnDefaultAttachedContainerId = new Identifier(AccessModifier.Private, BurnConstants.BurnDefaultAttachedContainerName); + private static readonly Identifier BundleLayoutOnlyPayloads = new Identifier(AccessModifier.Private, BurnConstants.BundleLayoutOnlyPayloadsName); /// /// Parses an ApprovedExeForElevation element. @@ -78,11 +73,11 @@ namespace WixToolset.Core this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Key")); } - var attributes = BundleApprovedExeForElevationAttributes.None; + var attributes = WixApprovedExeForElevationAttributes.None; if (win64 == YesNoType.Yes) { - attributes |= BundleApprovedExeForElevationAttributes.Win64; + attributes |= WixApprovedExeForElevationAttributes.Win64; } this.Core.ParseForExtensionElements(node); @@ -92,7 +87,7 @@ namespace WixToolset.Core var tuple = new WixApprovedExeForElevationTuple(sourceLineNumbers, id) { Key = key, - Value = valueName, + ValueName = valueName, Attributes = attributes }; @@ -110,8 +105,7 @@ namespace WixToolset.Core string copyright = null; string aboutUrl = null; var compressed = YesNoDefaultType.Default; - var disableModify = -1; - var disableRemove = YesNoType.NotSet; + WixBundleAttributes attributes = 0; string helpTelephone = null; string helpUrl = null; string manufacturer = null; @@ -152,13 +146,12 @@ namespace WixToolset.Core switch (value) { case "button": - disableModify = 2; + attributes |= WixBundleAttributes.SingleChangeUninstallButton; break; case "yes": - disableModify = 1; + attributes |= WixBundleAttributes.DisableModify; break; case "no": - disableModify = 0; break; default: this.Core.Write(ErrorMessages.IllegalAttributeValue(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, value, "button", "yes", "no")); @@ -166,10 +159,10 @@ namespace WixToolset.Core } break; case "DisableRemove": - disableRemove = this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib); - break; - case "DisableRepair": - this.Core.Write(WarningMessages.DeprecatedAttribute(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName)); + if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) + { + attributes |= WixBundleAttributes.DisableRemove; + } break; case "HelpTelephone": helpTelephone = this.Core.GetAttributeValue(sourceLineNumbers, attrib); @@ -239,13 +232,13 @@ namespace WixToolset.Core if (String.IsNullOrEmpty(name)) { - logVariablePrefixAndExtension = String.Concat("WixBundleLog:Setup.log"); + logVariablePrefixAndExtension = String.Concat("WixBundleLog:Setup:.log"); } else { // Ensure only allowable path characters are in "name" (and change spaces to underscores). fileSystemSafeBundleName = CompilerCore.MakeValidLongFileName(name.Replace(' ', '_'), "_"); - logVariablePrefixAndExtension = String.Concat("WixBundleLog:", fileSystemSafeBundleName, ".log"); + logVariablePrefixAndExtension = String.Concat("WixBundleLog:", fileSystemSafeBundleName, ":.log"); } this.activeName = String.IsNullOrEmpty(name) ? Common.GenerateGuid() : name; @@ -351,6 +344,37 @@ namespace WixToolset.Core if (!this.Core.EncounteredError) { + var tuple = new WixBundleTuple(sourceLineNumbers) + { + UpgradeCode = upgradeCode, + Version = version, + Copyright = copyright, + Name = name, + Manufacturer = manufacturer, + Attributes = attributes, + AboutUrl = aboutUrl, + HelpUrl = helpUrl, + HelpTelephone = helpTelephone, + UpdateUrl = updateUrl, + Compressed = YesNoDefaultType.Yes == compressed ? true : YesNoDefaultType.No == compressed ? (bool?)false : null, + IconSourceFile = iconSourceFile, + SplashScreenSourceFile = splashScreenSourceFile, + Condition = condition, + Tag = tag, + Platform = this.CurrentPlatform, + ParentName = parentName, + }; + + if (!String.IsNullOrEmpty(logVariablePrefixAndExtension)) + { + var split = logVariablePrefixAndExtension.Split(':'); + tuple.LogPathVariable = split[0]; + tuple.LogPrefix = split[1]; + tuple.LogExtension = split[2]; + } + + this.Core.AddTuple(tuple);; + if (null != upgradeCode) { this.Core.AddTuple(new WixRelatedBundleTuple(sourceLineNumbers) @@ -360,64 +384,32 @@ namespace WixToolset.Core }); } - this.Core.AddTuple(new WixBundleContainerTuple(sourceLineNumbers, new Identifier(AccessModifier.Private, Compiler.BurnDefaultAttachedContainerId)) + this.Core.AddTuple(new WixBundleContainerTuple(sourceLineNumbers, Compiler.BurnDefaultAttachedContainerId) { Name = "bundle-attached.cab", Type = ContainerType.Attached }); - var bundleTuple = this.Core.CreateTuple(sourceLineNumbers, TupleDefinitionType.WixBundle); - bundleTuple.Set(0, version); - bundleTuple.Set(1, copyright); - bundleTuple.Set(2, name); - bundleTuple.Set(3, aboutUrl); - if (-1 != disableModify) - { - bundleTuple.Set(4, disableModify); - } - if (YesNoType.NotSet != disableRemove) - { - bundleTuple.Set(5, (YesNoType.Yes == disableRemove) ? 1 : 0); - } - // row.Set(6] - (deprecated) "disable repair" - bundleTuple.Set(7, helpTelephone); - bundleTuple.Set(8, helpUrl); - bundleTuple.Set(9, manufacturer); - bundleTuple.Set(10, updateUrl); - if (YesNoDefaultType.Default != compressed) - { - bundleTuple.Set(11, (YesNoDefaultType.Yes == compressed) ? 1 : 0); - } - - bundleTuple.Set(12, logVariablePrefixAndExtension); - bundleTuple.Set(13, iconSourceFile); - bundleTuple.Set(14, splashScreenSourceFile); - bundleTuple.Set(15, condition); - bundleTuple.Set(16, tag); - bundleTuple.Set(17, this.CurrentPlatform.ToString()); - bundleTuple.Set(18, parentName); - bundleTuple.Set(19, upgradeCode); - // Ensure that the bundle stores the well-known persisted values. - this.Core.AddTuple(new WixBundleVariableTuple(sourceLineNumbers, new Identifier(AccessModifier.Private, Compiler.BURN_BUNDLE_NAME)) + this.Core.AddTuple(new WixBundleVariableTuple(sourceLineNumbers, new Identifier(AccessModifier.Private, BurnConstants.BURN_BUNDLE_NAME)) { Hidden = false, Persisted = true }); - this.Core.AddTuple(new WixBundleVariableTuple(sourceLineNumbers, new Identifier(AccessModifier.Private, Compiler.BURN_BUNDLE_ORIGINAL_SOURCE)) + this.Core.AddTuple(new WixBundleVariableTuple(sourceLineNumbers, new Identifier(AccessModifier.Private, BurnConstants.BURN_BUNDLE_ORIGINAL_SOURCE)) { Hidden = false, Persisted = true }); - this.Core.AddTuple(new WixBundleVariableTuple(sourceLineNumbers, new Identifier(AccessModifier.Private, Compiler.BURN_BUNDLE_ORIGINAL_SOURCE_FOLDER)) + this.Core.AddTuple(new WixBundleVariableTuple(sourceLineNumbers, new Identifier(AccessModifier.Private, BurnConstants.BURN_BUNDLE_ORIGINAL_SOURCE_FOLDER)) { Hidden = false, Persisted = true }); - this.Core.AddTuple(new WixBundleVariableTuple(sourceLineNumbers, new Identifier(AccessModifier.Private, Compiler.BURN_BUNDLE_LAST_USED_SOURCE)) + this.Core.AddTuple(new WixBundleVariableTuple(sourceLineNumbers, new Identifier(AccessModifier.Private, BurnConstants.BURN_BUNDLE_LAST_USED_SOURCE)) { Hidden = false, Persisted = true @@ -473,7 +465,7 @@ namespace WixToolset.Core this.Core.ParseForExtensionElements(node); - return YesNoType.Yes == disableLog ? null : String.Concat(variable, ":", logPrefix, logExtension); + return YesNoType.Yes == disableLog ? null : String.Join(":", variable, logPrefix, logExtension); } /// @@ -1126,9 +1118,9 @@ namespace WixToolset.Core tuple = new WixBundlePayloadTuple(sourceLineNumbers, id) { Name = String.IsNullOrEmpty(name) ? Path.GetFileName(sourceFile) : name, - SourceFile = sourceFile, + SourceFile = new IntermediateFieldPathValue { Path = sourceFile }, DownloadUrl = downloadUrl, - Compressed = compressed, + Compressed = (compressed == YesNoDefaultType.Yes) ? true : (compressed == YesNoDefaultType.No) ? (bool?)false : null, UnresolvedSourceFile = sourceFile, // duplicate of sourceFile but in a string column so it won't get resolved to a full path during binding. DisplayName = displayName, Description = description, @@ -1665,14 +1657,12 @@ namespace WixToolset.Core var vital = YesNoType.Yes; string installCommand = null; string repairCommand = null; - var repairable = YesNoType.NotSet; string uninstallCommand = null; var perMachine = YesNoDefaultType.NotSet; string detectCondition = null; string protocol = null; var installSize = CompilerConstants.IntegerNotSet; string msuKB = null; - var suppressLooseFilePayloadGeneration = YesNoType.NotSet; var enableSignatureVerification = YesNoType.No; var compressed = YesNoDefaultType.Default; var displayInternalUI = YesNoType.NotSet; @@ -1779,7 +1769,6 @@ namespace WixToolset.Core break; case "RepairCommand": repairCommand = this.Core.GetAttributeValue(sourceLineNumbers, attrib, EmptyRule.CanBeEmpty); - repairable = YesNoType.Yes; allowed = (packageType == WixBundlePackageType.Exe); break; case "UninstallCommand": @@ -1808,11 +1797,6 @@ namespace WixToolset.Core case "Compressed": compressed = this.Core.GetAttributeYesNoDefaultValue(sourceLineNumbers, attrib); break; - case "SuppressLooseFilePayloadGeneration": - this.Core.Write(WarningMessages.DeprecatedAttribute(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName)); - suppressLooseFilePayloadGeneration = this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib); - allowed = (packageType == WixBundlePackageType.Msi); - break; case "EnableSignatureVerification": enableSignatureVerification = this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib); break; @@ -2076,7 +2060,7 @@ namespace WixToolset.Core case WixBundlePackageType.Exe: this.Core.AddTuple(new WixBundleExePackageTuple(sourceLineNumbers, id) { - Attributes = (YesNoType.Yes == repairable) ? WixBundleExePackageAttributes.Repairable : 0, + Attributes = WixBundleExePackageAttributes.None, DetectCondition = detectCondition, InstallCommand = installCommand, RepairCommand = repairCommand, @@ -2090,7 +2074,6 @@ namespace WixToolset.Core msiAttributes |= (YesNoType.Yes == displayInternalUI) ? WixBundleMsiPackageAttributes.DisplayInternalUI : 0; msiAttributes |= (YesNoType.Yes == enableFeatureSelection) ? WixBundleMsiPackageAttributes.EnableFeatureSelection : 0; msiAttributes |= (YesNoType.Yes == forcePerMachine) ? WixBundleMsiPackageAttributes.ForcePerMachine : 0; - msiAttributes |= (YesNoType.Yes == suppressLooseFilePayloadGeneration) ? WixBundleMsiPackageAttributes.SuppressLooseFilePayloadGeneration : 0; this.Core.AddTuple(new WixBundleMsiPackageTuple(sourceLineNumbers, id) { @@ -2458,9 +2441,9 @@ namespace WixToolset.Core if (!this.Core.EncounteredError) { - var tuple = new WixBundleMsiPropertyTuple(sourceLineNumbers) + var tuple = new WixBundleMsiPropertyTuple(sourceLineNumbers, new Identifier(AccessModifier.Private, packageId, name)) { - WixBundlePackageRef = packageId, + PackageRef = packageId, Name = name, Value = value }; @@ -2514,10 +2497,10 @@ namespace WixToolset.Core if (!this.Core.EncounteredError) { - this.Core.AddTuple(new WixBundleSlipstreamMspTuple(sourceLineNumbers) + this.Core.AddTuple(new WixBundleSlipstreamMspTuple(sourceLineNumbers, new Identifier(AccessModifier.Private, packageId, id)) { - WixBundlePackageRef = packageId, - MspWixBundlePackageRef = id + TargetPackageRef = packageId, + MspPackageRef = id }); } } diff --git a/src/WixToolset.Core/ExtensibilityServices/BackendHelper.cs b/src/WixToolset.Core/ExtensibilityServices/BackendHelper.cs index 6cc91487..0bdecf7a 100644 --- a/src/WixToolset.Core/ExtensibilityServices/BackendHelper.cs +++ b/src/WixToolset.Core/ExtensibilityServices/BackendHelper.cs @@ -1,4 +1,4 @@ -// 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. +// 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.ExtensibilityServices { @@ -40,6 +40,15 @@ namespace WixToolset.Core.ExtensibilityServices return Uuid.NewUuid(namespaceGuid, value).ToString("B").ToUpperInvariant(); } + public IResolvedDirectory CreateResolvedDirectory(string directoryParent, string name) + { + return new ResolvedDirectory + { + DirectoryParent = directoryParent, + Name = name + }; + } + public ITrackedFile TrackFile(string path, TrackedFileType type, SourceLineNumber sourceLineNumbers = null) { return new TrackedFile(path, type, sourceLineNumbers); diff --git a/src/WixToolset.Core/ExtensibilityServices/PathResolver.cs b/src/WixToolset.Core/ExtensibilityServices/PathResolver.cs new file mode 100644 index 00000000..15cd4fc9 --- /dev/null +++ b/src/WixToolset.Core/ExtensibilityServices/PathResolver.cs @@ -0,0 +1,91 @@ +// 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.ExtensibilityServices +{ + using System; + using System.Collections.Generic; + using System.IO; + using WixToolset.Data; + using WixToolset.Data.WindowsInstaller; + using WixToolset.Extensibility.Data; + using WixToolset.Extensibility.Services; + + internal class PathResolver : IPathResolver + { + public string GetDirectoryPath(Dictionary directories, Dictionary componentIdGenSeeds, string directory, bool canonicalize) + { + if (!directories.TryGetValue(directory, out var resolvedDirectory)) + { + throw new WixException(ErrorMessages.ExpectedDirectory(directory)); + } + + if (null == resolvedDirectory.Path) + { + if (null != componentIdGenSeeds && componentIdGenSeeds.ContainsKey(directory)) + { + resolvedDirectory.Path = componentIdGenSeeds[directory]; + } + else if (canonicalize && WindowsInstallerStandard.IsStandardDirectory(directory)) + { + // when canonicalization is on, standard directories are treated equally + resolvedDirectory.Path = directory; + } + else + { + string name = resolvedDirectory.Name; + + if (canonicalize) + { + name = name?.ToLowerInvariant(); + } + + if (String.IsNullOrEmpty(resolvedDirectory.DirectoryParent)) + { + resolvedDirectory.Path = name; + } + else + { + var parentPath = this.GetDirectoryPath(directories, componentIdGenSeeds, resolvedDirectory.DirectoryParent, canonicalize); + + if (null != resolvedDirectory.Name) + { + resolvedDirectory.Path = Path.Combine(parentPath, name); + } + else + { + resolvedDirectory.Path = parentPath; + } + } + } + } + + return resolvedDirectory.Path; + } + + public string GetFileSourcePath(Dictionary directories, string directoryId, string fileName, bool compressed, bool useLongName) + { + var fileSourcePath = Common.GetName(fileName, true, useLongName); + + if (compressed) + { + // Use just the file name of the file since all uncompressed files must appear + // in the root of the image in a compressed package. + } + else + { + // Get the relative path of where we want the file to be layed out as specified + // in the Directory table. + var directoryPath = this.GetDirectoryPath(directories, null, directoryId, false); + fileSourcePath = Path.Combine(directoryPath, fileSourcePath); + } + + // Strip off "SourceDir" if it's still on there. + if (fileSourcePath.StartsWith("SourceDir\\", StringComparison.Ordinal)) + { + fileSourcePath = fileSourcePath.Substring(10); + } + + return fileSourcePath; + } + } +} diff --git a/src/WixToolset.Core/ExtensibilityServices/ResolvedDirectory.cs b/src/WixToolset.Core/ExtensibilityServices/ResolvedDirectory.cs new file mode 100644 index 00000000..cc8acfdd --- /dev/null +++ b/src/WixToolset.Core/ExtensibilityServices/ResolvedDirectory.cs @@ -0,0 +1,15 @@ +// 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.ExtensibilityServices +{ + using WixToolset.Extensibility.Data; + + internal class ResolvedDirectory : IResolvedDirectory + { + public string DirectoryParent { get; set; } + + public string Name { get; set; } + + public string Path { get; set; } + } +} diff --git a/src/WixToolset.Core/ExtensibilityServices/WindowsInstallerBackendHelper.cs b/src/WixToolset.Core/ExtensibilityServices/WindowsInstallerBackendHelper.cs index 6e0ffce6..26982ad6 100644 --- a/src/WixToolset.Core/ExtensibilityServices/WindowsInstallerBackendHelper.cs +++ b/src/WixToolset.Core/ExtensibilityServices/WindowsInstallerBackendHelper.cs @@ -1,8 +1,7 @@ -// 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. +// 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.ExtensibilityServices { - using System; using System.Linq; using WixToolset.Data; using WixToolset.Data.WindowsInstaller; @@ -10,14 +9,9 @@ namespace WixToolset.Core.ExtensibilityServices internal class WindowsInstallerBackendHelper : IWindowsInstallerBackendHelper { - public WindowsInstallerBackendHelper(IServiceProvider serviceProvider) - { - this.ServiceProvider = serviceProvider; - } + public bool TryAddTupleToOutputMatchingTableDefinitions(IntermediateTuple tuple, Output output, TableDefinition[] tableDefinitions) => this.TryAddTupleToOutputMatchingTableDefinitions(tuple, output, tableDefinitions, false); - private IServiceProvider ServiceProvider { get; } - - public bool TryAddTupleToOutputMatchingTableDefinitions(IntermediateTuple tuple, Output output, TableDefinition[] tableDefinitions) + public bool TryAddTupleToOutputMatchingTableDefinitions(IntermediateTuple tuple, Output output, TableDefinition[] tableDefinitions, bool columnZeroIsId) { var tableDefinition = tableDefinitions.FirstOrDefault(t => t.Name == tuple.Definition.Name); @@ -28,6 +22,14 @@ namespace WixToolset.Core.ExtensibilityServices var table = output.EnsureTable(tableDefinition); var row = table.CreateRow(tuple.SourceLineNumbers); + var rowOffset = 0; + + if (columnZeroIsId) + { + row[0] = tuple.Id.Id; + rowOffset = 1; + } + for (var i = 0; i < tuple.Fields.Length; ++i) { if (i < tableDefinition.Columns.Length) @@ -36,13 +38,13 @@ namespace WixToolset.Core.ExtensibilityServices switch (column.Type) { - case ColumnType.Number: - row[i] = tuple.AsNumber(i); - break; + case ColumnType.Number: + row[i + rowOffset] = column.Nullable ? tuple.AsNullableNumber(i) : tuple.AsNumber(i); + break; - default: - row[i] = tuple.AsString(i); - break; + default: + row[i + rowOffset] = tuple.AsString(i); + break; } } } diff --git a/src/WixToolset.Core/Link/WixGroupingOrdering.cs b/src/WixToolset.Core/Link/WixGroupingOrdering.cs index 9080775e..563cd565 100644 --- a/src/WixToolset.Core/Link/WixGroupingOrdering.cs +++ b/src/WixToolset.Core/Link/WixGroupingOrdering.cs @@ -12,19 +12,19 @@ namespace WixToolset.Core.Link using WixToolset.Data; using WixToolset.Data.Tuples; using WixToolset.Extensibility.Services; + using WixToolset.Data.Burn; /// /// Grouping and Ordering class of the WiX toolset. /// internal class WixGroupingOrdering { - private readonly IMessaging messageHandler; + private readonly IMessaging Messaging; private List groupTypes; private List itemTypes; private ItemCollection items; private readonly List rowsUsed; private bool loaded; - private bool encounteredError; /// /// Creates a WixGroupingOrdering object. @@ -36,11 +36,10 @@ namespace WixToolset.Core.Link public WixGroupingOrdering(IntermediateSection entrySections, IMessaging messageHandler) { this.EntrySection = entrySections; - this.messageHandler = messageHandler; + this.Messaging = messageHandler; this.rowsUsed = new List(); this.loaded = false; - this.encounteredError = false; } private IntermediateSection EntrySection { get; } @@ -71,7 +70,7 @@ namespace WixToolset.Core.Link Debug.Assert(this.groupTypes.Contains(parentTypeString)); this.CreateOrderedList(parentTypeString, parentId, out var orderedItems); - if (this.encounteredError) + if (this.Messaging.EncounteredError) { return; } @@ -95,7 +94,7 @@ namespace WixToolset.Core.Link Debug.Assert(this.groupTypes.Contains(parentTypeString)); this.LoadFlattenOrderGroups(); - if (this.encounteredError) + if (this.Messaging.EncounteredError) { return; } @@ -127,14 +126,14 @@ namespace WixToolset.Core.Link orderedItems = null; this.LoadFlattenOrderGroups(); - if (this.encounteredError) + if (this.Messaging.EncounteredError) { return; } if (!this.items.TryGetValue(parentType, parentId, out var parentItem)) { - this.messageHandler.Write(ErrorMessages.IdentifierNotFound(parentType, parentId)); + this.Messaging.Write(ErrorMessages.IdentifierNotFound(parentType, parentId)); return; } @@ -216,7 +215,7 @@ namespace WixToolset.Core.Link // dependencies. Group references, however, we can check directly. this.FindCircularGroupReferences(); - if (!this.encounteredError) + if (!this.Messaging.EncounteredError) { this.FlattenGroups(); this.FlattenOrdering(); @@ -304,7 +303,7 @@ namespace WixToolset.Core.Link if (this.FindCircularGroupReference(item, item, itemsSeen, out circularReference)) { itemsInKnownLoops.Add(itemsSeen); - this.messageHandler.Write(ErrorMessages.ReferenceLoopDetected(item.Row.SourceLineNumbers, circularReference)); + this.Messaging.Write(ErrorMessages.ReferenceLoopDetected(item.Row.SourceLineNumbers, circularReference)); } } } @@ -376,12 +375,12 @@ namespace WixToolset.Core.Link if (!this.items.TryGetValue(rowItemType, rowItemName, out var item)) { - this.messageHandler.Write(ErrorMessages.IdentifierNotFound(rowItemType, rowItemName)); + this.Messaging.Write(ErrorMessages.IdentifierNotFound(rowItemType, rowItemName)); } if (!this.items.TryGetValue(rowDependsOnType, rowDependsOnName, out var dependsOn)) { - this.messageHandler.Write(ErrorMessages.IdentifierNotFound(rowDependsOnType, rowDependsOnName)); + this.Messaging.Write(ErrorMessages.IdentifierNotFound(rowDependsOnType, rowDependsOnName)); } if (null == item || null == dependsOn) @@ -389,7 +388,7 @@ namespace WixToolset.Core.Link continue; } - item.AddAfter(dependsOn, this.messageHandler); + item.AddAfter(dependsOn, this.Messaging); } } @@ -404,12 +403,12 @@ namespace WixToolset.Core.Link // ordering. foreach (Item item in this.items) { - item.PropagateAfterToChildItems(this.messageHandler); + item.PropagateAfterToChildItems(this.Messaging); } foreach (Item item in this.items) { - item.FlattenAfters(this.messageHandler); + item.FlattenAfters(this.Messaging); } } @@ -668,7 +667,7 @@ namespace WixToolset.Core.Link { if (String.Equals(nameof(ComplexReferenceChildType.Package), this.Type, StringComparison.Ordinal) || (String.Equals(nameof(ComplexReferenceParentType.Container), this.Type, StringComparison.Ordinal) && - !String.Equals(Compiler.BurnUXContainerId.Id, this.Id, StringComparison.Ordinal))) + !String.Equals(BurnConstants.BurnUXContainerName, this.Id, StringComparison.Ordinal))) { return false; } diff --git a/src/WixToolset.Core/WixToolsetServiceProvider.cs b/src/WixToolset.Core/WixToolsetServiceProvider.cs index 267e4524..c7d6ff1d 100644 --- a/src/WixToolset.Core/WixToolsetServiceProvider.cs +++ b/src/WixToolset.Core/WixToolsetServiceProvider.cs @@ -24,7 +24,8 @@ namespace WixToolset.Core this.AddService((provider, singletons) => AddSingleton(singletons, new ParseHelper(provider))); this.AddService((provider, singletons) => AddSingleton(singletons, new PreprocessHelper(provider))); this.AddService((provider, singletons) => AddSingleton(singletons, new BackendHelper(provider))); - this.AddService((provider, singletons) => AddSingleton(singletons, new WindowsInstallerBackendHelper(provider))); + this.AddService((provider, singletons) => AddSingleton(singletons, new PathResolver())); + this.AddService((provider, singletons) => AddSingleton(singletons, new WindowsInstallerBackendHelper())); // Transients. this.AddService((provider, singletons) => new CommandLineArguments(provider)); @@ -47,6 +48,7 @@ namespace WixToolset.Core this.AddService((provider, singletons) => new DecompileResult()); this.AddService((provider, singletons) => new IncludedFile()); this.AddService((provider, singletons) => new PreprocessResult()); + this.AddService((provider, singletons) => new ResolvedDirectory()); this.AddService((provider, singletons) => new ResolveFileResult()); this.AddService((provider, singletons) => new ResolveResult()); this.AddService((provider, singletons) => new ResolvedCabinet()); -- cgit v1.2.3-55-g6feb