From 3704a5547766581b15690b6535d03568afcfc2a0 Mon Sep 17 00:00:00 2001 From: Sean Hall Date: Wed, 13 Apr 2022 10:14:16 -0500 Subject: Change harvested symbols to ref the package payload for remote support. --- .../WixToolset.Data/Symbols/SymbolDefinitions.cs | 4 + .../WixBundleHarvestedDependencyProviderSymbol.cs | 93 ++++++++++++++++++++++ .../Symbols/WixBundleMsiFeatureSymbol.cs | 10 +-- .../Symbols/WixBundlePackageRelatedBundleSymbol.cs | 10 +-- .../Symbols/WixBundlePatchTargetCodeSymbol.cs | 10 +-- .../Symbols/WixBundleRelatedPackageSymbol.cs | 10 +-- .../WixToolset.Core.Burn/Bind/BindBundleCommand.cs | 20 +++-- .../Bind/GenerateManifestDataFromIRCommand.cs | 1 + .../Bind/ProcessDependencyProvidersCommand.cs | 49 ++++++++++-- .../AutomaticallySlipstreamPatchesCommand.cs | 39 +++++---- ...CreateBootstrapperApplicationManifestCommand.cs | 61 ++++++++------ .../Bundles/CreateBurnManifestCommand.cs | 49 +++++++----- .../Bundles/GetPackageFacadesCommand.cs | 15 ++-- .../OrderPackagesAndRollbackBoundariesCommand.cs | 14 ++-- .../WixToolset.Core.Burn/Bundles/PackageFacades.cs | 54 +++++++++++++ .../PerformBundleBackendValidationCommand.cs | 9 +-- .../Bundles/ProcessBundlePackageCommand.cs | 15 ++-- .../Bundles/ProcessMsiPackageCommand.cs | 51 +++++------- .../Bundles/ProcessMspPackageCommand.cs | 6 +- src/wix/WixToolset.Core.Burn/BurnBackendErrors.cs | 6 ++ .../PackagePayloadFixture.cs | 78 ++++++++++++++++++ .../MsiPackagePayloadInPayloadGroup.wxs | 18 +++++ 22 files changed, 461 insertions(+), 161 deletions(-) create mode 100644 src/api/wix/WixToolset.Data/Symbols/WixBundleHarvestedDependencyProviderSymbol.cs create mode 100644 src/wix/WixToolset.Core.Burn/Bundles/PackageFacades.cs create mode 100644 src/wix/test/WixToolsetTest.CoreIntegration/TestData/PackagePayload/MsiPackagePayloadInPayloadGroup.wxs (limited to 'src') diff --git a/src/api/wix/WixToolset.Data/Symbols/SymbolDefinitions.cs b/src/api/wix/WixToolset.Data/Symbols/SymbolDefinitions.cs index 3e0ec512..4a3269c5 100644 --- a/src/api/wix/WixToolset.Data/Symbols/SymbolDefinitions.cs +++ b/src/api/wix/WixToolset.Data/Symbols/SymbolDefinitions.cs @@ -131,6 +131,7 @@ namespace WixToolset.Data WixBundleExePackagePayload, WixBundleExtension, WixBundleHarvestedBundlePackage, + WixBundleHarvestedDependencyProvider, WixBundleHarvestedMsiPackage, WixBundleHarvestedMspPackage, WixBundleMsiFeature, @@ -589,6 +590,9 @@ namespace WixToolset.Data case SymbolDefinitionType.WixBundleHarvestedBundlePackage: return SymbolDefinitions.WixBundleHarvestedBundlePackage; + case SymbolDefinitionType.WixBundleHarvestedDependencyProvider: + return SymbolDefinitions.WixBundleHarvestedDependencyProvider; + case SymbolDefinitionType.WixBundleHarvestedMsiPackage: return SymbolDefinitions.WixBundleHarvestedMsiPackage; diff --git a/src/api/wix/WixToolset.Data/Symbols/WixBundleHarvestedDependencyProviderSymbol.cs b/src/api/wix/WixToolset.Data/Symbols/WixBundleHarvestedDependencyProviderSymbol.cs new file mode 100644 index 00000000..71d77c94 --- /dev/null +++ b/src/api/wix/WixToolset.Data/Symbols/WixBundleHarvestedDependencyProviderSymbol.cs @@ -0,0 +1,93 @@ +// 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.Data +{ + using WixToolset.Data.Symbols; + + public static partial class SymbolDefinitions + { + public static readonly IntermediateSymbolDefinition WixBundleHarvestedDependencyProvider = new IntermediateSymbolDefinition( + SymbolDefinitionType.WixBundleHarvestedDependencyProvider, + new[] + { + new IntermediateFieldDefinition(nameof(WixBundleHarvestedDependencyProviderSymbolFields.PackagePayloadRef), IntermediateFieldType.String), + new IntermediateFieldDefinition(nameof(WixBundleHarvestedDependencyProviderSymbolFields.Attributes), IntermediateFieldType.Number), + new IntermediateFieldDefinition(nameof(WixBundleHarvestedDependencyProviderSymbolFields.ProviderKey), IntermediateFieldType.String), + new IntermediateFieldDefinition(nameof(WixBundleHarvestedDependencyProviderSymbolFields.Version), IntermediateFieldType.String), + new IntermediateFieldDefinition(nameof(WixBundleHarvestedDependencyProviderSymbolFields.DisplayName), IntermediateFieldType.String), + new IntermediateFieldDefinition(nameof(WixBundleHarvestedDependencyProviderSymbolFields.ProviderAttributes), IntermediateFieldType.Number), + }, + typeof(WixDependencyProviderSymbol)); + } +} + +namespace WixToolset.Data.Symbols +{ + using System; + using WixToolset.Data; + + public enum WixBundleHarvestedDependencyProviderSymbolFields + { + PackagePayloadRef, + Attributes, + ProviderKey, + Version, + DisplayName, + ProviderAttributes, + } + + [Flags] + public enum WixBundleHarvestedDependencyProviderAttributes + { + None = 0x0, + } + + public class WixBundleHarvestedDependencyProviderSymbol : IntermediateSymbol + { + public WixBundleHarvestedDependencyProviderSymbol() : base(SymbolDefinitions.WixBundleHarvestedDependencyProvider, null, null) + { + } + + public WixBundleHarvestedDependencyProviderSymbol(SourceLineNumber sourceLineNumber, Identifier id = null) : base(SymbolDefinitions.WixBundleHarvestedDependencyProvider, sourceLineNumber, id) + { + } + + public IntermediateField this[WixBundleHarvestedDependencyProviderSymbolFields index] => this.Fields[(int)index]; + + public string PackagePayloadRef + { + get => this.Fields[(int)WixBundleHarvestedDependencyProviderSymbolFields.PackagePayloadRef].AsString(); + set => this.Set((int)WixBundleHarvestedDependencyProviderSymbolFields.PackagePayloadRef, value); + } + + public WixBundleHarvestedDependencyProviderAttributes Attributes + { + get => (WixBundleHarvestedDependencyProviderAttributes)this.Fields[(int)WixBundleHarvestedDependencyProviderSymbolFields.Attributes].AsNumber(); + set => this.Set((int)WixBundleHarvestedDependencyProviderSymbolFields.Attributes, (int)value); + } + + public string ProviderKey + { + get => this.Fields[(int)WixBundleHarvestedDependencyProviderSymbolFields.ProviderKey].AsString(); + set => this.Set((int)WixBundleHarvestedDependencyProviderSymbolFields.ProviderKey, value); + } + + public string Version + { + get => this.Fields[(int)WixBundleHarvestedDependencyProviderSymbolFields.Version].AsString(); + set => this.Set((int)WixBundleHarvestedDependencyProviderSymbolFields.Version, value); + } + + public string DisplayName + { + get => this.Fields[(int)WixBundleHarvestedDependencyProviderSymbolFields.DisplayName].AsString(); + set => this.Set((int)WixBundleHarvestedDependencyProviderSymbolFields.DisplayName, value); + } + + public int ProviderAttributes + { + get => this.Fields[(int)WixBundleHarvestedDependencyProviderSymbolFields.ProviderAttributes].AsNumber(); + set => this.Set((int)WixBundleHarvestedDependencyProviderSymbolFields.ProviderAttributes, value); + } + } +} diff --git a/src/api/wix/WixToolset.Data/Symbols/WixBundleMsiFeatureSymbol.cs b/src/api/wix/WixToolset.Data/Symbols/WixBundleMsiFeatureSymbol.cs index 829e81c0..86ebdeb8 100644 --- a/src/api/wix/WixToolset.Data/Symbols/WixBundleMsiFeatureSymbol.cs +++ b/src/api/wix/WixToolset.Data/Symbols/WixBundleMsiFeatureSymbol.cs @@ -10,7 +10,7 @@ namespace WixToolset.Data SymbolDefinitionType.WixBundleMsiFeature, new[] { - new IntermediateFieldDefinition(nameof(WixBundleMsiFeatureSymbolFields.PackageRef), IntermediateFieldType.String), + new IntermediateFieldDefinition(nameof(WixBundleMsiFeatureSymbolFields.PackagePayloadRef), IntermediateFieldType.String), new IntermediateFieldDefinition(nameof(WixBundleMsiFeatureSymbolFields.Name), IntermediateFieldType.String), new IntermediateFieldDefinition(nameof(WixBundleMsiFeatureSymbolFields.Size), IntermediateFieldType.LargeNumber), new IntermediateFieldDefinition(nameof(WixBundleMsiFeatureSymbolFields.Parent), IntermediateFieldType.String), @@ -29,7 +29,7 @@ namespace WixToolset.Data.Symbols { public enum WixBundleMsiFeatureSymbolFields { - PackageRef, + PackagePayloadRef, Name, Size, Parent, @@ -53,10 +53,10 @@ namespace WixToolset.Data.Symbols public IntermediateField this[WixBundleMsiFeatureSymbolFields index] => this.Fields[(int)index]; - public string PackageRef + public string PackagePayloadRef { - get => (string)this.Fields[(int)WixBundleMsiFeatureSymbolFields.PackageRef]; - set => this.Set((int)WixBundleMsiFeatureSymbolFields.PackageRef, value); + get => (string)this.Fields[(int)WixBundleMsiFeatureSymbolFields.PackagePayloadRef]; + set => this.Set((int)WixBundleMsiFeatureSymbolFields.PackagePayloadRef, value); } public string Name diff --git a/src/api/wix/WixToolset.Data/Symbols/WixBundlePackageRelatedBundleSymbol.cs b/src/api/wix/WixToolset.Data/Symbols/WixBundlePackageRelatedBundleSymbol.cs index dfb48714..31f4f713 100644 --- a/src/api/wix/WixToolset.Data/Symbols/WixBundlePackageRelatedBundleSymbol.cs +++ b/src/api/wix/WixToolset.Data/Symbols/WixBundlePackageRelatedBundleSymbol.cs @@ -10,7 +10,7 @@ namespace WixToolset.Data SymbolDefinitionType.WixBundlePackageRelatedBundle, new[] { - new IntermediateFieldDefinition(nameof(WixBundlePackageRelatedBundleSymbolFields.PackageRef), IntermediateFieldType.String), + new IntermediateFieldDefinition(nameof(WixBundlePackageRelatedBundleSymbolFields.PackagePayloadRef), IntermediateFieldType.String), new IntermediateFieldDefinition(nameof(WixBundlePackageRelatedBundleSymbolFields.BundleId), IntermediateFieldType.String), new IntermediateFieldDefinition(nameof(WixBundlePackageRelatedBundleSymbolFields.Action), IntermediateFieldType.Number), }, @@ -22,7 +22,7 @@ namespace WixToolset.Data.Symbols { public enum WixBundlePackageRelatedBundleSymbolFields { - PackageRef, + PackagePayloadRef, BundleId, Action, } @@ -39,10 +39,10 @@ namespace WixToolset.Data.Symbols public IntermediateField this[WixBundlePackageRelatedBundleSymbolFields index] => this.Fields[(int)index]; - public string PackageRef + public string PackagePayloadRef { - get => (string)this.Fields[(int)WixBundlePackageRelatedBundleSymbolFields.PackageRef]; - set => this.Set((int)WixBundlePackageRelatedBundleSymbolFields.PackageRef, value); + get => (string)this.Fields[(int)WixBundlePackageRelatedBundleSymbolFields.PackagePayloadRef]; + set => this.Set((int)WixBundlePackageRelatedBundleSymbolFields.PackagePayloadRef, value); } public string BundleId diff --git a/src/api/wix/WixToolset.Data/Symbols/WixBundlePatchTargetCodeSymbol.cs b/src/api/wix/WixToolset.Data/Symbols/WixBundlePatchTargetCodeSymbol.cs index 85f50602..37b5bfa9 100644 --- a/src/api/wix/WixToolset.Data/Symbols/WixBundlePatchTargetCodeSymbol.cs +++ b/src/api/wix/WixToolset.Data/Symbols/WixBundlePatchTargetCodeSymbol.cs @@ -10,7 +10,7 @@ namespace WixToolset.Data SymbolDefinitionType.WixBundlePatchTargetCode, new[] { - new IntermediateFieldDefinition(nameof(WixBundlePatchTargetCodeSymbolFields.PackageRef), IntermediateFieldType.String), + new IntermediateFieldDefinition(nameof(WixBundlePatchTargetCodeSymbolFields.PackagePayloadRef), IntermediateFieldType.String), new IntermediateFieldDefinition(nameof(WixBundlePatchTargetCodeSymbolFields.TargetCode), IntermediateFieldType.String), new IntermediateFieldDefinition(nameof(WixBundlePatchTargetCodeSymbolFields.Attributes), IntermediateFieldType.Number), new IntermediateFieldDefinition(nameof(WixBundlePatchTargetCodeSymbolFields.Type), IntermediateFieldType.Number), @@ -25,7 +25,7 @@ namespace WixToolset.Data.Symbols public enum WixBundlePatchTargetCodeSymbolFields { - PackageRef, + PackagePayloadRef, TargetCode, Attributes, Type, @@ -67,10 +67,10 @@ namespace WixToolset.Data.Symbols public IntermediateField this[WixBundlePatchTargetCodeSymbolFields index] => this.Fields[(int)index]; - public string PackageRef + public string PackagePayloadRef { - get => (string)this.Fields[(int)WixBundlePatchTargetCodeSymbolFields.PackageRef]; - set => this.Set((int)WixBundlePatchTargetCodeSymbolFields.PackageRef, value); + get => (string)this.Fields[(int)WixBundlePatchTargetCodeSymbolFields.PackagePayloadRef]; + set => this.Set((int)WixBundlePatchTargetCodeSymbolFields.PackagePayloadRef, value); } public string TargetCode diff --git a/src/api/wix/WixToolset.Data/Symbols/WixBundleRelatedPackageSymbol.cs b/src/api/wix/WixToolset.Data/Symbols/WixBundleRelatedPackageSymbol.cs index 77789048..d809e09d 100644 --- a/src/api/wix/WixToolset.Data/Symbols/WixBundleRelatedPackageSymbol.cs +++ b/src/api/wix/WixToolset.Data/Symbols/WixBundleRelatedPackageSymbol.cs @@ -10,7 +10,7 @@ namespace WixToolset.Data SymbolDefinitionType.WixBundleRelatedPackage, new[] { - new IntermediateFieldDefinition(nameof(WixBundleRelatedPackageSymbolFields.PackageRef), IntermediateFieldType.String), + new IntermediateFieldDefinition(nameof(WixBundleRelatedPackageSymbolFields.PackagePayloadRef), IntermediateFieldType.String), new IntermediateFieldDefinition(nameof(WixBundleRelatedPackageSymbolFields.RelatedId), IntermediateFieldType.String), new IntermediateFieldDefinition(nameof(WixBundleRelatedPackageSymbolFields.MinVersion), IntermediateFieldType.String), new IntermediateFieldDefinition(nameof(WixBundleRelatedPackageSymbolFields.MaxVersion), IntermediateFieldType.String), @@ -27,7 +27,7 @@ namespace WixToolset.Data.Symbols public enum WixBundleRelatedPackageSymbolFields { - PackageRef, + PackagePayloadRef, RelatedId, MinVersion, MaxVersion, @@ -57,10 +57,10 @@ namespace WixToolset.Data.Symbols public IntermediateField this[WixBundleRelatedPackageSymbolFields index] => this.Fields[(int)index]; - public string PackageRef + public string PackagePayloadRef { - get => (string)this.Fields[(int)WixBundleRelatedPackageSymbolFields.PackageRef]; - set => this.Set((int)WixBundleRelatedPackageSymbolFields.PackageRef, value); + get => (string)this.Fields[(int)WixBundleRelatedPackageSymbolFields.PackagePayloadRef]; + set => this.Set((int)WixBundleRelatedPackageSymbolFields.PackagePayloadRef, value); } public string RelatedId diff --git a/src/wix/WixToolset.Core.Burn/Bind/BindBundleCommand.cs b/src/wix/WixToolset.Core.Burn/Bind/BindBundleCommand.cs index 201d2839..ffc219dc 100644 --- a/src/wix/WixToolset.Core.Burn/Bind/BindBundleCommand.cs +++ b/src/wix/WixToolset.Core.Burn/Bind/BindBundleCommand.cs @@ -159,7 +159,7 @@ namespace WixToolset.Core.Burn processedPayloads = new HashSet(payloadSymbols.Keys); } - IDictionary facades; + PackageFacades facades; { var command = new GetPackageFacadesCommand(this.Messaging, chainPackageSymbols, section); command.Execute(); @@ -325,7 +325,7 @@ namespace WixToolset.Core.Burn // Determine patches to automatically slipstream. { - var command = new AutomaticallySlipstreamPatchesCommand(section, facades.Values); + var command = new AutomaticallySlipstreamPatchesCommand(this.Messaging, section, facades); command.Execute(); } @@ -334,13 +334,11 @@ namespace WixToolset.Core.Burn return; } - IEnumerable orderedFacades; IEnumerable boundaries; { var command = new OrderPackagesAndRollbackBoundariesCommand(this.Messaging, section, facades); command.Execute(); - orderedFacades = command.OrderedPackageFacades; boundaries = command.UsedRollbackBoundaries; } @@ -351,7 +349,7 @@ namespace WixToolset.Core.Burn } { - var command = new ProcessDependencyProvidersCommand(this.Messaging, section, facades); + var command = new ProcessDependencyProvidersCommand(this.ServiceProvider, section, facades); command.Execute(); if (!String.IsNullOrEmpty(command.BundleProviderKey)) @@ -361,7 +359,7 @@ namespace WixToolset.Core.Burn } // Update the bundle per-machine/per-user scope based on the chained packages. - this.ResolveBundleInstallScope(section, bundleSymbol, orderedFacades); + this.ResolveBundleInstallScope(section, bundleSymbol, facades.OrderedValues); var softwareTags = section.Symbols.OfType().ToList(); if (softwareTags.Any()) @@ -370,7 +368,7 @@ namespace WixToolset.Core.Burn command.Execute(); } - this.DetectDuplicateCacheIds(facades); + this.DetectDuplicateCacheIds(facades.Values); if (this.Messaging.EncounteredError) { @@ -413,7 +411,7 @@ namespace WixToolset.Core.Burn // Generate the core-defined BA manifest tables... string baManifestPath; { - var command = new CreateBootstrapperApplicationManifestCommand(section, bundleSymbol, boundaries, orderedFacades, uxPayloadIndex, payloadSymbols, packagesPayloads, this.IntermediateFolder, this.InternalBurnBackendHelper); + var command = new CreateBootstrapperApplicationManifestCommand(section, bundleSymbol, boundaries, facades, uxPayloadIndex, payloadSymbols, packagesPayloads, this.IntermediateFolder, this.InternalBurnBackendHelper); command.Execute(); var baManifestPayload = command.BootstrapperApplicationManifestPayloadRow; @@ -480,7 +478,7 @@ namespace WixToolset.Core.Burn { var executableName = Path.GetFileName(this.OutputPath); - var command = new CreateBurnManifestCommand(executableName, section, bundleSymbol, containers.Values, chainSymbol, orderedFacades, boundaries, uxPayloads, payloadSymbols, packagesPayloads, orderedSearches, this.IntermediateFolder); + var command = new CreateBurnManifestCommand(executableName, section, bundleSymbol, containers.Values, chainSymbol, facades, boundaries, uxPayloads, payloadSymbols, packagesPayloads, orderedSearches, this.IntermediateFolder); command.Execute(); manifestPath = command.OutputPath; @@ -637,11 +635,11 @@ namespace WixToolset.Core.Burn } } - private void DetectDuplicateCacheIds(IDictionary facades) + private void DetectDuplicateCacheIds(IEnumerable facades) { var duplicateCacheIdDetector = new Dictionary(); - foreach (var facade in facades.Values) + foreach (var facade in facades) { if (duplicateCacheIdDetector.TryGetValue(facade.PackageSymbol.CacheId, out var collisionPackage)) { diff --git a/src/wix/WixToolset.Core.Burn/Bind/GenerateManifestDataFromIRCommand.cs b/src/wix/WixToolset.Core.Burn/Bind/GenerateManifestDataFromIRCommand.cs index 610bdd75..740a6e26 100644 --- a/src/wix/WixToolset.Core.Burn/Bind/GenerateManifestDataFromIRCommand.cs +++ b/src/wix/WixToolset.Core.Burn/Bind/GenerateManifestDataFromIRCommand.cs @@ -71,6 +71,7 @@ namespace WixToolset.Core.Burn.Bind case SymbolDefinitionType.WixBundleExePackagePayload: case SymbolDefinitionType.WixBundleExtension: case SymbolDefinitionType.WixBundleHarvestedBundlePackage: + case SymbolDefinitionType.WixBundleHarvestedDependencyProvider: case SymbolDefinitionType.WixBundleHarvestedMsiPackage: case SymbolDefinitionType.WixBundleHarvestedMspPackage: case SymbolDefinitionType.WixBundleMsiFeature: diff --git a/src/wix/WixToolset.Core.Burn/Bind/ProcessDependencyProvidersCommand.cs b/src/wix/WixToolset.Core.Burn/Bind/ProcessDependencyProvidersCommand.cs index e4e04845..992ce3d6 100644 --- a/src/wix/WixToolset.Core.Burn/Bind/ProcessDependencyProvidersCommand.cs +++ b/src/wix/WixToolset.Core.Burn/Bind/ProcessDependencyProvidersCommand.cs @@ -12,11 +12,12 @@ namespace WixToolset.Core.Burn.Bind internal class ProcessDependencyProvidersCommand { - public ProcessDependencyProvidersCommand(IMessaging messaging, IntermediateSection section, IDictionary facades) + public ProcessDependencyProvidersCommand(IServiceProvider serviceProvider, IntermediateSection section, PackageFacades facades) { - this.Messaging = messaging; - this.Section = section; + this.Messaging = serviceProvider.GetService(); + this.BackendHelper = serviceProvider.GetService(); + this.Section = section; this.Facades = facades; } @@ -24,9 +25,11 @@ namespace WixToolset.Core.Burn.Bind private IMessaging Messaging { get; } + private IBackendHelper BackendHelper { get; } + private IntermediateSection Section { get; } - private IDictionary Facades { get; } + private PackageFacades Facades { get; } /// /// Sets the explicitly provided bundle provider key, if provided. And... @@ -36,23 +39,29 @@ namespace WixToolset.Core.Burn.Bind /// public void Execute() { + this.ProcessHarvestedProviders(); + var dependencySymbols = this.Section.Symbols.OfType(); foreach (var dependency in dependencySymbols) { // Sets the provider key for the bundle, if it is not set already. - if (String.IsNullOrEmpty(this.BundleProviderKey)) + if (dependency.Bundle) { - if (dependency.Bundle) + if (String.IsNullOrEmpty(this.BundleProviderKey)) { this.BundleProviderKey = dependency.ProviderKey; } + else + { + this.Messaging.Write(BurnBackendErrors.BundleMultipleProviders(dependency.SourceLineNumbers, dependency.ProviderKey, this.BundleProviderKey)); + } } // Import any authored dependencies. These may merge with imported provides from MSI packages. var packageId = dependency.ParentRef; - if (this.Facades.TryGetValue(packageId, out var facade)) + if (this.Facades.TryGetFacadeByPackageId(packageId, out var facade)) { if (String.IsNullOrEmpty(dependency.ProviderKey)) { @@ -142,5 +151,31 @@ namespace WixToolset.Core.Burn.Bind return dependencySymbolsByPackageId; } + + private void ProcessHarvestedProviders() + { + var harvestedDependencies = this.Section.Symbols.OfType().ToList(); + foreach (var harvestedDependency in harvestedDependencies) + { + if (!this.Facades.TryGetFacadesByPackagePayloadId(harvestedDependency.PackagePayloadRef, out var facades)) + { + this.Messaging.Write(ErrorMessages.IdentifierNotFound("Package.PayloadRef", harvestedDependency.PackagePayloadRef)); + continue; + } + + foreach (var facade in facades) + { + var depId = new Identifier(AccessModifier.Section, this.BackendHelper.GenerateIdentifier("dep", facade.PackageId, harvestedDependency.Id.Id)); + this.Section.AddSymbol(new WixDependencyProviderSymbol(harvestedDependency.SourceLineNumbers, depId) + { + ParentRef = facade.PackageId, + ProviderKey = harvestedDependency.ProviderKey, + Version = harvestedDependency.Version, + DisplayName = harvestedDependency.DisplayName, + Attributes = WixDependencyProviderAttributes.ProvidesAttributesImported | (WixDependencyProviderAttributes)harvestedDependency.ProviderAttributes, + }); + } + } + } } } diff --git a/src/wix/WixToolset.Core.Burn/Bundles/AutomaticallySlipstreamPatchesCommand.cs b/src/wix/WixToolset.Core.Burn/Bundles/AutomaticallySlipstreamPatchesCommand.cs index 064bc62a..0c1b4fcb 100644 --- a/src/wix/WixToolset.Core.Burn/Bundles/AutomaticallySlipstreamPatchesCommand.cs +++ b/src/wix/WixToolset.Core.Burn/Bundles/AutomaticallySlipstreamPatchesCommand.cs @@ -7,18 +7,22 @@ namespace WixToolset.Core.Burn.Bundles using System.Linq; using WixToolset.Data; using WixToolset.Data.Symbols; + using WixToolset.Extensibility.Services; internal class AutomaticallySlipstreamPatchesCommand { - public AutomaticallySlipstreamPatchesCommand(IntermediateSection section, ICollection packageFacades) + public AutomaticallySlipstreamPatchesCommand(IMessaging messaging, IntermediateSection section, PackageFacades packageFacades) { + this.Messaging = messaging; this.Section = section; this.PackageFacades = packageFacades; } + private IMessaging Messaging { get; } + private IntermediateSection Section { get; } - private IEnumerable PackageFacades { get; } + private PackageFacades PackageFacades { get; } public void Execute() { @@ -26,7 +30,7 @@ namespace WixToolset.Core.Burn.Bundles var targetsProductCode = new Dictionary>(); var targetsUpgradeCode = new Dictionary>(); - foreach (var facade in this.PackageFacades) + foreach (var facade in this.PackageFacades.Values) { // Keep track of all MSI packages. if (facade.SpecificPackageSymbol is WixBundleMsiPackageSymbol msiPackage) @@ -37,7 +41,7 @@ namespace WixToolset.Core.Burn.Bundles { var patchTargetCodeSymbols = this.Section.Symbols .OfType() - .Where(r => r.PackageRef == facade.PackageId); + .Where(r => r.PackagePayloadRef == facade.PackageSymbol.PayloadRef); // Index target ProductCodes and UpgradeCodes for slipstreamed MSPs. foreach (var symbol in patchTargetCodeSymbols) @@ -89,22 +93,27 @@ namespace WixToolset.Core.Burn.Bundles } } - private bool TryAddSlipstreamSymbol(HashSet slipstreamMspIds, WixBundleMsiPackageSymbol msiPackage, WixBundlePatchTargetCodeSymbol patchTargetCode) + private void TryAddSlipstreamSymbol(HashSet slipstreamMspIds, WixBundleMsiPackageSymbol msiPackage, WixBundlePatchTargetCodeSymbol patchTargetCode) { - var id = new Identifier(AccessModifier.Section, msiPackage.Id.Id, patchTargetCode.PackageRef); + if (!this.PackageFacades.TryGetFacadesByPackagePayloadId(patchTargetCode.PackagePayloadRef, out var packageFacades)) + { + this.Messaging.Write(ErrorMessages.IdentifierNotFound("Package.PayloadRef", patchTargetCode.PackagePayloadRef)); + return; + } - if (slipstreamMspIds.Add(id.Id)) + foreach (var packageFacade in packageFacades) { - this.Section.AddSymbol(new WixBundleSlipstreamMspSymbol(patchTargetCode.SourceLineNumbers) - { - TargetPackageRef = msiPackage.Id.Id, - MspPackageRef = patchTargetCode.PackageRef, - }); + var id = new Identifier(AccessModifier.Section, msiPackage.Id.Id, packageFacade.PackageId); - return true; + if (slipstreamMspIds.Add(id.Id)) + { + this.Section.AddSymbol(new WixBundleSlipstreamMspSymbol(patchTargetCode.SourceLineNumbers) + { + TargetPackageRef = msiPackage.Id.Id, + MspPackageRef = packageFacade.PackageId, + }); + } } - - return false; } } } diff --git a/src/wix/WixToolset.Core.Burn/Bundles/CreateBootstrapperApplicationManifestCommand.cs b/src/wix/WixToolset.Core.Burn/Bundles/CreateBootstrapperApplicationManifestCommand.cs index b993da87..39347d19 100644 --- a/src/wix/WixToolset.Core.Burn/Bundles/CreateBootstrapperApplicationManifestCommand.cs +++ b/src/wix/WixToolset.Core.Burn/Bundles/CreateBootstrapperApplicationManifestCommand.cs @@ -15,12 +15,12 @@ namespace WixToolset.Core.Burn.Bundles internal class CreateBootstrapperApplicationManifestCommand { - public CreateBootstrapperApplicationManifestCommand(IntermediateSection section, WixBundleSymbol bundleSymbol, IEnumerable boundaries, IEnumerable chainPackages, int lastUXPayloadIndex, Dictionary payloadSymbols, Dictionary> packagesPayloads, string intermediateFolder, IInternalBurnBackendHelper internalBurnBackendHelper) + public CreateBootstrapperApplicationManifestCommand(IntermediateSection section, WixBundleSymbol bundleSymbol, IEnumerable boundaries, PackageFacades packageFacades, int lastUXPayloadIndex, Dictionary payloadSymbols, Dictionary> packagesPayloads, string intermediateFolder, IInternalBurnBackendHelper internalBurnBackendHelper) { this.Section = section; this.BundleSymbol = bundleSymbol; this.RollbackBoundaries = boundaries; - this.ChainPackages = chainPackages; + this.PackagesFacades = packageFacades; this.LastUXPayloadIndex = lastUXPayloadIndex; this.Payloads = payloadSymbols; this.PackagesPayloads = packagesPayloads; @@ -34,7 +34,7 @@ namespace WixToolset.Core.Burn.Bundles private IEnumerable RollbackBoundaries { get; } - private IEnumerable ChainPackages { get; } + private PackageFacades PackagesFacades { get; } private IInternalBurnBackendHelper InternalBurnBackendHelper { get; } @@ -141,7 +141,7 @@ namespace WixToolset.Core.Burn.Bundles private void WritePackageInfo(XmlTextWriter writer) { - foreach (var package in this.ChainPackages) + foreach (var package in this.PackagesFacades.OrderedValues) { if (!this.PackagesPayloads.TryGetValue(package.PackageId, out var payloads)) { @@ -229,33 +229,46 @@ namespace WixToolset.Core.Burn.Bundles foreach (var featureSymbol in featureSymbols) { - writer.WriteStartElement("WixPackageFeatureInfo"); - - writer.WriteAttributeString("Package", featureSymbol.PackageRef); - writer.WriteAttributeString("Feature", featureSymbol.Name); - writer.WriteAttributeString("Size", featureSymbol.Size.ToString(CultureInfo.InvariantCulture)); - - if (!String.IsNullOrEmpty(featureSymbol.Parent)) + if (!this.PackagesFacades.TryGetFacadesByPackagePayloadId(featureSymbol.PackagePayloadRef, out var facades)) { - writer.WriteAttributeString("Parent", featureSymbol.Parent); + continue; } - if (!String.IsNullOrEmpty(featureSymbol.Title)) + foreach (var facade in facades) { - writer.WriteAttributeString("Title", featureSymbol.Title); - } + if (!(facade.SpecificPackageSymbol is WixBundleMsiPackageSymbol msiPackage) || !msiPackage.EnableFeatureSelection) + { + continue; + } - if (!String.IsNullOrEmpty(featureSymbol.Description)) - { - writer.WriteAttributeString("Description", featureSymbol.Description); - } + writer.WriteStartElement("WixPackageFeatureInfo"); - writer.WriteAttributeString("Display", featureSymbol.Display.ToString(CultureInfo.InvariantCulture)); - writer.WriteAttributeString("Level", featureSymbol.Level.ToString(CultureInfo.InvariantCulture)); - writer.WriteAttributeString("Directory", featureSymbol.Directory); - writer.WriteAttributeString("Attributes", featureSymbol.Attributes.ToString(CultureInfo.InvariantCulture)); + writer.WriteAttributeString("Package", facade.PackageId); + writer.WriteAttributeString("Feature", featureSymbol.Name); + writer.WriteAttributeString("Size", featureSymbol.Size.ToString(CultureInfo.InvariantCulture)); - writer.WriteEndElement(); + if (!String.IsNullOrEmpty(featureSymbol.Parent)) + { + writer.WriteAttributeString("Parent", featureSymbol.Parent); + } + + if (!String.IsNullOrEmpty(featureSymbol.Title)) + { + writer.WriteAttributeString("Title", featureSymbol.Title); + } + + if (!String.IsNullOrEmpty(featureSymbol.Description)) + { + writer.WriteAttributeString("Description", featureSymbol.Description); + } + + writer.WriteAttributeString("Display", featureSymbol.Display.ToString(CultureInfo.InvariantCulture)); + writer.WriteAttributeString("Level", featureSymbol.Level.ToString(CultureInfo.InvariantCulture)); + writer.WriteAttributeString("Directory", featureSymbol.Directory); + writer.WriteAttributeString("Attributes", featureSymbol.Attributes.ToString(CultureInfo.InvariantCulture)); + + writer.WriteEndElement(); + } } } diff --git a/src/wix/WixToolset.Core.Burn/Bundles/CreateBurnManifestCommand.cs b/src/wix/WixToolset.Core.Burn/Bundles/CreateBurnManifestCommand.cs index be5fdf0d..508395f5 100644 --- a/src/wix/WixToolset.Core.Burn/Bundles/CreateBurnManifestCommand.cs +++ b/src/wix/WixToolset.Core.Burn/Bundles/CreateBurnManifestCommand.cs @@ -18,14 +18,14 @@ namespace WixToolset.Core.Burn.Bundles internal class CreateBurnManifestCommand { - public CreateBurnManifestCommand(string executableName, IntermediateSection section, WixBundleSymbol bundleSymbol, IEnumerable containers, WixChainSymbol chainSymbol, IEnumerable orderedPackages, IEnumerable boundaries, IEnumerable uxPayloads, Dictionary allPayloadsById, Dictionary> packagesPayloads, IEnumerable orderedSearches, string intermediateFolder) + public CreateBurnManifestCommand(string executableName, IntermediateSection section, WixBundleSymbol bundleSymbol, IEnumerable containers, WixChainSymbol chainSymbol, PackageFacades packageFacades, IEnumerable boundaries, IEnumerable uxPayloads, Dictionary allPayloadsById, Dictionary> packagesPayloads, IEnumerable orderedSearches, string intermediateFolder) { this.ExecutableName = executableName; this.Section = section; this.BundleSymbol = bundleSymbol; this.Chain = chainSymbol; this.Containers = containers; - this.OrderedPackages = orderedPackages; + this.PackageFacades = packageFacades; this.RollbackBoundaries = boundaries; this.UXContainerPayloads = uxPayloads; this.Payloads = allPayloadsById; @@ -46,7 +46,7 @@ namespace WixToolset.Core.Burn.Bundles private IEnumerable RollbackBoundaries { get; } - private IEnumerable OrderedPackages { get; } + private PackageFacades PackageFacades { get; } private IEnumerable OrderedSearches { get; } @@ -316,11 +316,11 @@ namespace WixToolset.Core.Burn.Bundles } // Index a few tables by package. - var targetCodesByPatch = this.Section.Symbols.OfType().ToLookup(r => r.PackageRef); - var msiFeaturesByPackage = this.Section.Symbols.OfType().ToLookup(r => r.PackageRef); + var targetCodesByPackagePayload = this.Section.Symbols.OfType().ToLookup(r => r.PackagePayloadRef); + var msiFeaturesByPackagePayload = this.Section.Symbols.OfType().ToLookup(r => r.PackagePayloadRef); var msiPropertiesByPackage = this.Section.Symbols.OfType().ToLookup(r => r.PackageRef); - var relatedBundlesByPackage = this.Section.Symbols.OfType().ToLookup(r => r.PackageRef); - var relatedPackagesByPackage = this.Section.Symbols.OfType().ToLookup(r => r.PackageRef); + var relatedBundlesByPackagePayload = this.Section.Symbols.OfType().ToLookup(r => r.PackagePayloadRef); + var relatedPackagesByPackagePayload = this.Section.Symbols.OfType().ToLookup(r => r.PackagePayloadRef); var slipstreamMspsByPackage = this.Section.Symbols.OfType().ToLookup(r => r.TargetPackageRef); var exitCodesByPackage = this.Section.Symbols.OfType().ToLookup(r => r.ChainPackageId); var commandLinesByPackage = this.Section.Symbols.OfType().ToLookup(r => r.WixBundlePackageRef); @@ -331,8 +331,10 @@ namespace WixToolset.Core.Burn.Bundles // Build up the list of target codes from all the MSPs in the chain. var targetCodes = new List(); - foreach (var package in this.OrderedPackages) + foreach (var package in this.PackageFacades.OrderedValues) { + var packagePayloadId = package.PackageSymbol.PayloadRef; + writer.WriteStartElement(String.Format(CultureInfo.InvariantCulture, "{0}Package", package.PackageSymbol.Type)); writer.WriteAttributeString("Id", package.PackageId); @@ -425,6 +427,19 @@ namespace WixToolset.Core.Burn.Bundles { writer.WriteAttributeString("UpgradeCode", msiPackage.UpgradeCode); } + + // If feature selection is enabled, represent the Feature table in the manifest. + if (msiPackage.EnableFeatureSelection) + { + var packageMsiFeatures = msiFeaturesByPackagePayload[packagePayloadId]; + + foreach (var feature in packageMsiFeatures) + { + writer.WriteStartElement("MsiFeature"); + writer.WriteAttributeString("Id", feature.Name); + writer.WriteEndElement(); + } + } } else if (package.SpecificPackageSymbol is WixBundleMspPackageSymbol mspPackage) // MSP { @@ -435,7 +450,7 @@ namespace WixToolset.Core.Burn.Bundles // product codes, add the patch list to the overall list. if (null != targetCodes) { - foreach (var patchTargetCode in targetCodesByPatch[mspPackage.Id.Id]) + foreach (var patchTargetCode in targetCodesByPackagePayload[packagePayloadId]) { if (patchTargetCode.Type == WixBundlePatchTargetCodeType.Unspecified) { @@ -453,15 +468,6 @@ namespace WixToolset.Core.Burn.Bundles writer.WriteAttributeString("KB", msuPackage.MsuKB); } - var packageMsiFeatures = msiFeaturesByPackage[package.PackageId]; - - foreach (var feature in packageMsiFeatures) - { - writer.WriteStartElement("MsiFeature"); - writer.WriteAttributeString("Id", feature.Name); - writer.WriteEndElement(); - } - var packageMsiProperties = msiPropertiesByPackage[package.PackageId]; foreach (var msiProperty in packageMsiProperties) @@ -536,14 +542,14 @@ namespace WixToolset.Core.Burn.Bundles if (dependency.Imported) { - // The package dependency was explicitly authored into the manifest. + // The package dependency was harvested from the package. writer.WriteAttributeString("Imported", "yes"); } writer.WriteEndElement(); } - var packageRelatedBundles = relatedBundlesByPackage[package.PackageId]; + var packageRelatedBundles = relatedBundlesByPackagePayload[packagePayloadId]; foreach (var relatedBundle in packageRelatedBundles) { @@ -553,7 +559,7 @@ namespace WixToolset.Core.Burn.Bundles writer.WriteEndElement(); } - var packageRelatedPackages = relatedPackagesByPackage[package.PackageId]; + var packageRelatedPackages = relatedPackagesByPackagePayload[packagePayloadId]; foreach (var related in packageRelatedPackages) { @@ -587,7 +593,6 @@ namespace WixToolset.Core.Burn.Bundles } // Write any contained Payloads with the PackagePayload being first - var packagePayloadId = package.PackageSymbol.PayloadRef; writer.WriteStartElement("PayloadRef"); writer.WriteAttributeString("Id", packagePayloadId); writer.WriteEndElement(); diff --git a/src/wix/WixToolset.Core.Burn/Bundles/GetPackageFacadesCommand.cs b/src/wix/WixToolset.Core.Burn/Bundles/GetPackageFacadesCommand.cs index 19403631..f8c70c1a 100644 --- a/src/wix/WixToolset.Core.Burn/Bundles/GetPackageFacadesCommand.cs +++ b/src/wix/WixToolset.Core.Burn/Bundles/GetPackageFacadesCommand.cs @@ -23,7 +23,7 @@ namespace WixToolset.Core.Burn.Bundles private IntermediateSection Section { get; } - public IDictionary PackageFacades { get; private set; } + public PackageFacades PackageFacades { get; private set; } public void Execute() { @@ -39,7 +39,7 @@ namespace WixToolset.Core.Burn.Bundles var mspPackagePayloads = this.Section.Symbols.OfType().ToDictionary(t => t.Id.Id); var msuPackagePayloads = this.Section.Symbols.OfType().ToDictionary(t => t.Id.Id); - var facades = new Dictionary(); + var facades = new PackageFacades(); foreach (var package in this.ChainPackageSymbols) { @@ -135,6 +135,7 @@ namespace WixToolset.Core.Burn.Bundles if (packagePayload == null) { this.Messaging.Write(ErrorMessages.MissingPackagePayload(package.SourceLineNumbers, id, package.Type.ToString())); + continue; } else { @@ -146,7 +147,7 @@ namespace WixToolset.Core.Burn.Bundles case WixBundlePackageType.Bundle: if (bundlePackages.TryGetValue(id, out var bundlePackage)) { - facades.Add(id, new PackageFacade(package, bundlePackage)); + facades.Add(new PackageFacade(package, bundlePackage)); } else { @@ -157,7 +158,7 @@ namespace WixToolset.Core.Burn.Bundles case WixBundlePackageType.Exe: if (exePackages.TryGetValue(id, out var exePackage)) { - facades.Add(id, new PackageFacade(package, exePackage)); + facades.Add(new PackageFacade(package, exePackage)); } else { @@ -168,7 +169,7 @@ namespace WixToolset.Core.Burn.Bundles case WixBundlePackageType.Msi: if (msiPackages.TryGetValue(id, out var msiPackage)) { - facades.Add(id, new PackageFacade(package, msiPackage)); + facades.Add(new PackageFacade(package, msiPackage)); } else { @@ -179,7 +180,7 @@ namespace WixToolset.Core.Burn.Bundles case WixBundlePackageType.Msp: if (mspPackages.TryGetValue(id, out var mspPackage)) { - facades.Add(id, new PackageFacade(package, mspPackage)); + facades.Add(new PackageFacade(package, mspPackage)); } else { @@ -190,7 +191,7 @@ namespace WixToolset.Core.Burn.Bundles case WixBundlePackageType.Msu: if (msuPackages.TryGetValue(id, out var msuPackage)) { - facades.Add(id, new PackageFacade(package, msuPackage)); + facades.Add(new PackageFacade(package, msuPackage)); } else { diff --git a/src/wix/WixToolset.Core.Burn/Bundles/OrderPackagesAndRollbackBoundariesCommand.cs b/src/wix/WixToolset.Core.Burn/Bundles/OrderPackagesAndRollbackBoundariesCommand.cs index 99e1e196..13aa60e3 100644 --- a/src/wix/WixToolset.Core.Burn/Bundles/OrderPackagesAndRollbackBoundariesCommand.cs +++ b/src/wix/WixToolset.Core.Burn/Bundles/OrderPackagesAndRollbackBoundariesCommand.cs @@ -12,7 +12,7 @@ namespace WixToolset.Core.Burn.Bundles internal class OrderPackagesAndRollbackBoundariesCommand { - public OrderPackagesAndRollbackBoundariesCommand(IMessaging messaging, IntermediateSection section, IDictionary packageFacades) + public OrderPackagesAndRollbackBoundariesCommand(IMessaging messaging, IntermediateSection section, PackageFacades packageFacades) { this.Messaging = messaging; this.Section = section; @@ -23,9 +23,7 @@ namespace WixToolset.Core.Burn.Bundles private IntermediateSection Section { get; } - private IDictionary PackageFacades { get; } - - public IEnumerable OrderedPackageFacades { get; private set; } + private PackageFacades PackageFacades { get; } public IEnumerable UsedRollbackBoundaries { get; private set; } @@ -34,7 +32,6 @@ namespace WixToolset.Core.Burn.Bundles var groupSymbols = this.Section.Symbols.OfType().ToList(); var boundariesById = this.Section.Symbols.OfType().ToDictionary(b => b.Id.Id); - var orderedFacades = new List(); var usedBoundaries = new List(); // Process the chain of packages to add them in the correct order @@ -55,7 +52,7 @@ namespace WixToolset.Core.Burn.Bundles { if (ComplexReferenceChildType.Package == groupSymbol.ChildType && ComplexReferenceParentType.PackageGroup == groupSymbol.ParentType && BurnConstants.BundleChainPackageGroupId == groupSymbol.ParentId) { - if (this.PackageFacades.TryGetValue(groupSymbol.ChildId, out var facade)) + if (this.PackageFacades.TryGetFacadeByPackageId(groupSymbol.ChildId, out var facade)) { var insideMsiTransaction = lastRollbackBoundary.Transaction; @@ -102,7 +99,7 @@ namespace WixToolset.Core.Burn.Bundles } } - orderedFacades.Add(facade); + this.PackageFacades.AddOrdered(facade); } else // must be a rollback boundary. { @@ -158,7 +155,7 @@ namespace WixToolset.Core.Burn.Bundles string previousRollbackBoundaryId = null; PackageFacade previousFacade = null; - foreach (var package in orderedFacades) + foreach (var package in this.PackageFacades.OrderedValues) { if (null != package.PackageSymbol.RollbackBoundaryRef) { @@ -178,7 +175,6 @@ namespace WixToolset.Core.Burn.Bundles previousFacade.PackageSymbol.RollbackBoundaryBackwardRef = previousRollbackBoundaryId; } - this.OrderedPackageFacades = orderedFacades; this.UsedRollbackBoundaries = usedBoundaries; } } diff --git a/src/wix/WixToolset.Core.Burn/Bundles/PackageFacades.cs b/src/wix/WixToolset.Core.Burn/Bundles/PackageFacades.cs new file mode 100644 index 00000000..a5737505 --- /dev/null +++ b/src/wix/WixToolset.Core.Burn/Bundles/PackageFacades.cs @@ -0,0 +1,54 @@ +// 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.Burn.Bundles +{ + using System.Collections.Generic; + using System.Linq; + using WixToolset.Data; + + internal class PackageFacades + { + private Dictionary FacadesByPackageId { get; } = new Dictionary(); + + private Dictionary> FacadesByPackagePayloadId { get; } = new Dictionary>(); + + private List OrderedFacades { get; } = new List(); + + public void Add(PackageFacade item) + { + this.FacadesByPackageId.Add(item.PackageId, item); + + if (!this.FacadesByPackagePayloadId.TryGetValue(item.PackageSymbol.PayloadRef, out var facades)) + { + facades = new List(); + this.FacadesByPackagePayloadId.Add(item.PackageSymbol.PayloadRef, facades); + } + + facades.Add(item); + } + + public void AddOrdered(PackageFacade item) + { + if (!this.FacadesByPackageId.ContainsKey(item.PackageId)) + { + throw new WixException("Ordered PackageFacade must already exist"); + } + + this.OrderedFacades.Add(item); + } + + public IReadOnlyCollection OrderedValues => this.OrderedFacades.AsReadOnly(); + + public IEnumerable Values => this.FacadesByPackageId.Values; + + public bool TryGetFacadeByPackageId(string packageId, out PackageFacade facade) + { + return this.FacadesByPackageId.TryGetValue(packageId, out facade); + } + + public bool TryGetFacadesByPackagePayloadId(string packagePayloadId, out List facades) + { + return this.FacadesByPackagePayloadId.TryGetValue(packagePayloadId, out facades); + } + } +} diff --git a/src/wix/WixToolset.Core.Burn/Bundles/PerformBundleBackendValidationCommand.cs b/src/wix/WixToolset.Core.Burn/Bundles/PerformBundleBackendValidationCommand.cs index 8a2f1c64..3ffb8df4 100644 --- a/src/wix/WixToolset.Core.Burn/Bundles/PerformBundleBackendValidationCommand.cs +++ b/src/wix/WixToolset.Core.Burn/Bundles/PerformBundleBackendValidationCommand.cs @@ -3,7 +3,6 @@ namespace WixToolset.Core.Burn.Bundles { using System; - using System.Collections.Generic; using WixToolset.Data; using WixToolset.Data.Symbols; using WixToolset.Extensibility.Data; @@ -11,12 +10,12 @@ namespace WixToolset.Core.Burn.Bundles internal class PerformBundleBackendValidationCommand { - public PerformBundleBackendValidationCommand(IMessaging messaging, IBurnBackendHelper burnBackendHelper, IntermediateSection section, IDictionary packageFacadesById) + public PerformBundleBackendValidationCommand(IMessaging messaging, IBurnBackendHelper burnBackendHelper, IntermediateSection section, PackageFacades packageFacades) { this.Messaging = messaging; this.BackendHelper = burnBackendHelper; this.Section = section; - this.PackageFacadesById = packageFacadesById; + this.PackageFacades = packageFacades; } private IMessaging Messaging { get; } @@ -25,7 +24,7 @@ namespace WixToolset.Core.Burn.Bundles private IntermediateSection Section { get; } - private IDictionary PackageFacadesById { get; } + private PackageFacades PackageFacades { get; } public void Execute() { @@ -53,7 +52,7 @@ namespace WixToolset.Core.Burn.Bundles } } - foreach (var packageFacade in this.PackageFacadesById.Values) + foreach (var packageFacade in this.PackageFacades.Values) { if (packageFacade.SpecificPackageSymbol is WixBundleBundlePackageSymbol wixBundleBundlePackageSymbol) { diff --git a/src/wix/WixToolset.Core.Burn/Bundles/ProcessBundlePackageCommand.cs b/src/wix/WixToolset.Core.Burn/Bundles/ProcessBundlePackageCommand.cs index 2abdec06..47231ccb 100644 --- a/src/wix/WixToolset.Core.Burn/Bundles/ProcessBundlePackageCommand.cs +++ b/src/wix/WixToolset.Core.Burn/Bundles/ProcessBundlePackageCommand.cs @@ -57,8 +57,8 @@ namespace WixToolset.Core.Burn.Bundles public void Execute() { var harvestedBundlePackage = this.Section.Symbols.OfType() - .Where(h => h.Id == this.ChainPackage.Id) - .SingleOrDefault(); + .Where(h => h.Id == this.PackagePayload.Id) + .SingleOrDefault(); if (harvestedBundlePackage == null) { @@ -200,13 +200,12 @@ namespace WixToolset.Core.Burn.Bundles version = registrationElement.GetAttribute("Version"); var providerKey = registrationElement.GetAttribute("ProviderKey"); - var depId = new Identifier(AccessModifier.Section, this.BackendHelper.GenerateIdentifier("dep", this.PackageId, providerKey)); - this.Section.AddSymbol(new WixDependencyProviderSymbol(sourceLineNumbers, depId) + var depId = new Identifier(AccessModifier.Section, this.BackendHelper.GenerateIdentifier("dep", this.PackagePayload.Id.Id, providerKey)); + this.Section.AddSymbol(new WixBundleHarvestedDependencyProviderSymbol(sourceLineNumbers, depId) { - ParentRef = this.PackageId, + PackagePayloadRef = this.PackagePayload.Id.Id, ProviderKey = providerKey, Version = version, - Attributes = WixDependencyProviderAttributes.ProvidesAttributesImported, }); displayName = arpElement.GetAttribute("DisplayName"); @@ -224,7 +223,7 @@ namespace WixToolset.Core.Burn.Bundles } } - return this.Section.AddSymbol(new WixBundleHarvestedBundlePackageSymbol(this.PackagePayload.SourceLineNumbers, this.ChainPackage.Id) + return this.Section.AddSymbol(new WixBundleHarvestedBundlePackageSymbol(this.PackagePayload.SourceLineNumbers, this.PackagePayload.Id) { Win64 = win64, BundleId = bundleId, @@ -274,7 +273,7 @@ namespace WixToolset.Core.Burn.Bundles this.Section.AddSymbol(new WixBundlePackageRelatedBundleSymbol(sourceLineNumbers) { - PackageRef = this.PackageId, + PackagePayloadRef = this.PackagePayload.Id.Id, BundleId = id, Action = action, }); diff --git a/src/wix/WixToolset.Core.Burn/Bundles/ProcessMsiPackageCommand.cs b/src/wix/WixToolset.Core.Burn/Bundles/ProcessMsiPackageCommand.cs index 5acec2a4..0bec201d 100644 --- a/src/wix/WixToolset.Core.Burn/Bundles/ProcessMsiPackageCommand.cs +++ b/src/wix/WixToolset.Core.Burn/Bundles/ProcessMsiPackageCommand.cs @@ -65,7 +65,7 @@ namespace WixToolset.Core.Burn.Bundles public void Execute() { var harvestedMsiPackage = this.Section.Symbols.OfType() - .Where(h => h.Id == this.ChainPackage.Id) + .Where(h => h.Id == this.PackagePayload.Id) .SingleOrDefault(); if (harvestedMsiPackage == null) @@ -78,6 +78,17 @@ namespace WixToolset.Core.Burn.Bundles } } + foreach (var childPayload in this.Section.Symbols.OfType().Where(p => p.ParentPackagePayloadRef == this.PackagePayload.Id.Id).ToList()) + { + this.Section.AddSymbol(new WixGroupSymbol(childPayload.SourceLineNumbers) + { + ParentType = ComplexReferenceParentType.Package, + ParentId = this.PackageId, + ChildType = ComplexReferenceChildType.Payload, + ChildId = childPayload.Id.Id, + }); + } + this.ChainPackage.PerMachine = harvestedMsiPackage.PerMachine; this.ChainPackage.Win64 = harvestedMsiPackage.Win64; @@ -218,11 +229,7 @@ namespace WixToolset.Core.Burn.Bundles this.CreateRelatedPackages(db); - // If feature selection is enabled, represent the Feature table in the manifest. - if (this.MsiPackage.EnableFeatureSelection) - { - this.CreateMsiFeatures(db); - } + this.CreateMsiFeatures(db); // Add all external cabinets as package payloads. this.ImportExternalCabinetAsPayloads(db, payloadNames); @@ -241,7 +248,7 @@ namespace WixToolset.Core.Burn.Bundles return null; } - return this.Section.AddSymbol(new WixBundleHarvestedMsiPackageSymbol(this.PackagePayload.SourceLineNumbers, this.ChainPackage.Id) + return this.Section.AddSymbol(new WixBundleHarvestedMsiPackageSymbol(this.PackagePayload.SourceLineNumbers, this.PackagePayload.Id) { PerMachine = perMachine, Win64 = win64, @@ -379,7 +386,7 @@ namespace WixToolset.Core.Burn.Bundles this.Section.AddSymbol(new WixBundleRelatedPackageSymbol(this.PackagePayload.SourceLineNumbers) { - PackageRef = this.PackageId, + PackagePayloadRef = this.PackagePayload.Id.Id, RelatedId = record.GetString(1), MinVersion = record.GetString(2), MaxVersion = record.GetString(3), @@ -425,9 +432,9 @@ namespace WixToolset.Core.Burn.Bundles } } - this.Section.AddSymbol(new WixBundleMsiFeatureSymbol(this.PackagePayload.SourceLineNumbers, new Identifier(AccessModifier.Section, this.PackageId, featureName)) + this.Section.AddSymbol(new WixBundleMsiFeatureSymbol(this.PackagePayload.SourceLineNumbers, new Identifier(AccessModifier.Section, this.PackagePayload.Id.Id, featureName)) { - PackageRef = this.PackageId, + PackagePayloadRef = this.PackagePayload.Id.Id, Name = featureName, Parent = allFeaturesResultRecord.GetString(2), Title = allFeaturesResultRecord.GetString(3), @@ -468,14 +475,6 @@ namespace WixToolset.Core.Burn.Bundles var generatedId = this.BackendHelper.GenerateIdentifier("cab", this.PackagePayload.Id.Id, cabinet); var payloadSourceFile = this.ResolveRelatedFile(this.PackagePayload.SourceFile.Path, this.PackagePayload.UnresolvedSourceFile, cabinet, "Cabinet", sourceLineNumbers); - this.Section.AddSymbol(new WixGroupSymbol(sourceLineNumbers) - { - ParentType = ComplexReferenceParentType.Package, - ParentId = this.PackageId, - ChildType = ComplexReferenceChildType.Payload, - ChildId = generatedId - }); - this.Section.AddSymbol(new WixBundlePayloadSymbol(sourceLineNumbers, new Identifier(AccessModifier.Section, generatedId)) { Name = cabinetName, @@ -540,14 +539,6 @@ namespace WixToolset.Core.Burn.Bundles var generatedId = this.BackendHelper.GenerateIdentifier("f", this.PackagePayload.Id.Id, record.GetString(2)); var payloadSourceFile = this.ResolveRelatedFile(this.PackagePayload.SourceFile.Path, this.PackagePayload.UnresolvedSourceFile, fileSourcePath, "File", sourceLineNumbers); - this.Section.AddSymbol(new WixGroupSymbol(sourceLineNumbers) - { - ParentType = ComplexReferenceParentType.Package, - ParentId = this.PackageId, - ChildType = ComplexReferenceChildType.Payload, - ChildId = generatedId - }); - this.Section.AddSymbol(new WixBundlePayloadSymbol(sourceLineNumbers, new Identifier(AccessModifier.Section, generatedId)) { Name = name, @@ -594,16 +585,16 @@ namespace WixToolset.Core.Burn.Bundles { foreach (var record in view.Records) { - var id = new Identifier(AccessModifier.Section, this.BackendHelper.GenerateIdentifier("dep", this.PackageId, record.GetString(1))); + var id = new Identifier(AccessModifier.Section, this.BackendHelper.GenerateIdentifier("dep", this.PackagePayload.Id.Id, record.GetString(1))); // Import the provider key and attributes. - this.Section.AddSymbol(new WixDependencyProviderSymbol(this.PackagePayload.SourceLineNumbers, id) + this.Section.AddSymbol(new WixBundleHarvestedDependencyProviderSymbol(this.PackagePayload.SourceLineNumbers, id) { - ParentRef = this.PackageId, + PackagePayloadRef = this.PackagePayload.Id.Id, ProviderKey = record.GetString(2), Version = record.GetString(3) ?? this.MsiPackage.ProductVersion, DisplayName = record.GetString(4) ?? this.ChainPackage.DisplayName, - Attributes = WixDependencyProviderAttributes.ProvidesAttributesImported | (WixDependencyProviderAttributes)record.GetInteger(5), + ProviderAttributes = record.GetInteger(5), }); } } diff --git a/src/wix/WixToolset.Core.Burn/Bundles/ProcessMspPackageCommand.cs b/src/wix/WixToolset.Core.Burn/Bundles/ProcessMspPackageCommand.cs index cef68c8a..466ef5b9 100644 --- a/src/wix/WixToolset.Core.Burn/Bundles/ProcessMspPackageCommand.cs +++ b/src/wix/WixToolset.Core.Burn/Bundles/ProcessMspPackageCommand.cs @@ -53,7 +53,7 @@ namespace WixToolset.Core.Burn.Bundles public void Execute() { var harvestedMspPackage = this.Section.Symbols.OfType() - .Where(h => h.Id == this.ChainPackage.Id) + .Where(h => h.Id == this.PackagePayload.Id) .SingleOrDefault(); if (harvestedMspPackage == null) @@ -123,7 +123,7 @@ namespace WixToolset.Core.Burn.Bundles return null; } - return this.Section.AddSymbol(new WixBundleHarvestedMspPackageSymbol(this.PackagePayload.SourceLineNumbers, this.ChainPackage.Id) + return this.Section.AddSymbol(new WixBundleHarvestedMspPackageSymbol(this.PackagePayload.SourceLineNumbers, this.PackagePayload.Id) { PatchCode = patchCode, DisplayName = displayName, @@ -175,7 +175,7 @@ namespace WixToolset.Core.Burn.Bundles { var symbol = section.AddSymbol(new WixBundlePatchTargetCodeSymbol(sourceLineNumbers) { - PackageRef = id.Id, + PackagePayloadRef = id.Id, TargetCode = targetCode, Attributes = 0, Type = type, diff --git a/src/wix/WixToolset.Core.Burn/BurnBackendErrors.cs b/src/wix/WixToolset.Core.Burn/BurnBackendErrors.cs index bf07fad2..0cfd849b 100644 --- a/src/wix/WixToolset.Core.Burn/BurnBackendErrors.cs +++ b/src/wix/WixToolset.Core.Burn/BurnBackendErrors.cs @@ -17,6 +17,11 @@ namespace WixToolset.Core.Burn return Message(sourceLineNumbers, Ids.BAContainerPayloadCollision2, "The location of the payload related to the previous error."); } + public static Message BundleMultipleProviders(SourceLineNumber sourceLineNumbers, string extraProviderKey, string originalProviderKey) + { + return Message(sourceLineNumbers, Ids.BundleMultipleProviders, "The bundle can only have a single dependency provider, but it has '{0}' and '{1}'.", originalProviderKey, extraProviderKey); + } + public static Message DuplicateCacheIds(SourceLineNumber originalLineNumber, string cacheId, string packageId) { return Message(originalLineNumber, Ids.DuplicateCacheIds, "The CacheId '{0}' for package '{1}' is duplicated. Each package must have a unique CacheId.", cacheId, packageId); @@ -110,6 +115,7 @@ namespace WixToolset.Core.Burn UnsupportedRemotePackagePayload = 8010, FailedToAddIconOrSplashScreenToBundle = 8011, InvalidBundleManifest = 8012, + BundleMultipleProviders = 8013, } // last available is 8499. 8500 is BurnBackendWarnings. } } diff --git a/src/wix/test/WixToolsetTest.CoreIntegration/PackagePayloadFixture.cs b/src/wix/test/WixToolsetTest.CoreIntegration/PackagePayloadFixture.cs index 6db96dbc..3dead50d 100644 --- a/src/wix/test/WixToolsetTest.CoreIntegration/PackagePayloadFixture.cs +++ b/src/wix/test/WixToolsetTest.CoreIntegration/PackagePayloadFixture.cs @@ -5,12 +5,90 @@ namespace WixToolsetTest.CoreIntegration using System.Collections.Generic; using System.IO; using System.Linq; + using System.Xml; using WixBuildTools.TestSupport; using WixToolset.Core.TestPackage; using Xunit; public class PackagePayloadFixture { + [Fact] + public void CanSpecifyMsiPackagePayloadInPayloadGroup() + { + var folder = TestData.Get(@"TestData"); + + using (var fs = new DisposableFileSystem()) + { + var baseFolder = fs.GetFolder(); + var intermediateFolder = Path.Combine(baseFolder, "obj"); + var bundlePath = Path.Combine(baseFolder, @"bin\test.exe"); + var baFolderPath = Path.Combine(baseFolder, "ba"); + var extractFolderPath = Path.Combine(baseFolder, "extract"); + + var result = WixRunner.Execute(new[] + { + "build", + Path.Combine(folder, "PackagePayload", "MsiPackagePayloadInPayloadGroup.wxs"), + Path.Combine(folder, "BundleWithPackageGroupRef", "Bundle.wxs"), + "-bindpath", Path.Combine(folder, "SimpleBundle", "data"), + "-bindpath", Path.Combine(folder, ".Data"), + "-intermediateFolder", intermediateFolder, + "-o", bundlePath, + }); + + result.AssertSuccess(); + + Assert.True(File.Exists(bundlePath)); + + var extractResult = BundleExtractor.ExtractBAContainer(null, bundlePath, baFolderPath, extractFolderPath); + extractResult.AssertSuccess(); + + var ignoreAttributesByElementName = new Dictionary> + { + { "ExePackage", new List { "CacheId", "InstallSize", "Size" } }, + }; + var msiPackageElements = extractResult.SelectManifestNodes("/burn:BurnManifest/burn:Chain/burn:MsiPackage") + .Cast() + .Select(e => e.GetTestXml(ignoreAttributesByElementName)) + .ToArray(); + WixAssert.CompareLineByLine(new[] + { + "" + + "" + + "" + + "" + + "" + + "", + + "" + + "" + + "" + + "" + + "" + + "", + }, msiPackageElements); + + var packageElements = extractResult.SelectBADataNodes("/ba:BootstrapperApplicationData/ba:WixPackageProperties") + .Cast() + .Select(e => e.GetTestXml()) + .ToArray(); + WixAssert.CompareLineByLine(new [] + { + "", + "", + }, packageElements); + + var featureElements = extractResult.SelectBADataNodes("/ba:BootstrapperApplicationData/ba:WixPackageFeatureInfo") + .Cast() + .Select(e => e.GetTestXml()) + .ToArray(); + WixAssert.CompareLineByLine(new[] + { + "", + }, featureElements); + } + } + [Fact] public void CanSpecifyPackagePayloadInPayloadGroup() { diff --git a/src/wix/test/WixToolsetTest.CoreIntegration/TestData/PackagePayload/MsiPackagePayloadInPayloadGroup.wxs b/src/wix/test/WixToolsetTest.CoreIntegration/TestData/PackagePayload/MsiPackagePayloadInPayloadGroup.wxs new file mode 100644 index 00000000..1fa7b7e6 --- /dev/null +++ b/src/wix/test/WixToolsetTest.CoreIntegration/TestData/PackagePayload/MsiPackagePayloadInPayloadGroup.wxs @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + -- cgit v1.2.3-55-g6feb