aboutsummaryrefslogtreecommitdiff
path: root/src/api/burn/WixToolset.Mba.Core/BootstrapperCommand.cs
diff options
context:
space:
mode:
authorRob Mensching <rob@firegiant.com>2024-03-06 14:48:10 -0800
committerRob Mensching <rob@firegiant.com>2024-03-07 10:55:57 -0800
commit3d2d46f62fc01e2653d0251ad9703090574e7c41 (patch)
treeffdf7dce6c646f38b5e3ad8325c2ce78ca891a1a /src/api/burn/WixToolset.Mba.Core/BootstrapperCommand.cs
parenta8504dc4eb1c2d09965b0858699ac737336ef3c1 (diff)
downloadwix-3d2d46f62fc01e2653d0251ad9703090574e7c41.tar.gz
wix-3d2d46f62fc01e2653d0251ad9703090574e7c41.tar.bz2
wix-3d2d46f62fc01e2653d0251ad9703090574e7c41.zip
Better .nupkg names
Diffstat (limited to 'src/api/burn/WixToolset.Mba.Core/BootstrapperCommand.cs')
-rw-r--r--src/api/burn/WixToolset.Mba.Core/BootstrapperCommand.cs239
1 files changed, 0 insertions, 239 deletions
diff --git a/src/api/burn/WixToolset.Mba.Core/BootstrapperCommand.cs b/src/api/burn/WixToolset.Mba.Core/BootstrapperCommand.cs
deleted file mode 100644
index b96a8f95..00000000
--- a/src/api/burn/WixToolset.Mba.Core/BootstrapperCommand.cs
+++ /dev/null
@@ -1,239 +0,0 @@
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
3namespace WixToolset.Mba.Core
4{
5 using System;
6 using System.CodeDom.Compiler;
7 using System.Collections.Generic;
8 using System.ComponentModel;
9 using System.Runtime.InteropServices;
10
11 /// <summary>
12 /// Command-line provided to the bootstrapper application.
13 /// </summary>
14 [Serializable]
15 [StructLayout(LayoutKind.Sequential)]
16 [GeneratedCodeAttribute("WixToolset.Bootstrapper.InteropCodeGenerator", "1.0.0.0")]
17 public struct Command
18 {
19 // Strings must be declared as pointers so that Marshaling doesn't free them.
20 [MarshalAs(UnmanagedType.I4)] internal int cbSize;
21 [MarshalAs(UnmanagedType.U4)] private readonly LaunchAction action;
22 [MarshalAs(UnmanagedType.U4)] private readonly Display display;
23 private readonly IntPtr wzCommandLine;
24 [MarshalAs(UnmanagedType.I4)] private readonly int nCmdShow;
25 [MarshalAs(UnmanagedType.U4)] private readonly ResumeType resume;
26 private readonly IntPtr hwndSplashScreen;
27 [MarshalAs(UnmanagedType.I4)] private readonly RelationType relation;
28 [MarshalAs(UnmanagedType.Bool)] private readonly bool passthrough;
29 private readonly IntPtr wzLayoutDirectory;
30 private readonly IntPtr wzBootstrapperWorkingFolder;
31 private readonly IntPtr wzBootstrapperApplicationDataPath;
32
33 /// <summary>
34 /// Gets the IBootstrapperCommand for this Command.
35 /// </summary>
36 /// <returns>IBootstrapperCommand</returns>
37 public IBootstrapperCommand GetBootstrapperCommand()
38 {
39 return new BootstrapperCommand(
40 this.action,
41 this.display,
42 Marshal.PtrToStringUni(this.wzCommandLine),
43 this.nCmdShow,
44 this.resume,
45 this.hwndSplashScreen,
46 this.relation,
47 this.passthrough,
48 Marshal.PtrToStringUni(this.wzLayoutDirectory),
49 Marshal.PtrToStringUni(this.wzBootstrapperWorkingFolder),
50 Marshal.PtrToStringUni(this.wzBootstrapperApplicationDataPath));
51 }
52 }
53
54 /// <summary>
55 /// Default implementation of <see cref="IBootstrapperCommand"/>.
56 /// </summary>
57 public sealed class BootstrapperCommand : IBootstrapperCommand
58 {
59 /// <summary>
60 /// See <see cref="IBootstrapperCommand"/>.
61 /// </summary>
62 public BootstrapperCommand(
63 LaunchAction action,
64 Display display,
65 string commandLine,
66 int cmdShow,
67 ResumeType resume,
68 IntPtr splashScreen,
69 RelationType relation,
70 bool passthrough,
71 string layoutDirectory,
72 string bootstrapperWorkingFolder,
73 string bootstrapperApplicationDataPath)
74 {
75 this.Action = action;
76 this.Display = display;
77 this.CommandLine = commandLine;
78 this.CmdShow = cmdShow;
79 this.Resume = resume;
80 this.SplashScreen = splashScreen;
81 this.Relation = relation;
82 this.Passthrough = passthrough;
83 this.LayoutDirectory = layoutDirectory;
84 this.BootstrapperWorkingFolder = bootstrapperWorkingFolder;
85 this.BootstrapperApplicationDataPath = bootstrapperApplicationDataPath;
86 }
87
88 /// <inheritdoc/>
89 public LaunchAction Action { get; }
90
91 /// <inheritdoc/>
92 public Display Display { get; }
93
94 /// <inheritdoc/>
95 public string CommandLine { get; }
96
97 /// <inheritdoc/>
98 public int CmdShow { get; }
99
100 /// <inheritdoc/>
101 public ResumeType Resume { get; }
102
103 /// <inheritdoc/>
104 public IntPtr SplashScreen { get; }
105
106 /// <inheritdoc/>
107 public RelationType Relation { get; }
108
109 /// <inheritdoc/>
110 public bool Passthrough { get; }
111
112 /// <inheritdoc/>
113 public string LayoutDirectory { get; }
114
115 /// <inheritdoc/>
116 public string BootstrapperWorkingFolder { get; }
117
118 /// <inheritdoc/>
119 public string BootstrapperApplicationDataPath { get; }
120
121 /// <inheritdoc/>
122 public IMbaCommand ParseCommandLine()
123 {
124 var args = ParseCommandLineToArgs(this.CommandLine);
125 var unknownArgs = new List<string>();
126 var variables = new List<KeyValuePair<string, string>>();
127 var restart = Restart.Unknown;
128
129 foreach (var arg in args)
130 {
131 var unknownArg = false;
132
133 if (arg[0] == '-' || arg[0] == '/')
134 {
135 var parameter = arg.Substring(1).ToLowerInvariant();
136 switch (parameter)
137 {
138 case "norestart":
139 if (restart == Restart.Unknown)
140 {
141 restart = Restart.Never;
142 }
143 break;
144 case "forcerestart":
145 if (restart == Restart.Unknown)
146 {
147 restart = Restart.Always;
148 }
149 break;
150 default:
151 unknownArg = true;
152 break;
153 }
154 }
155 else
156 {
157 var index = arg.IndexOf('=');
158 if (index == -1)
159 {
160 unknownArg = true;
161 }
162 else
163 {
164 var name = arg.Substring(0, index);
165 var value = arg.Substring(index + 1);
166 variables.Add(new KeyValuePair<string, string>(name, value));
167 }
168 }
169
170 if (unknownArg)
171 {
172 unknownArgs.Add(arg);
173 }
174 }
175
176 if (restart == Restart.Unknown)
177 {
178 restart = this.Display < Display.Full ? Restart.Automatic : Restart.Prompt;
179 }
180
181 return new MbaCommand
182 {
183 Restart = restart,
184 UnknownCommandLineArgs = unknownArgs.ToArray(),
185 Variables = variables.ToArray(),
186 };
187 }
188
189 /// <summary>
190 /// Gets the command line arguments as a string array.
191 /// </summary>
192 /// <returns>
193 /// Array of command line arguments.
194 /// </returns>
195 /// <exception type="Win32Exception">The command line could not be parsed into an array.</exception>
196 /// <remarks>
197 /// This method uses the same parsing as the operating system which handles quotes and spaces correctly.
198 /// </remarks>
199 public static string[] ParseCommandLineToArgs(string commandLine)
200 {
201 if (null == commandLine)
202 {
203 return new string[0];
204 }
205
206 // Parse the filtered command line arguments into a native array.
207 int argc = 0;
208
209 // CommandLineToArgvW tries to treat the first argument as the path to the process,
210 // which fails pretty miserably if your first argument is something like
211 // FOO="C:\Program Files\My Company". So give it something harmless to play with.
212 IntPtr argv = NativeMethods.CommandLineToArgvW("ignored " + commandLine, out argc);
213
214 if (IntPtr.Zero == argv)
215 {
216 // Throw an exception with the last error.
217 throw new Win32Exception();
218 }
219
220 // Marshal each native array pointer to a managed string.
221 try
222 {
223 // Skip "ignored" argument/hack.
224 string[] args = new string[argc - 1];
225 for (int i = 1; i < argc; ++i)
226 {
227 IntPtr argvi = Marshal.ReadIntPtr(argv, i * IntPtr.Size);
228 args[i - 1] = Marshal.PtrToStringUni(argvi);
229 }
230
231 return args;
232 }
233 finally
234 {
235 NativeMethods.LocalFree(argv);
236 }
237 }
238 }
239}