From 4d30dccc66470fb4311b602adee60bf00ae8e64f Mon Sep 17 00:00:00 2001 From: Rob Mensching Date: Thu, 10 Mar 2022 14:27:44 -0800 Subject: Implement "wix burn extract" In v3, bundles were extracted by "decompiling" even though the process did not actually result in decompiled source code. In v4, the backends and provide specialized commands so have "extract" join "detach" and "reattach" subcommands on the "burn" command. Completes 6314 --- src/wix/WixToolset.Core.Burn/BundleBackend.cs | 17 ----- .../CommandLine/BurnCommand.cs | 4 + .../CommandLine/ExtractSubcommand.cs | 86 ++++++++++++++++++++++ .../BundleExtractionFixture.cs | 23 +++--- 4 files changed, 104 insertions(+), 26 deletions(-) create mode 100644 src/wix/WixToolset.Core.Burn/CommandLine/ExtractSubcommand.cs diff --git a/src/wix/WixToolset.Core.Burn/BundleBackend.cs b/src/wix/WixToolset.Core.Burn/BundleBackend.cs index e248bc67..a2003989 100644 --- a/src/wix/WixToolset.Core.Burn/BundleBackend.cs +++ b/src/wix/WixToolset.Core.Burn/BundleBackend.cs @@ -3,9 +3,6 @@ namespace WixToolset.Core.Burn { using System; - using System.IO; - using WixToolset.Core.Burn.Bundles; - using WixToolset.Data; using WixToolset.Extensibility; using WixToolset.Extensibility.Data; using WixToolset.Extensibility.Services; @@ -43,19 +40,5 @@ namespace WixToolset.Core.Burn { throw new NotImplementedException(); } - - public Intermediate Unbind(IUnbindContext context) - { - var uxExtractPath = Path.Combine(context.ExportBasePath, "UX"); - var messaging = context.ServiceProvider.GetService(); - - using (var reader = BurnReader.Open(messaging, context.InputFilePath)) - { - reader.ExtractUXContainer(uxExtractPath, context.IntermediateFolder); - reader.ExtractAttachedContainers(context.ExportBasePath, context.IntermediateFolder); - } - - return null; - } } } diff --git a/src/wix/WixToolset.Core.Burn/CommandLine/BurnCommand.cs b/src/wix/WixToolset.Core.Burn/CommandLine/BurnCommand.cs index b552678f..c9c0c657 100644 --- a/src/wix/WixToolset.Core.Burn/CommandLine/BurnCommand.cs +++ b/src/wix/WixToolset.Core.Burn/CommandLine/BurnCommand.cs @@ -49,6 +49,10 @@ namespace WixToolset.Core.Burn.CommandLine this.Subcommand = new DetachSubcommand(this.ServiceProvider); return true; + case "extract": + this.Subcommand = new ExtractSubcommand(this.ServiceProvider); + return true; + case "reattach": this.Subcommand = new ReattachSubcommand(this.ServiceProvider); return true; diff --git a/src/wix/WixToolset.Core.Burn/CommandLine/ExtractSubcommand.cs b/src/wix/WixToolset.Core.Burn/CommandLine/ExtractSubcommand.cs new file mode 100644 index 00000000..859f5e34 --- /dev/null +++ b/src/wix/WixToolset.Core.Burn/CommandLine/ExtractSubcommand.cs @@ -0,0 +1,86 @@ +// 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.CommandLine +{ + using System; + using System.IO; + using System.Threading; + using System.Threading.Tasks; + using WixToolset.Core.Burn.Bundles; + using WixToolset.Core.Burn.Inscribe; + using WixToolset.Extensibility.Services; + + internal class ExtractSubcommand : BurnSubcommandBase + { + public ExtractSubcommand(IServiceProvider serviceProvider) + { + this.ServiceProvider = serviceProvider; + this.Messaging = serviceProvider.GetService(); + } + + private IServiceProvider ServiceProvider { get; } + + private IMessaging Messaging { get; } + + private string InputPath { get; set; } + + private string IntermediateFolder { get; set; } + + private string ExtractPath { get; set; } + + public override Task ExecuteAsync(CancellationToken cancellationToken) + { + if (String.IsNullOrEmpty(this.InputPath)) + { + Console.Error.WriteLine("Path to input bundle is required"); + return Task.FromResult(-1); + } + + if (String.IsNullOrEmpty(this.ExtractPath)) + { + Console.Error.WriteLine("Path to output the extracted bundle is required"); + return Task.FromResult(-1); + } + + if (String.IsNullOrEmpty(this.IntermediateFolder)) + { + this.IntermediateFolder = Path.GetTempPath(); + } + + var uxExtractPath = Path.Combine(this.ExtractPath, "BA"); + + using (var reader = BurnReader.Open(this.Messaging, this.InputPath)) + { + reader.ExtractUXContainer(uxExtractPath, this.IntermediateFolder); + reader.ExtractAttachedContainers(this.ExtractPath, this.IntermediateFolder); + } + + return Task.FromResult(this.Messaging.LastErrorNumber); + } + + public override bool TryParseArgument(ICommandLineParser parser, string argument) + { + if (parser.IsSwitch(argument)) + { + var parameter = argument.Substring(1); + switch (parameter.ToLowerInvariant()) + { + case "intermediatefolder": + this.IntermediateFolder = parser.GetNextArgumentAsDirectoryOrError(argument); + return true; + + case "o": + this.ExtractPath = parser.GetNextArgumentAsDirectoryOrError(argument); + return true; + } + } + else if (String.IsNullOrEmpty(this.InputPath)) + { + this.InputPath = argument; + return true; + } + + return false; + } + } +} diff --git a/src/wix/test/WixToolsetTest.CoreIntegration/BundleExtractionFixture.cs b/src/wix/test/WixToolsetTest.CoreIntegration/BundleExtractionFixture.cs index 5a5a52d3..478d8c95 100644 --- a/src/wix/test/WixToolsetTest.CoreIntegration/BundleExtractionFixture.cs +++ b/src/wix/test/WixToolsetTest.CoreIntegration/BundleExtractionFixture.cs @@ -5,10 +5,8 @@ namespace WixToolsetTest.CoreIntegration using System.IO; using System.Linq; using WixBuildTools.TestSupport; - using WixToolset.Core; using WixToolset.Core.TestPackage; using WixToolset.Data; - using WixToolset.Extensibility.Services; using Xunit; public class BundleExtractionFixture @@ -23,13 +21,10 @@ namespace WixToolsetTest.CoreIntegration var baseFolder = fs.GetFolder(); var intermediateFolder = Path.Combine(baseFolder, "obj"); var exePath = Path.Combine(baseFolder, @"bin\test.exe"); - var pdbPath = Path.Combine(baseFolder, @"bin\test.wixpdb"); var extractFolderPath = Path.Combine(baseFolder, "extract"); - var baFolderPath = Path.Combine(extractFolderPath, "UX"); + var baFolderPath = Path.Combine(extractFolderPath, "BA"); var attachedContainerFolderPath = Path.Combine(extractFolderPath, "WixAttachedContainer"); - // TODO: use WixRunner.Execute(string[]) to always go through the command line. - var serviceProvider = WixToolsetServiceProviderFactory.CreateServiceProvider(); var result = WixRunner.Execute(new[] { "build", @@ -40,14 +35,24 @@ namespace WixToolsetTest.CoreIntegration "-bindpath", Path.Combine(folder, ".Data"), "-intermediateFolder", intermediateFolder, "-o", exePath, - }, serviceProvider, out var messages).Result; + }); - WixRunnerResult.AssertSuccess(result, messages); - Assert.Empty(messages.Where(m => m.Level == MessageLevel.Warning)); + result.AssertSuccess(); + Assert.Empty(result.Messages.Where(m => m.Level == MessageLevel.Warning)); Assert.True(File.Exists(exePath)); + result = WixRunner.Execute(new[] + { + "burn", "extract", + exePath, + "-o", extractFolderPath + }); + + result.AssertSuccess(); + Assert.True(File.Exists(Path.Combine(baFolderPath, "manifest.xml"))); + Assert.False(Directory.Exists(attachedContainerFolderPath)); } } } -- cgit v1.2.3-55-g6feb