main
cs 116 lines 4.52 KB
Raw
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.Data;
11 using WixToolset.Extensibility.Data;
12 using WixToolset.Extensibility.Services;
13
14 internal class ExtractSubcommand : BurnSubcommandBase
15 {
16 public ExtractSubcommand(IServiceProvider serviceProvider)
17 {
18 this.Messaging = serviceProvider.GetService<IMessaging>();
19 this.FileSystem = serviceProvider.GetService<IFileSystem>();
20 }
21
22 private IMessaging Messaging { get; }
23
24 private IFileSystem FileSystem { get; }
25
26 private string InputPath { get; set; }
27
28 private string IntermediateFolder { get; set; }
29
30 private string ExtractBootstrapperApplicationPath { get; set; }
31
32 private string ExtractContainersPath { get; set; }
33
34 public override CommandLineHelp GetCommandLineHelp()
35 {
36 return new CommandLineHelp("Extracts the contents of a bundle.", "burn extract [options] bundle.exe -o outputfolder", new[]
37 {
38 new CommandLineHelpSwitch("-intermediateFolder", "Optional working folder. If not specified %TMP% will be used."),
39 new CommandLineHelpSwitch("-outba", "-oba", "Folder to extract the bundle bootstrapper application to."),
40 new CommandLineHelpSwitch("-out", "-o", "Folder to extract the bundle contents to."),
41 });
42 }
43
44 public override Task<int> ExecuteAsync(CancellationToken cancellationToken)
45 {
46 if (String.IsNullOrEmpty(this.InputPath))
47 {
48 this.Messaging.Write(ErrorMessages.FilePathRequired("input bundle"));
49 }
50 else if (String.IsNullOrEmpty(this.ExtractBootstrapperApplicationPath) && String.IsNullOrEmpty(this.ExtractContainersPath))
51 {
52 this.Messaging.Write(ErrorMessages.FilePathRequired("output the extracted bundle"));
53 }
54 else
55 {
56 if (String.IsNullOrEmpty(this.IntermediateFolder))
57 {
58 this.IntermediateFolder = Path.GetTempPath();
59 }
60
61 using (var reader = BurnReader.Open(this.Messaging, this.FileSystem, this.InputPath))
62 {
63 if (!String.IsNullOrEmpty(this.ExtractBootstrapperApplicationPath))
64 {
65 reader.ExtractUXContainer(this.ExtractBootstrapperApplicationPath, this.IntermediateFolder);
66 }
67
68 try
69 {
70 if (!String.IsNullOrEmpty(this.ExtractContainersPath))
71 {
72 reader.ExtractAttachedContainers(this.ExtractContainersPath, this.IntermediateFolder);
73 }
74 }
75 catch (Exception e)
76 {
77 this.Messaging.Write(BurnBackendWarnings.FailedToExtractAttachedContainers(new SourceLineNumber(this.ExtractContainersPath), e.Message));
78 }
79 }
80 }
81
82 return Task.FromResult(this.Messaging.LastErrorNumber);
83 }
84
85 public override bool TryParseArgument(ICommandLineParser parser, string argument)
86 {
87 if (parser.IsSwitch(argument))
88 {
89 var parameter = argument.Substring(1);
90 switch (parameter.ToLowerInvariant())
91 {
92 case "intermediatefolder":
93 this.IntermediateFolder = parser.GetNextArgumentAsDirectoryOrError(argument);
94 return true;
95
96 case "oba":
97 case "outba":
98 this.ExtractBootstrapperApplicationPath = parser.GetNextArgumentAsDirectoryOrError(argument);
99 return true;
100
101 case "o":
102 case "out":
103 this.ExtractContainersPath = parser.GetNextArgumentAsDirectoryOrError(argument);
104 return true;
105 }
106 }
107 else if (String.IsNullOrEmpty(this.InputPath))
108 {
109 this.InputPath = argument;
110 return true;
111 }
112
113 return false;
114 }
115 }
116 }