From 535e4165e3121a14e5799f575a1010671212c539 Mon Sep 17 00:00:00 2001 From: Sean Hall Date: Wed, 13 Apr 2022 12:17:36 -0500 Subject: Add bundle support to "burn remotepayload" command. --- .../WixToolset.Core.Burn/Bind/BindBundleCommand.cs | 2 + .../Bundles/HarvestBundlePackageCommand.cs | 248 +++++++++++++++++++++ .../Bundles/ProcessBundlePackageCommand.cs | 215 ++---------------- .../CommandLine/RemotePayloadSubcommand.cs | 79 ++++++- .../BundleFixture.cs | 2 +- .../PackagePayloadFixture.cs | 4 +- .../RemotePayloadFixture.cs | 35 ++- 7 files changed, 379 insertions(+), 206 deletions(-) create mode 100644 src/wix/WixToolset.Core.Burn/Bundles/HarvestBundlePackageCommand.cs (limited to 'src') diff --git a/src/wix/WixToolset.Core.Burn/Bind/BindBundleCommand.cs b/src/wix/WixToolset.Core.Burn/Bind/BindBundleCommand.cs index ffc219dc..1c88fdeb 100644 --- a/src/wix/WixToolset.Core.Burn/Bind/BindBundleCommand.cs +++ b/src/wix/WixToolset.Core.Burn/Bind/BindBundleCommand.cs @@ -182,6 +182,8 @@ namespace WixToolset.Core.Burn { var command = new ProcessBundlePackageCommand(this.ServiceProvider, section, facade, packagesPayloads[facade.PackageId], this.IntermediateFolder); command.Execute(); + + trackedFiles.AddRange(command.TrackedFiles); } break; diff --git a/src/wix/WixToolset.Core.Burn/Bundles/HarvestBundlePackageCommand.cs b/src/wix/WixToolset.Core.Burn/Bundles/HarvestBundlePackageCommand.cs new file mode 100644 index 00000000..84ce6051 --- /dev/null +++ b/src/wix/WixToolset.Core.Burn/Bundles/HarvestBundlePackageCommand.cs @@ -0,0 +1,248 @@ +// 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; + using System.Collections.Generic; + using System.IO; + using System.Text; + using System.Xml; + using WixToolset.Data; + using WixToolset.Data.Symbols; + using WixToolset.Extensibility.Data; + using WixToolset.Extensibility.Services; + + internal class HarvestBundlePackageCommand + { + public HarvestBundlePackageCommand(IServiceProvider serviceProvider, string intermediateFolder, WixBundlePayloadSymbol payloadSymbol) + { + this.Messaging = serviceProvider.GetService(); + this.BackendHelper = serviceProvider.GetService(); + this.IntermediateFolder = intermediateFolder; + + this.PackagePayload = payloadSymbol; + } + + private IMessaging Messaging { get; } + + private IBackendHelper BackendHelper { get; } + + private string IntermediateFolder { get; } + + private WixBundlePayloadSymbol PackagePayload { get; } + + public WixBundleHarvestedBundlePackageSymbol HarvestedBundlePackage { get; private set; } + + public WixBundleHarvestedDependencyProviderSymbol HarvestedDependencyProvider { get; private set; } + + public List RelatedBundles { get; } = new List(); + + public List TrackedFiles { get; } = new List(); + + public void Execute() + { + bool win64; + string bundleId; + string engineVersion; + int protocolVersion; + string manifestNamespace; + bool perMachine; + string version; + string displayName; + long installSize; + + var sourcePath = this.PackagePayload.SourceFile.Path; + var sourceLineNumbers = this.PackagePayload.SourceLineNumbers; + + using (var burnReader = BurnReader.Open(this.Messaging, sourcePath)) + { + if (burnReader.Invalid) + { + return; + } + + var baFolderPath = Path.Combine(this.IntermediateFolder, burnReader.BundleId.ToString()); + + if (!burnReader.ExtractUXContainer(baFolderPath, baFolderPath)) + { + return; + } + + foreach (var filePath in Directory.EnumerateFiles(baFolderPath, "*.*", SearchOption.AllDirectories)) + { + this.TrackedFiles.Add(this.BackendHelper.TrackFile(filePath, TrackedFileType.Temporary, sourceLineNumbers)); + } + + bundleId = burnReader.BundleId.ToString("B").ToUpperInvariant(); + + try + { + var document = new XmlDocument(); + document.Load(Path.Combine(baFolderPath, "manifest.xml")); + var namespaceManager = new XmlNamespaceManager(document.NameTable); + + if (document.DocumentElement.LocalName != "BurnManifest") + { + this.Messaging.Write(BurnBackendErrors.InvalidBundleManifest(sourceLineNumbers, sourcePath, $"Expected root element to be 'BurnManifest' but was '{document.DocumentElement.LocalName}'.")); + return; + } + + engineVersion = document.DocumentElement.GetAttribute("EngineVersion"); + protocolVersion = this.ProcessProtocolVersion(burnReader, document); + win64 = this.ProcessWin64(burnReader, document, sourceLineNumbers, sourcePath); + + manifestNamespace = document.DocumentElement.NamespaceURI; + + namespaceManager.AddNamespace("burn", document.DocumentElement.NamespaceURI); + var registrationElement = document.SelectSingleNode("/burn:BurnManifest/burn:Registration", namespaceManager) as XmlElement; + var arpElement = document.SelectSingleNode("/burn:BurnManifest/burn:Registration/burn:Arp", namespaceManager) as XmlElement; + + perMachine = registrationElement.GetAttribute("PerMachine") == "yes"; + + version = registrationElement.GetAttribute("Version"); + + var providerKey = registrationElement.GetAttribute("ProviderKey"); + var depId = new Identifier(AccessModifier.Section, this.BackendHelper.GenerateIdentifier("dep", this.PackagePayload.Id.Id, providerKey)); + this.HarvestedDependencyProvider = new WixBundleHarvestedDependencyProviderSymbol(sourceLineNumbers, depId) + { + PackagePayloadRef = this.PackagePayload.Id.Id, + ProviderKey = providerKey, + Version = version, + }; + + displayName = arpElement.GetAttribute("DisplayName"); + + installSize = this.ProcessPackages(document, namespaceManager); + + this.ProcessRelatedBundles(document, namespaceManager, sourcePath); + + // TODO: Add payloads? + } + catch (Exception e) + { + this.Messaging.Write(BurnBackendErrors.InvalidBundleManifest(sourceLineNumbers, sourcePath, e.ToString())); + return; + } + } + + this.HarvestedBundlePackage = new WixBundleHarvestedBundlePackageSymbol(this.PackagePayload.SourceLineNumbers, this.PackagePayload.Id) + { + Win64 = win64, + BundleId = bundleId, + EngineVersion = engineVersion, + ManifestNamespace = manifestNamespace, + ProtocolVersion = protocolVersion, + PerMachine = perMachine, + Version = version, + DisplayName = displayName, + InstallSize = installSize, + }; + } + + private int ProcessProtocolVersion(BurnReader burnReader, XmlDocument document) + { + var protocolVersionValue = document.DocumentElement.GetAttribute("ProtocolVersion"); + + if (Int32.TryParse(protocolVersionValue, out var protocolVersion)) + { + return protocolVersion; + } + + // Assume that the .wixburn section version will change when the Burn protocol changes. + // This should be a safe assumption since only old bundles should be missing the ProtocolVersion from the manifest. + return burnReader.Version == 2 ? 1 : 0; + } + + private bool ProcessWin64(BurnReader burnReader, XmlDocument document, SourceLineNumber sourceLineNumbers, string sourcePath) + { + var win64Value = document.DocumentElement.GetAttribute("Win64"); + + switch (win64Value) + { + case "yes": + return true; + case "no": + return false; + } + + switch (burnReader.MachineType) + { + case BurnCommon.IMAGE_FILE_MACHINE_ARM: + case BurnCommon.IMAGE_FILE_MACHINE_ARMNT: + case BurnCommon.IMAGE_FILE_MACHINE_I386: + case BurnCommon.IMAGE_FILE_MACHINE_LOONGARCH32: + return false; + case BurnCommon.IMAGE_FILE_MACHINE_AMD64: + case BurnCommon.IMAGE_FILE_MACHINE_ARM64: + case BurnCommon.IMAGE_FILE_MACHINE_IA64: + case BurnCommon.IMAGE_FILE_MACHINE_LOONGARCH64: + return true; + case BurnCommon.IMAGE_FILE_MACHINE_AM33: + case BurnCommon.IMAGE_FILE_MACHINE_EBC: + case BurnCommon.IMAGE_FILE_MACHINE_M32R: + case BurnCommon.IMAGE_FILE_MACHINE_MIPS16: + case BurnCommon.IMAGE_FILE_MACHINE_MIPSFPU: + case BurnCommon.IMAGE_FILE_MACHINE_MIPSFPU16: + case BurnCommon.IMAGE_FILE_MACHINE_POWERPC: + case BurnCommon.IMAGE_FILE_MACHINE_POWERPCFP: + case BurnCommon.IMAGE_FILE_MACHINE_R4000: + case BurnCommon.IMAGE_FILE_MACHINE_RISCV32: + case BurnCommon.IMAGE_FILE_MACHINE_RISCV64: + case BurnCommon.IMAGE_FILE_MACHINE_RISCV128: + case BurnCommon.IMAGE_FILE_MACHINE_SH3: + case BurnCommon.IMAGE_FILE_MACHINE_SH3DSP: + case BurnCommon.IMAGE_FILE_MACHINE_SH4: + case BurnCommon.IMAGE_FILE_MACHINE_SH5: + case BurnCommon.IMAGE_FILE_MACHINE_THUMB: + case BurnCommon.IMAGE_FILE_MACHINE_WCEMIPSV2: + default: + this.Messaging.Write(BurnBackendWarnings.UnknownCoffMachineType(sourceLineNumbers, sourcePath, burnReader.MachineType)); + return false; + } + } + + private long ProcessPackages(XmlDocument document, XmlNamespaceManager namespaceManager) + { + long packageInstallSize = 0; + + foreach (XmlElement packageElement in document.SelectNodes("/burn:BurnManifest/burn:Chain/*", namespaceManager)) + { + if (!packageElement.Name.EndsWith("Package")) + { + continue; + } + + if (Int64.TryParse(packageElement.GetAttribute("InstallSize"), out var installSize)) + { + packageInstallSize += installSize; + } + } + + return packageInstallSize; + } + + private void ProcessRelatedBundles(XmlDocument document, XmlNamespaceManager namespaceManager, string sourcePath) + { + var sourceLineNumbers = this.PackagePayload.SourceLineNumbers; + + foreach (XmlElement relatedBundleElement in document.SelectNodes("/burn:BurnManifest/burn:RelatedBundle", namespaceManager)) + { + var id = relatedBundleElement.GetAttribute("Id"); + var actionValue = relatedBundleElement.GetAttribute("Action"); + + if (!Enum.TryParse(actionValue, out RelatedBundleActionType action)) + { + this.Messaging.Write(BurnBackendWarnings.UnknownBundleRelationAction(sourceLineNumbers, sourcePath, actionValue)); + continue; + } + + this.RelatedBundles.Add(new WixBundlePackageRelatedBundleSymbol(sourceLineNumbers) + { + PackagePayloadRef = this.PackagePayload.Id.Id, + BundleId = id, + Action = action, + }); + } + } + } +} diff --git a/src/wix/WixToolset.Core.Burn/Bundles/ProcessBundlePackageCommand.cs b/src/wix/WixToolset.Core.Burn/Bundles/ProcessBundlePackageCommand.cs index c8e6bcf2..af37676c 100644 --- a/src/wix/WixToolset.Core.Burn/Bundles/ProcessBundlePackageCommand.cs +++ b/src/wix/WixToolset.Core.Burn/Bundles/ProcessBundlePackageCommand.cs @@ -4,10 +4,7 @@ namespace WixToolset.Core.Burn.Bundles { using System; using System.Collections.Generic; - using System.Diagnostics; - using System.IO; using System.Linq; - using System.Xml; using WixToolset.Data; using WixToolset.Data.Symbols; using WixToolset.Extensibility.Data; @@ -20,8 +17,8 @@ namespace WixToolset.Core.Burn.Bundles { public ProcessBundlePackageCommand(IServiceProvider serviceProvider, IntermediateSection section, PackageFacade facade, Dictionary packagePayloads, string intermediateFolder) { + this.ServiceProvider = serviceProvider; this.Messaging = serviceProvider.GetService(); - this.BackendHelper = serviceProvider.GetService(); this.PackagePayloads = packagePayloads; this.Section = section; this.IntermediateFolder = intermediateFolder; @@ -31,9 +28,9 @@ namespace WixToolset.Core.Burn.Bundles this.PackagePayload = packagePayloads[this.ChainPackage.PayloadRef]; } - private IMessaging Messaging { get; } + private IServiceProvider ServiceProvider { get; } - private IBackendHelper BackendHelper { get; } + private IMessaging Messaging { get; } private Dictionary PackagePayloads { get; } @@ -101,210 +98,26 @@ namespace WixToolset.Core.Burn.Bundles this.ChainPackage.InstallSize = harvestedBundlePackage.InstallSize; } - public WixBundleHarvestedBundlePackageSymbol HarvestPackage() + private WixBundleHarvestedBundlePackageSymbol HarvestPackage() { - bool win64; - string bundleId; - string engineVersion; - int protocolVersion; - string manifestNamespace; - bool perMachine; - string version; - string displayName; - long installSize; - - var sourcePath = this.PackagePayload.SourceFile.Path; - var sourceLineNumbers = this.PackagePayload.SourceLineNumbers; + var command = new HarvestBundlePackageCommand(this.ServiceProvider, this.IntermediateFolder, this.PackagePayload); + command.Execute(); - using (var burnReader = BurnReader.Open(this.Messaging, sourcePath)) + this.TrackedFiles.AddRange(command.TrackedFiles); + if (this.Messaging.EncounteredError) { - if (burnReader.Invalid) - { - return null; - } - - var baFolderPath = Path.Combine(this.IntermediateFolder, burnReader.BundleId.ToString()); - - if (!burnReader.ExtractUXContainer(baFolderPath, baFolderPath)) - { - return null; - } - - foreach (var filePath in Directory.EnumerateFiles(baFolderPath, "*.*", SearchOption.AllDirectories)) - { - this.TrackedFiles.Add(this.BackendHelper.TrackFile(filePath, TrackedFileType.Temporary, sourceLineNumbers)); - } - - bundleId = burnReader.BundleId.ToString("B").ToUpperInvariant(); - - try - { - var document = new XmlDocument(); - document.Load(Path.Combine(baFolderPath, "manifest.xml")); - var namespaceManager = new XmlNamespaceManager(document.NameTable); - - if (document.DocumentElement.LocalName != "BurnManifest") - { - this.Messaging.Write(BurnBackendErrors.InvalidBundleManifest(sourceLineNumbers, sourcePath, $"Expected root element to be 'BurnManifest' but was '{document.DocumentElement.LocalName}'.")); - return null; - } - - engineVersion = document.DocumentElement.GetAttribute("EngineVersion"); - protocolVersion = this.ProcessProtocolVersion(burnReader, document); - win64 = this.ProcessWin64(burnReader, document, sourceLineNumbers, sourcePath); - - manifestNamespace = document.DocumentElement.NamespaceURI; - - namespaceManager.AddNamespace("burn", document.DocumentElement.NamespaceURI); - var registrationElement = document.SelectSingleNode("/burn:BurnManifest/burn:Registration", namespaceManager) as XmlElement; - var arpElement = document.SelectSingleNode("/burn:BurnManifest/burn:Registration/burn:Arp", namespaceManager) as XmlElement; - - perMachine = registrationElement.GetAttribute("PerMachine") == "yes"; - - version = registrationElement.GetAttribute("Version"); - - var providerKey = registrationElement.GetAttribute("ProviderKey"); - var depId = new Identifier(AccessModifier.Section, this.BackendHelper.GenerateIdentifier("dep", this.PackagePayload.Id.Id, providerKey)); - this.Section.AddSymbol(new WixBundleHarvestedDependencyProviderSymbol(sourceLineNumbers, depId) - { - PackagePayloadRef = this.PackagePayload.Id.Id, - ProviderKey = providerKey, - Version = version, - }); - - displayName = arpElement.GetAttribute("DisplayName"); - - installSize = this.ProcessPackages(document, namespaceManager); - - this.ProcessRelatedBundles(document, namespaceManager, sourcePath); - - // TODO: Add payloads? - } - catch (Exception e) - { - this.Messaging.Write(BurnBackendErrors.InvalidBundleManifest(sourceLineNumbers, sourcePath, e.ToString())); - return null; - } + return null; } - return this.Section.AddSymbol(new WixBundleHarvestedBundlePackageSymbol(this.PackagePayload.SourceLineNumbers, this.PackagePayload.Id) - { - Win64 = win64, - BundleId = bundleId, - EngineVersion = engineVersion, - ManifestNamespace = manifestNamespace, - ProtocolVersion = protocolVersion, - PerMachine = perMachine, - Version = version, - DisplayName = displayName, - InstallSize = installSize, - }); - } - - private int ProcessProtocolVersion(BurnReader burnReader, XmlDocument document) - { - var protocolVersionValue = document.DocumentElement.GetAttribute("ProtocolVersion"); + this.Section.AddSymbol(command.HarvestedBundlePackage); + this.Section.AddSymbol(command.HarvestedDependencyProvider); - if (Int32.TryParse(protocolVersionValue, out var protocolVersion)) + foreach (var relatedBundle in command.RelatedBundles) { - return protocolVersion; + this.Section.AddSymbol(relatedBundle); } - // Assume that the .wixburn section version will change when the Burn protocol changes. - // This should be a safe assumption since only old bundles should be missing the ProtocolVersion from the manifest. - return burnReader.Version == 2 ? 1 : 0; - } - - private bool ProcessWin64(BurnReader burnReader, XmlDocument document, SourceLineNumber sourceLineNumbers, string sourcePath) - { - var win64Value = document.DocumentElement.GetAttribute("Win64"); - - switch (win64Value) - { - case "yes": - return true; - case "no": - return false; - } - - switch (burnReader.MachineType) - { - case BurnCommon.IMAGE_FILE_MACHINE_ARM: - case BurnCommon.IMAGE_FILE_MACHINE_ARMNT: - case BurnCommon.IMAGE_FILE_MACHINE_I386: - case BurnCommon.IMAGE_FILE_MACHINE_LOONGARCH32: - return false; - case BurnCommon.IMAGE_FILE_MACHINE_AMD64: - case BurnCommon.IMAGE_FILE_MACHINE_ARM64: - case BurnCommon.IMAGE_FILE_MACHINE_IA64: - case BurnCommon.IMAGE_FILE_MACHINE_LOONGARCH64: - return true; - case BurnCommon.IMAGE_FILE_MACHINE_AM33: - case BurnCommon.IMAGE_FILE_MACHINE_EBC: - case BurnCommon.IMAGE_FILE_MACHINE_M32R: - case BurnCommon.IMAGE_FILE_MACHINE_MIPS16: - case BurnCommon.IMAGE_FILE_MACHINE_MIPSFPU: - case BurnCommon.IMAGE_FILE_MACHINE_MIPSFPU16: - case BurnCommon.IMAGE_FILE_MACHINE_POWERPC: - case BurnCommon.IMAGE_FILE_MACHINE_POWERPCFP: - case BurnCommon.IMAGE_FILE_MACHINE_R4000: - case BurnCommon.IMAGE_FILE_MACHINE_RISCV32: - case BurnCommon.IMAGE_FILE_MACHINE_RISCV64: - case BurnCommon.IMAGE_FILE_MACHINE_RISCV128: - case BurnCommon.IMAGE_FILE_MACHINE_SH3: - case BurnCommon.IMAGE_FILE_MACHINE_SH3DSP: - case BurnCommon.IMAGE_FILE_MACHINE_SH4: - case BurnCommon.IMAGE_FILE_MACHINE_SH5: - case BurnCommon.IMAGE_FILE_MACHINE_THUMB: - case BurnCommon.IMAGE_FILE_MACHINE_WCEMIPSV2: - default: - this.Messaging.Write(BurnBackendWarnings.UnknownCoffMachineType(sourceLineNumbers, sourcePath, burnReader.MachineType)); - return false; - } - } - - private long ProcessPackages(XmlDocument document, XmlNamespaceManager namespaceManager) - { - long packageInstallSize = 0; - - foreach (XmlElement packageElement in document.SelectNodes("/burn:BurnManifest/burn:Chain/*", namespaceManager)) - { - if (!packageElement.Name.EndsWith("Package")) - { - continue; - } - - if (Int64.TryParse(packageElement.GetAttribute("InstallSize"), out var installSize)) - { - packageInstallSize += installSize; - } - } - - return packageInstallSize; - } - - private void ProcessRelatedBundles(XmlDocument document, XmlNamespaceManager namespaceManager, string sourcePath) - { - var sourceLineNumbers = this.PackagePayload.SourceLineNumbers; - - foreach (XmlElement relatedBundleElement in document.SelectNodes("/burn:BurnManifest/burn:RelatedBundle", namespaceManager)) - { - var id = relatedBundleElement.GetAttribute("Id"); - var actionValue = relatedBundleElement.GetAttribute("Action"); - - if (!Enum.TryParse(actionValue, out RelatedBundleActionType action)) - { - this.Messaging.Write(BurnBackendWarnings.UnknownBundleRelationAction(sourceLineNumbers, sourcePath, actionValue)); - continue; - } - - this.Section.AddSymbol(new WixBundlePackageRelatedBundleSymbol(sourceLineNumbers) - { - PackagePayloadRef = this.PackagePayload.Id.Id, - BundleId = id, - Action = action, - }); - } + return command.HarvestedBundlePackage; } } } diff --git a/src/wix/WixToolset.Core.Burn/CommandLine/RemotePayloadSubcommand.cs b/src/wix/WixToolset.Core.Burn/CommandLine/RemotePayloadSubcommand.cs index 7b362485..6eed62eb 100644 --- a/src/wix/WixToolset.Core.Burn/CommandLine/RemotePayloadSubcommand.cs +++ b/src/wix/WixToolset.Core.Burn/CommandLine/RemotePayloadSubcommand.cs @@ -9,6 +9,7 @@ namespace WixToolset.Core.Burn.CommandLine using System.Threading; using System.Threading.Tasks; using System.Xml.Linq; + using WixToolset.Core.Burn.Bundles; using WixToolset.Core.Burn.Interfaces; using WixToolset.Core.Native; using WixToolset.Data; @@ -17,16 +18,22 @@ namespace WixToolset.Core.Burn.CommandLine internal class RemotePayloadSubcommand : BurnSubcommandBase { + private static readonly XName BundlePackagePayloadName = "BundlePackagePayload"; private static readonly XName ExePackagePayloadName = "ExePackagePayload"; private static readonly XName MsuPackagePayloadName = "MsuPackagePayload"; private static readonly XName PayloadName = "Payload"; + private static readonly XName RemoteBundleName = "RemoteBundle"; + private static readonly XName RemoteRelatedBundleName = "RemoteRelatedBundle"; public RemotePayloadSubcommand(IServiceProvider serviceProvider) { + this.ServiceProvider = serviceProvider; this.Messaging = serviceProvider.GetService(); this.PayloadHarvester = serviceProvider.GetService(); } + private IServiceProvider ServiceProvider { get; } + private IMessaging Messaging { get; } private IPayloadHarvester PayloadHarvester { get; } @@ -37,6 +44,8 @@ namespace WixToolset.Core.Burn.CommandLine private List InputPaths { get; } = new List(); + private string IntermediateFolder { get; set; } + private string OutputPath { get; set; } private WixBundlePackageType? PackageType { get; set; } @@ -58,6 +67,11 @@ namespace WixToolset.Core.Burn.CommandLine this.BasePaths.Sort(); this.BasePaths.Reverse(); + if (String.IsNullOrEmpty(this.IntermediateFolder)) + { + this.IntermediateFolder = Path.GetTempPath(); + } + var elements = this.HarvestRemotePayloads(inputPaths); if (!this.Messaging.EncounteredError) @@ -98,6 +112,10 @@ namespace WixToolset.Core.Burn.CommandLine this.DownloadUrl = parser.GetNextArgumentOrError(argument); return true; + case "intermediatefolder": + this.IntermediateFolder = parser.GetNextArgumentAsDirectoryOrError(argument); + return true; + case "packagetype": var packageTypeValue = parser.GetNextArgumentOrError(argument); if (Enum.TryParse(packageTypeValue, ignoreCase: true, out var packageType)) @@ -174,7 +192,7 @@ namespace WixToolset.Core.Burn.CommandLine continue; } - var payloadSymbol = new WixBundlePayloadSymbol + var payloadSymbol = new WixBundlePayloadSymbol(null, new Identifier(AccessModifier.Section, "id")) { SourceFile = new IntermediateFieldPathValue { Path = path }, }; @@ -225,6 +243,62 @@ namespace WixToolset.Core.Burn.CommandLine element.Add(new XAttribute("Version", payloadSymbol.Version)); } + if (element.Name == BundlePackagePayloadName) + { + var command = new HarvestBundlePackageCommand(this.ServiceProvider, this.IntermediateFolder, payloadSymbol); + command.Execute(); + + if (!this.Messaging.EncounteredError) + { + var bundleElement = new XElement(RemoteBundleName); + + bundleElement.Add(new XAttribute("BundleId", command.HarvestedBundlePackage.BundleId)); + + if (!String.IsNullOrEmpty(command.HarvestedBundlePackage.DisplayName)) + { + bundleElement.Add(new XAttribute("DisplayName", command.HarvestedBundlePackage.DisplayName)); + } + + if (!String.IsNullOrEmpty(command.HarvestedBundlePackage.EngineVersion)) + { + bundleElement.Add(new XAttribute("EngineVersion", command.HarvestedBundlePackage.EngineVersion)); + } + + bundleElement.Add(new XAttribute("InstallSize", command.HarvestedBundlePackage.InstallSize)); + bundleElement.Add(new XAttribute("ManifestNamespace", command.HarvestedBundlePackage.ManifestNamespace)); + bundleElement.Add(new XAttribute("PerMachine", command.HarvestedBundlePackage.PerMachine ? "yes" : "no")); + bundleElement.Add(new XAttribute("ProviderKey", command.HarvestedDependencyProvider.ProviderKey)); + bundleElement.Add(new XAttribute("ProtocolVersion", command.HarvestedBundlePackage.ProtocolVersion)); + + if (!String.IsNullOrEmpty(command.HarvestedBundlePackage.Version)) + { + bundleElement.Add(new XAttribute("Version", command.HarvestedBundlePackage.Version)); + } + + bundleElement.Add(new XAttribute("Win64", command.HarvestedBundlePackage.Win64 ? "yes" : "no")); + + var setUpgradeCode = false; + foreach (var relatedBundle in command.RelatedBundles) + { + if (!setUpgradeCode && relatedBundle.Action == RelatedBundleActionType.Upgrade) + { + setUpgradeCode = true; + bundleElement.Add(new XAttribute("UpgradeCode", relatedBundle.BundleId)); + continue; + } + + var relatedBundleElement = new XElement(RemoteRelatedBundleName); + + relatedBundleElement.Add(new XAttribute("Id", relatedBundle.BundleId)); + relatedBundleElement.Add(new XAttribute("Action", relatedBundle.Action.ToString())); + + bundleElement.Add(relatedBundleElement); + } + + element.Add(bundleElement); + } + } + yield return element; } } @@ -237,6 +311,9 @@ namespace WixToolset.Core.Burn.CommandLine switch (extension.ToUpperInvariant()) { + case "BUNDLE": + return new XElement(BundlePackagePayloadName); + case "EXE": case ".EXE": return new XElement(ExePackagePayloadName); diff --git a/src/wix/test/WixToolsetTest.CoreIntegration/BundleFixture.cs b/src/wix/test/WixToolsetTest.CoreIntegration/BundleFixture.cs index 0dd29e38..6387a12a 100644 --- a/src/wix/test/WixToolsetTest.CoreIntegration/BundleFixture.cs +++ b/src/wix/test/WixToolsetTest.CoreIntegration/BundleFixture.cs @@ -574,7 +574,7 @@ namespace WixToolsetTest.CoreIntegration } [Fact] - public void CantBuildWithSubfolderContainer() + public void CanBuildWithSubfolderContainer() { var folder = TestData.Get(@"TestData"); diff --git a/src/wix/test/WixToolsetTest.CoreIntegration/PackagePayloadFixture.cs b/src/wix/test/WixToolsetTest.CoreIntegration/PackagePayloadFixture.cs index 3dead50d..29ea1e7f 100644 --- a/src/wix/test/WixToolsetTest.CoreIntegration/PackagePayloadFixture.cs +++ b/src/wix/test/WixToolsetTest.CoreIntegration/PackagePayloadFixture.cs @@ -90,7 +90,7 @@ namespace WixToolsetTest.CoreIntegration } [Fact] - public void CanSpecifyPackagePayloadInPayloadGroup() + public void CanSpecifyExePackagePayloadInPayloadGroup() { var folder = TestData.Get(@"TestData"); @@ -135,7 +135,7 @@ namespace WixToolsetTest.CoreIntegration } [Fact] - public void CanSpecifyPackagePayloadWithCertificate() + public void CanSpecifyExePackagePayloadWithCertificate() { var folder = TestData.Get(@"TestData", "PackagePayload"); diff --git a/src/wix/test/WixToolsetTest.CoreIntegration/RemotePayloadFixture.cs b/src/wix/test/WixToolsetTest.CoreIntegration/RemotePayloadFixture.cs index 434b3621..41791bd0 100644 --- a/src/wix/test/WixToolsetTest.CoreIntegration/RemotePayloadFixture.cs +++ b/src/wix/test/WixToolsetTest.CoreIntegration/RemotePayloadFixture.cs @@ -11,7 +11,40 @@ namespace WixToolsetTest.CoreIntegration public class RemotePayloadFixture { [Fact] - public void CanGetRemotePayload() + public void CanGetRemoteV3BundlePayload() + { + var folder = TestData.Get(@"TestData"); + + using (var fs = new DisposableFileSystem()) + { + var outputFolder = fs.GetFolder(); + var outFile = Path.Combine(outputFolder, "out.xml"); + + var result = WixRunner.Execute(new[] + { + "burn", "remotepayload", + Path.Combine(folder, ".Data", "v3bundle.exe"), + "-downloadurl", "https://www.example.com/files/{0}", + "-o", outFile, + "-packagetype", "bundle", + }); + + result.AssertSuccess(); + + var elements = File.ReadAllLines(outFile); + elements = elements.Select(s => s.Replace("\"", "'")).ToArray(); + + WixAssert.CompareLineByLine(new[] + { + "", + " ", + "", + }, elements); + } + } + + [Fact] + public void CanGetRemoteExePayload() { var folder = TestData.Get(@"TestData"); -- cgit v1.2.3-55-g6feb