main
cs 147 lines 5.63 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.WindowsInstaller.CommandLine
4 {
5 using System;
6 using System.Collections.Generic;
7 using System.IO;
8 using System.Threading;
9 using System.Threading.Tasks;
10 using WixToolset.Core.WindowsInstaller.Validate;
11 using WixToolset.Data;
12 using WixToolset.Data.WindowsInstaller;
13 using WixToolset.Extensibility.Data;
14 using WixToolset.Extensibility.Services;
15
16 internal class ValidateSubcommand : WindowsInstallerSubcommandBase
17 {
18 public ValidateSubcommand(IServiceProvider serviceProvider)
19 {
20 this.Messaging = serviceProvider.GetService<IMessaging>();
21 this.FileSystem = serviceProvider.GetService<IFileSystem>();
22 }
23
24 private IMessaging Messaging { get; }
25
26 private IFileSystem FileSystem { get; }
27
28 private string DatabasePath { get; set; }
29
30 private string WixpdbPath { get; set; }
31
32 private string IntermediateFolder { get; set; }
33
34 private List<string> CubeFiles { get; } = new List<string>();
35
36 private List<string> Ices { get; } = new List<string>();
37
38 private List<string> SuppressIces { get; } = new List<string>();
39
40 public override CommandLineHelp GetCommandLineHelp()
41 {
42 return new CommandLineHelp("Validates MSI database using standard or custom ICEs.", "msi validate [options] {inputfile.msi|inputfile.msm}", new[]
43 {
44 new CommandLineHelpSwitch("-cub", "Optional path to a custom validation .CUBe file."),
45 new CommandLineHelpSwitch("-ice", "Validates only with the specified ICE. May be provided multiple times."),
46 new CommandLineHelpSwitch("-intermediateFolder", "Optional working folder. If not specified %TMP% will be used."),
47 new CommandLineHelpSwitch("-pdb", "Optional path to .wixpdb for source line information. If not provided, will check next to the input file."),
48 new CommandLineHelpSwitch("-sice", "Suppresses an ICE validator."),
49 });
50 }
51
52 public override Task<int> ExecuteAsync(CancellationToken cancellationToken)
53 {
54 WindowsInstallerData data = null;
55
56 if (String.IsNullOrEmpty(this.DatabasePath))
57 {
58 this.Messaging.Write(ErrorMessages.FilePathRequired("input MSI or MSM database"));
59 }
60 else if (this.CubeFiles.Count == 0)
61 {
62 var ext = Path.GetExtension(this.DatabasePath);
63 switch (ext.ToLowerInvariant())
64 {
65 case ".msi":
66 this.CubeFiles.Add("darice.cub");
67 break;
68
69 case ".msm":
70 this.CubeFiles.Add("mergemod.cub");
71 break;
72
73 default:
74 this.Messaging.Write(WindowsInstallerBackendErrors.UnknownValidationTargetFileExtension(ext));
75 break;
76 }
77 }
78
79 if (!this.Messaging.EncounteredError)
80 {
81 if (String.IsNullOrEmpty(this.WixpdbPath))
82 {
83 this.WixpdbPath = Path.ChangeExtension(this.DatabasePath, ".wixpdb");
84 }
85
86 if (String.IsNullOrEmpty(this.IntermediateFolder))
87 {
88 this.IntermediateFolder = Path.GetTempPath();
89 }
90
91 if (File.Exists(this.WixpdbPath))
92 {
93 try
94 {
95 data = WindowsInstallerData.Load(this.WixpdbPath);
96 }
97 catch (ArgumentOutOfRangeException)
98 {
99 this.Messaging.Write(WindowsInstallerBackendErrors.InvalidWindowsInstallerWixpdbForValidation(this.WixpdbPath));
100 }
101 }
102
103 var command = new ValidateDatabaseCommand(this.Messaging, this.FileSystem, this.IntermediateFolder, this.DatabasePath, data, this.CubeFiles, this.Ices, this.SuppressIces);
104 command.Execute();
105 }
106
107 return Task.FromResult(this.Messaging.LastErrorNumber);
108 }
109
110 public override bool TryParseArgument(ICommandLineParser parser, string argument)
111 {
112 if (parser.IsSwitch(argument))
113 {
114 var parameter = argument.Substring(1);
115 switch (parameter.ToLowerInvariant())
116 {
117 case "cub":
118 parser.GetNextArgumentOrError(argument, this.CubeFiles);
119 return true;
120
121 case "ice":
122 parser.GetNextArgumentOrError(argument, this.Ices);
123 return true;
124
125 case "intermediatefolder":
126 this.IntermediateFolder = parser.GetNextArgumentAsDirectoryOrError(argument);
127 return true;
128
129 case "pdb":
130 this.WixpdbPath = parser.GetNextArgumentAsFilePathOrError(argument, "wixpdb path");
131 return true;
132
133 case "sice":
134 parser.GetNextArgumentOrError(argument, this.SuppressIces);
135 return true;
136 }
137 }
138 else if (String.IsNullOrEmpty(this.DatabasePath))
139 {
140 this.DatabasePath = argument;
141 return true;
142 }
143
144 return false;
145 }
146 }
147 }