diff options
Diffstat (limited to '')
-rw-r--r-- | src/WixToolset.Mba.Core/BootstrapperCommand.cs | 107 |
1 files changed, 107 insertions, 0 deletions
diff --git a/src/WixToolset.Mba.Core/BootstrapperCommand.cs b/src/WixToolset.Mba.Core/BootstrapperCommand.cs new file mode 100644 index 00000000..bbd10e1d --- /dev/null +++ b/src/WixToolset.Mba.Core/BootstrapperCommand.cs | |||
@@ -0,0 +1,107 @@ | |||
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.BootstrapperCore | ||
4 | { | ||
5 | using System; | ||
6 | using System.ComponentModel; | ||
7 | using System.Runtime.InteropServices; | ||
8 | |||
9 | public sealed class BootstrapperCommand : IBootstrapperCommand | ||
10 | { | ||
11 | private readonly string commandLine; | ||
12 | |||
13 | public BootstrapperCommand( | ||
14 | LaunchAction action, | ||
15 | Display display, | ||
16 | Restart restart, | ||
17 | string commandLine, | ||
18 | int cmdShow, | ||
19 | ResumeType resume, | ||
20 | IntPtr splashScreen, | ||
21 | RelationType relation, | ||
22 | bool passthrough, | ||
23 | string layoutDirectory) | ||
24 | { | ||
25 | this.Action = action; | ||
26 | this.Display = display; | ||
27 | this.Restart = restart; | ||
28 | this.commandLine = commandLine; | ||
29 | this.CmdShow = cmdShow; | ||
30 | this.Resume = resume; | ||
31 | this.SplashScreen = splashScreen; | ||
32 | this.Relation = relation; | ||
33 | this.Passthrough = passthrough; | ||
34 | this.LayoutDirectory = layoutDirectory; | ||
35 | } | ||
36 | |||
37 | public LaunchAction Action { get; } | ||
38 | |||
39 | public Display Display { get; } | ||
40 | |||
41 | public Restart Restart { get; } | ||
42 | |||
43 | public string[] CommandLineArgs => GetCommandLineArgs(this.commandLine); | ||
44 | |||
45 | public int CmdShow { get; } | ||
46 | |||
47 | public ResumeType Resume { get; } | ||
48 | |||
49 | public IntPtr SplashScreen { get; } | ||
50 | |||
51 | public RelationType Relation { get; } | ||
52 | |||
53 | public bool Passthrough { get; } | ||
54 | |||
55 | public string LayoutDirectory { get; } | ||
56 | |||
57 | /// <summary> | ||
58 | /// Gets the command line arguments as a string array. | ||
59 | /// </summary> | ||
60 | /// <returns> | ||
61 | /// Array of command line arguments. | ||
62 | /// </returns> | ||
63 | /// <exception type="Win32Exception">The command line could not be parsed into an array.</exception> | ||
64 | /// <remarks> | ||
65 | /// This method uses the same parsing as the operating system which handles quotes and spaces correctly. | ||
66 | /// </remarks> | ||
67 | public static string[] GetCommandLineArgs(string commandLine) | ||
68 | { | ||
69 | if (null == commandLine) | ||
70 | { | ||
71 | return new string[0]; | ||
72 | } | ||
73 | |||
74 | // Parse the filtered command line arguments into a native array. | ||
75 | int argc = 0; | ||
76 | |||
77 | // CommandLineToArgvW tries to treat the first argument as the path to the process, | ||
78 | // which fails pretty miserably if your first argument is something like | ||
79 | // FOO="C:\Program Files\My Company". So give it something harmless to play with. | ||
80 | IntPtr argv = NativeMethods.CommandLineToArgvW("ignored " + commandLine, out argc); | ||
81 | |||
82 | if (IntPtr.Zero == argv) | ||
83 | { | ||
84 | // Throw an exception with the last error. | ||
85 | throw new Win32Exception(); | ||
86 | } | ||
87 | |||
88 | // Marshal each native array pointer to a managed string. | ||
89 | try | ||
90 | { | ||
91 | // Skip "ignored" argument/hack. | ||
92 | string[] args = new string[argc - 1]; | ||
93 | for (int i = 1; i < argc; ++i) | ||
94 | { | ||
95 | IntPtr argvi = Marshal.ReadIntPtr(argv, i * IntPtr.Size); | ||
96 | args[i - 1] = Marshal.PtrToStringUni(argvi); | ||
97 | } | ||
98 | |||
99 | return args; | ||
100 | } | ||
101 | finally | ||
102 | { | ||
103 | NativeMethods.LocalFree(argv); | ||
104 | } | ||
105 | } | ||
106 | } | ||
107 | } | ||