-
Notifications
You must be signed in to change notification settings - Fork 4.9k
/
Copy pathEnvironment.GetCommandLineArgs.cs
132 lines (110 loc) · 5.54 KB
/
Environment.GetCommandLineArgs.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using Microsoft.DotNet.RemoteExecutor;
using Xunit;
namespace System.Tests
{
public class GetCommandLineArgs
{
public static IEnumerable<object[]> GetCommandLineArgs_TestData()
{
yield return new object[] { new string[] { "singleArg" } };
yield return new object[] { new string[] { "Arg1", "Arg2" } };
yield return new object[] { new string[] { "\"Arg With Quotes\"" } };
yield return new object[] { new string[] { "\"Arg1 With Quotes\"", "\"Arg2 With Quotes\"" } };
yield return new object[] { new string[] { "\"Arg1 With Quotes\"", "Arg2", "\"Arg3 With Quotes\"" } };
yield return new object[] { new string[] { "arg1", @"\\\\\" + "\"alpha", @"\" + "\"arg3" } };
}
[ConditionalTheory(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))]
[MemberData(nameof(GetCommandLineArgs_TestData))]
public void GetCommandLineArgs_Invoke_ReturnsExpected(string[] args)
{
switch (args.Length)
{
case 1:
RemoteExecutor.Invoke((arg) => CheckCommandLineArgs(new string[] { arg }), args[0]).Dispose();
break;
case 2:
RemoteExecutor.Invoke((arg1, arg2) => CheckCommandLineArgs(new string[] { arg1, arg2 }), args[0], args[1]).Dispose();
break;
case 3:
RemoteExecutor.Invoke((arg1, arg2, arg3) => CheckCommandLineArgs(new string[] { arg1, arg2, arg3 }), args[0], args[1], args[2]).Dispose();
break;
default:
Assert.Fail("Unexpected number of args passed to test");
break;
}
}
public static int CheckCommandLineArgs(string[] args)
{
string[] cmdLineArgs = Environment.GetCommandLineArgs();
Assert.InRange(cmdLineArgs.Length, 5, int.MaxValue); /*AppName, AssemblyName, TypeName, MethodName, ExceptionFile */
Assert.Contains(RemoteExecutor.Path, cmdLineArgs[0]); /*The host returns the fullName*/
Type t = typeof(GetCommandLineArgs);
MethodInfo mi = t.GetMethod("CheckCommandLineArgs");
Assembly a = t.GetTypeInfo().Assembly;
Assert.Equal(cmdLineArgs[1], a.FullName);
Assert.Contains(t.FullName, cmdLineArgs[2]);
Assert.Contains("GetCommandLineArgs_Invoke_ReturnsExpected", cmdLineArgs[3]);
// Check the arguments sent to the method.
Assert.Equal(args.Length, cmdLineArgs.Length - 5);
for (int i = 0; i < args.Length; i++)
{
Assert.Equal(args[i], cmdLineArgs[i + 5]);
}
return RemoteExecutor.SuccessExitCode;
}
[ConditionalFact(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))]
public void GetCommandLineArgs_Fallback_Returns()
{
if (PlatformDetection.IsNotMonoRuntime
&& PlatformDetection.IsNotNativeAot
&& PlatformDetection.IsWindows)
{
// Currently fallback command line is only implemented on Windows coreclr
RemoteExecutor.Invoke(CheckCommandLineArgsFallback).Dispose();
}
}
public static int CheckCommandLineArgsFallback()
{
string[] oldArgs = Environment.GetCommandLineArgs();
// Clear the command line args set for managed entry point
var field = typeof(Environment).GetField("s_commandLineArgs", BindingFlags.Static | BindingFlags.NonPublic);
Assert.NotNull(field);
field.SetValue(null, null);
string[] args = Environment.GetCommandLineArgs();
Assert.NotEmpty(args);
// The native command line should be superset of managed command line
foreach (string arg in oldArgs)
{
Assert.Contains(arg, args);
}
return RemoteExecutor.SuccessExitCode;
}
public static bool IsWindowsCoreCLRJit
=> PlatformDetection.IsWindows
&& PlatformDetection.IsNotMonoRuntime
&& PlatformDetection.IsNotNativeAot;
[ConditionalTheory(typeof(GetCommandLineArgs), nameof(IsWindowsCoreCLRJit))]
[InlineData(@"cmd ""abc"" d e", new[] { "cmd", "abc", "d", "e" })]
[InlineData(@"cmd a\\b d""e f""g h", new[] { "cmd", @"a\\b", "de fg", "h" })]
[InlineData(@"cmd a\\\""b c d", new[] { "cmd", @"a\""b", "c", "d" })]
[InlineData(@"cmd a\\\\""b c"" d e", new[] { "cmd", @"a\\b c", "d", "e" })]
[InlineData(@"cmd a""b"""" c d", new[] { "cmd", @"ab"" c d" })]
[InlineData(@"X:\No""t A"""" P""ath arg", new[] { @"X:\Not A Path", "arg" })]
[InlineData(@"""\\Some Server\cmd"" ""arg", new[] { @"\\Some Server\cmd", "arg" })]
public static unsafe void CheckCommandLineParser(string cmdLine, string[] args)
{
var method = typeof(Environment).GetMethod("SegmentCommandLine", BindingFlags.Static | BindingFlags.NonPublic);
Assert.NotNull(method);
var span = cmdLine.AsSpan(); // Workaround
fixed (char* p = span)
{
Assert.Equal(args, method.Invoke(null, new object[] { Pointer.Box(p, typeof(char*)) }));
}
}
}
}