diff options
author | Rob Mensching <rob@firegiant.com> | 2022-03-10 14:27:44 -0800 |
---|---|---|
committer | Rob Mensching <rob@firegiant.com> | 2022-03-14 12:50:55 -0700 |
commit | 4d30dccc66470fb4311b602adee60bf00ae8e64f (patch) | |
tree | 46f6a666ee985d865e131215ce047c82cff907b1 | |
parent | 64750a8dd105d89c27613694e1008a454df2a4ee (diff) | |
download | wix-4d30dccc66470fb4311b602adee60bf00ae8e64f.tar.gz wix-4d30dccc66470fb4311b602adee60bf00ae8e64f.tar.bz2 wix-4d30dccc66470fb4311b602adee60bf00ae8e64f.zip |
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
4 files changed, 104 insertions, 26 deletions
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 @@ | |||
3 | namespace WixToolset.Core.Burn | 3 | namespace WixToolset.Core.Burn |
4 | { | 4 | { |
5 | using System; | 5 | using System; |
6 | using System.IO; | ||
7 | using WixToolset.Core.Burn.Bundles; | ||
8 | using WixToolset.Data; | ||
9 | using WixToolset.Extensibility; | 6 | using WixToolset.Extensibility; |
10 | using WixToolset.Extensibility.Data; | 7 | using WixToolset.Extensibility.Data; |
11 | using WixToolset.Extensibility.Services; | 8 | using WixToolset.Extensibility.Services; |
@@ -43,19 +40,5 @@ namespace WixToolset.Core.Burn | |||
43 | { | 40 | { |
44 | throw new NotImplementedException(); | 41 | throw new NotImplementedException(); |
45 | } | 42 | } |
46 | |||
47 | public Intermediate Unbind(IUnbindContext context) | ||
48 | { | ||
49 | var uxExtractPath = Path.Combine(context.ExportBasePath, "UX"); | ||
50 | var messaging = context.ServiceProvider.GetService<IMessaging>(); | ||
51 | |||
52 | using (var reader = BurnReader.Open(messaging, context.InputFilePath)) | ||
53 | { | ||
54 | reader.ExtractUXContainer(uxExtractPath, context.IntermediateFolder); | ||
55 | reader.ExtractAttachedContainers(context.ExportBasePath, context.IntermediateFolder); | ||
56 | } | ||
57 | |||
58 | return null; | ||
59 | } | ||
60 | } | 43 | } |
61 | } | 44 | } |
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 | |||
49 | this.Subcommand = new DetachSubcommand(this.ServiceProvider); | 49 | this.Subcommand = new DetachSubcommand(this.ServiceProvider); |
50 | return true; | 50 | return true; |
51 | 51 | ||
52 | case "extract": | ||
53 | this.Subcommand = new ExtractSubcommand(this.ServiceProvider); | ||
54 | return true; | ||
55 | |||
52 | case "reattach": | 56 | case "reattach": |
53 | this.Subcommand = new ReattachSubcommand(this.ServiceProvider); | 57 | this.Subcommand = new ReattachSubcommand(this.ServiceProvider); |
54 | return true; | 58 | 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 @@ | |||
1 | // 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. | ||
2 | |||
3 | namespace WixToolset.Core.Burn.CommandLine | ||
4 | { | ||
5 | using System; | ||
6 | using System.IO; | ||
7 | using System.Threading; | ||
8 | using System.Threading.Tasks; | ||
9 | using WixToolset.Core.Burn.Bundles; | ||
10 | using WixToolset.Core.Burn.Inscribe; | ||
11 | using WixToolset.Extensibility.Services; | ||
12 | |||
13 | internal class ExtractSubcommand : BurnSubcommandBase | ||
14 | { | ||
15 | public ExtractSubcommand(IServiceProvider serviceProvider) | ||
16 | { | ||
17 | this.ServiceProvider = serviceProvider; | ||
18 | this.Messaging = serviceProvider.GetService<IMessaging>(); | ||
19 | } | ||
20 | |||
21 | private IServiceProvider ServiceProvider { get; } | ||
22 | |||
23 | private IMessaging Messaging { get; } | ||
24 | |||
25 | private string InputPath { get; set; } | ||
26 | |||
27 | private string IntermediateFolder { get; set; } | ||
28 | |||
29 | private string ExtractPath { get; set; } | ||
30 | |||
31 | public override Task<int> ExecuteAsync(CancellationToken cancellationToken) | ||
32 | { | ||
33 | if (String.IsNullOrEmpty(this.InputPath)) | ||
34 | { | ||
35 | Console.Error.WriteLine("Path to input bundle is required"); | ||
36 | return Task.FromResult(-1); | ||
37 | } | ||
38 | |||
39 | if (String.IsNullOrEmpty(this.ExtractPath)) | ||
40 | { | ||
41 | Console.Error.WriteLine("Path to output the extracted bundle is required"); | ||
42 | return Task.FromResult(-1); | ||
43 | } | ||
44 | |||
45 | if (String.IsNullOrEmpty(this.IntermediateFolder)) | ||
46 | { | ||
47 | this.IntermediateFolder = Path.GetTempPath(); | ||
48 | } | ||
49 | |||
50 | var uxExtractPath = Path.Combine(this.ExtractPath, "BA"); | ||
51 | |||
52 | using (var reader = BurnReader.Open(this.Messaging, this.InputPath)) | ||
53 | { | ||
54 | reader.ExtractUXContainer(uxExtractPath, this.IntermediateFolder); | ||
55 | reader.ExtractAttachedContainers(this.ExtractPath, this.IntermediateFolder); | ||
56 | } | ||
57 | |||
58 | return Task.FromResult(this.Messaging.LastErrorNumber); | ||
59 | } | ||
60 | |||
61 | public override bool TryParseArgument(ICommandLineParser parser, string argument) | ||
62 | { | ||
63 | if (parser.IsSwitch(argument)) | ||
64 | { | ||
65 | var parameter = argument.Substring(1); | ||
66 | switch (parameter.ToLowerInvariant()) | ||
67 | { | ||
68 | case "intermediatefolder": | ||
69 | this.IntermediateFolder = parser.GetNextArgumentAsDirectoryOrError(argument); | ||
70 | return true; | ||
71 | |||
72 | case "o": | ||
73 | this.ExtractPath = parser.GetNextArgumentAsDirectoryOrError(argument); | ||
74 | return true; | ||
75 | } | ||
76 | } | ||
77 | else if (String.IsNullOrEmpty(this.InputPath)) | ||
78 | { | ||
79 | this.InputPath = argument; | ||
80 | return true; | ||
81 | } | ||
82 | |||
83 | return false; | ||
84 | } | ||
85 | } | ||
86 | } | ||
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 | |||
5 | using System.IO; | 5 | using System.IO; |
6 | using System.Linq; | 6 | using System.Linq; |
7 | using WixBuildTools.TestSupport; | 7 | using WixBuildTools.TestSupport; |
8 | using WixToolset.Core; | ||
9 | using WixToolset.Core.TestPackage; | 8 | using WixToolset.Core.TestPackage; |
10 | using WixToolset.Data; | 9 | using WixToolset.Data; |
11 | using WixToolset.Extensibility.Services; | ||
12 | using Xunit; | 10 | using Xunit; |
13 | 11 | ||
14 | public class BundleExtractionFixture | 12 | public class BundleExtractionFixture |
@@ -23,13 +21,10 @@ namespace WixToolsetTest.CoreIntegration | |||
23 | var baseFolder = fs.GetFolder(); | 21 | var baseFolder = fs.GetFolder(); |
24 | var intermediateFolder = Path.Combine(baseFolder, "obj"); | 22 | var intermediateFolder = Path.Combine(baseFolder, "obj"); |
25 | var exePath = Path.Combine(baseFolder, @"bin\test.exe"); | 23 | var exePath = Path.Combine(baseFolder, @"bin\test.exe"); |
26 | var pdbPath = Path.Combine(baseFolder, @"bin\test.wixpdb"); | ||
27 | var extractFolderPath = Path.Combine(baseFolder, "extract"); | 24 | var extractFolderPath = Path.Combine(baseFolder, "extract"); |
28 | var baFolderPath = Path.Combine(extractFolderPath, "UX"); | 25 | var baFolderPath = Path.Combine(extractFolderPath, "BA"); |
29 | var attachedContainerFolderPath = Path.Combine(extractFolderPath, "WixAttachedContainer"); | 26 | var attachedContainerFolderPath = Path.Combine(extractFolderPath, "WixAttachedContainer"); |
30 | 27 | ||
31 | // TODO: use WixRunner.Execute(string[]) to always go through the command line. | ||
32 | var serviceProvider = WixToolsetServiceProviderFactory.CreateServiceProvider(); | ||
33 | var result = WixRunner.Execute(new[] | 28 | var result = WixRunner.Execute(new[] |
34 | { | 29 | { |
35 | "build", | 30 | "build", |
@@ -40,14 +35,24 @@ namespace WixToolsetTest.CoreIntegration | |||
40 | "-bindpath", Path.Combine(folder, ".Data"), | 35 | "-bindpath", Path.Combine(folder, ".Data"), |
41 | "-intermediateFolder", intermediateFolder, | 36 | "-intermediateFolder", intermediateFolder, |
42 | "-o", exePath, | 37 | "-o", exePath, |
43 | }, serviceProvider, out var messages).Result; | 38 | }); |
44 | 39 | ||
45 | WixRunnerResult.AssertSuccess(result, messages); | 40 | result.AssertSuccess(); |
46 | Assert.Empty(messages.Where(m => m.Level == MessageLevel.Warning)); | 41 | Assert.Empty(result.Messages.Where(m => m.Level == MessageLevel.Warning)); |
47 | 42 | ||
48 | Assert.True(File.Exists(exePath)); | 43 | Assert.True(File.Exists(exePath)); |
49 | 44 | ||
45 | result = WixRunner.Execute(new[] | ||
46 | { | ||
47 | "burn", "extract", | ||
48 | exePath, | ||
49 | "-o", extractFolderPath | ||
50 | }); | ||
51 | |||
52 | result.AssertSuccess(); | ||
50 | 53 | ||
54 | Assert.True(File.Exists(Path.Combine(baFolderPath, "manifest.xml"))); | ||
55 | Assert.False(Directory.Exists(attachedContainerFolderPath)); | ||
51 | } | 56 | } |
52 | } | 57 | } |
53 | } | 58 | } |