mirror of
https://github.com/aphrody-labs/PowerShell.git
synced 2026-10-17 04:36:39 +00:00
Redo command-line parsing, add -noninteractive and -encodedcommand options
This commit is contained in:
1 parent
7048b5774c
commit
d1edcb38bd
1 file changed
+115
-38
@@ -14,6 +14,30 @@ namespace Microsoft.PowerShell.CoreConsoleHost
|
||||
|
||||
public static class Program
|
||||
{
|
||||
private enum Options {Help, File, Command, NoProfile, NonInteractive, EncodedCommand, Invalid};
|
||||
private class CommandOptions
|
||||
{
|
||||
public Options opt;
|
||||
public string optString;
|
||||
|
||||
public CommandOptions(Options o, string s)
|
||||
{
|
||||
opt = o;
|
||||
optString = s;
|
||||
}
|
||||
}
|
||||
|
||||
private static CommandOptions[] commandOptions = new CommandOptions[]
|
||||
{
|
||||
new CommandOptions(Options.Help, "help"),
|
||||
new CommandOptions(Options.Help, "?"),
|
||||
new CommandOptions(Options.File, "file"),
|
||||
new CommandOptions(Options.Command, "command"),
|
||||
new CommandOptions(Options.NoProfile, "noprofile"),
|
||||
new CommandOptions(Options.NonInteractive, "noninteractive"),
|
||||
new CommandOptions(Options.EncodedCommand, "encodedcommand")
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Creates and initiates the listener instance.
|
||||
/// </summary>
|
||||
@@ -25,6 +49,7 @@ namespace Microsoft.PowerShell.CoreConsoleHost
|
||||
// here eliminates the need for a custom native host.
|
||||
PowerShellAssemblyLoadContextInitializer.SetPowerShellAssemblyLoadContext(string.Empty);
|
||||
|
||||
|
||||
// Argument parsing
|
||||
string initialScript = null;
|
||||
bool loadProfiles = true;
|
||||
@@ -37,15 +62,33 @@ namespace Microsoft.PowerShell.CoreConsoleHost
|
||||
bool hasNext = (i+1) < args.Length;
|
||||
string nextArg = hasNext ? args[i+1] : string.Empty;
|
||||
|
||||
// --help was specified
|
||||
if (arg == "--help" || arg == "-h")
|
||||
// options start with "-" or "--"
|
||||
|
||||
string option;
|
||||
if (arg.StartsWith("-"))
|
||||
{
|
||||
Console.WriteLine(@"
|
||||
usage: powershell[.exe] [ (--help | -h) ]
|
||||
if (arg.StartsWith("--"))
|
||||
{
|
||||
option = arg.Remove(0, 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
option = arg.Remove(0, 1);
|
||||
}
|
||||
|
||||
Options bestOption = FindOption(option);
|
||||
|
||||
switch (bestOption)
|
||||
{
|
||||
case Options.Help:
|
||||
Console.WriteLine(@"
|
||||
usage: powershell[.exe] [ (--help | -h | -?) ]
|
||||
[ (--file | -f) <filePath> ]
|
||||
[ <script>.ps1 ]
|
||||
[ (--command | -c) <string> ]
|
||||
[ --noprofile ]
|
||||
[ --noprofile | -nop ]
|
||||
[ --noninteractive | -non ]
|
||||
[ (--encodedcommand | -e) <bas64Command> ]
|
||||
|
||||
SYNOPSIS
|
||||
|
||||
@@ -65,46 +108,63 @@ OPTIONS
|
||||
(--command | -c) <string>
|
||||
Will execute given string as a PowerShell script.
|
||||
|
||||
--noprofile
|
||||
(--noprofile | -nop)
|
||||
Disables parsing of PowerShell profiles.
|
||||
|
||||
(--help | -h)
|
||||
(--help | -h | -?)
|
||||
Prints this text.
|
||||
|
||||
(--noninteractive | -non)
|
||||
Does not present an interactive prompt to the user.
|
||||
|
||||
(--encodedcommand | -e) <base64Command>
|
||||
Accepts a base-64-encoded string version of a command.
|
||||
");
|
||||
return;
|
||||
}
|
||||
else if (arg == "--noprofile")
|
||||
{
|
||||
loadProfiles = false;
|
||||
}
|
||||
// lone argument is a script
|
||||
else if (!hasNext && arg.EndsWith(".ps1"))
|
||||
{
|
||||
initialScript = Path.GetFullPath(arg);
|
||||
}
|
||||
// lone argument is an inline script
|
||||
else if (!hasNext)
|
||||
{
|
||||
initialScript = arg;
|
||||
}
|
||||
// --file <filePath> was specified
|
||||
else if (hasNext && (arg == "--file" || arg == "-f"))
|
||||
{
|
||||
initialScript = Path.GetFullPath(nextArg);
|
||||
++i;
|
||||
}
|
||||
// --command <string> was specified
|
||||
else if (hasNext && (arg == "--command" || arg == "-c"))
|
||||
{
|
||||
if (nextArg == "-")
|
||||
{
|
||||
initialScript = "\"TODO: read stdin using Console.OpenStandardInput\"";
|
||||
return;
|
||||
|
||||
case Options.NoProfile:
|
||||
loadProfiles = false;
|
||||
break;
|
||||
case Options.File:
|
||||
initialScript = Path.GetFullPath(nextArg);
|
||||
++i;
|
||||
break;
|
||||
case Options.Command:
|
||||
if (nextArg == "-")
|
||||
{
|
||||
initialScript = "\"TODO: read stdin using Console.OpenStandardInput\"";
|
||||
}
|
||||
else
|
||||
{
|
||||
initialScript = nextArg;
|
||||
}
|
||||
++i;
|
||||
break;
|
||||
case Options.NonInteractive:
|
||||
// TODO, figure out what this option does exactly
|
||||
break;
|
||||
case Options.EncodedCommand:
|
||||
byte[] data = Convert.FromBase64String(nextArg);
|
||||
initialScript = Encoding.UTF8.GetString(data);
|
||||
++i;
|
||||
break;
|
||||
default:
|
||||
Console.WriteLine("Invalid command-line option: {0}. Use '-help' option to get a list of valid options.");
|
||||
return;
|
||||
}
|
||||
else
|
||||
}
|
||||
else // not an option parameter
|
||||
{
|
||||
// lone argument is a script
|
||||
if (!hasNext && arg.EndsWith(".ps1"))
|
||||
{
|
||||
initialScript = nextArg;
|
||||
initialScript = Path.GetFullPath(arg);
|
||||
}
|
||||
// lone argument is an inline script
|
||||
else if (!hasNext)
|
||||
{
|
||||
initialScript = arg;
|
||||
}
|
||||
++i;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -129,6 +189,23 @@ OPTIONS
|
||||
// The exit code is set in the host by the MyHost.SetShouldExit() method.
|
||||
System.Environment.Exit(listener.ExitCode);
|
||||
}
|
||||
|
||||
private static Options FindOption(string option)
|
||||
{
|
||||
int matches = 0;
|
||||
int index = -1;
|
||||
|
||||
for (int i=0; i<commandOptions.Length; ++i)
|
||||
{
|
||||
if (commandOptions[i].optString.StartsWith(option, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
matches++;
|
||||
index = i;
|
||||
}
|
||||
}
|
||||
|
||||
return (matches == 1) ? commandOptions[index].opt : Options.Invalid;
|
||||
}
|
||||
}
|
||||
|
||||
internal class Listener
|
||||
|
||||
Reference in new issue
Block a user