in DbgShell/CommandLineParameterParser.cs [272:694]
private void ParseHelper(string[] args)
{
Util.Assert(args != null, "Argument 'args' to ParseHelper should never be null");
bool noexitSeen = false;
for (int i = 0; i < args.Length; ++i)
{
// Invariant culture used because command-line parameters are not localized.
string switchKey = args[i].Trim().ToLowerInvariant();
if (String.IsNullOrEmpty(switchKey))
{
continue;
}
if (!SpecialCharacters.IsDash(switchKey[0]) && switchKey[0] != '/')
{
// then its a command
--i;
ParseCommand(args, ref i, noexitSeen, false);
break;
}
// chop off the first character so that we're agnostic wrt specifying / or -
// in front of the switch name.
switchKey = switchKey.Substring(1);
// chop off the second dash so we're agnostic wrt specifying - or --
if (!String.IsNullOrEmpty(switchKey) && SpecialCharacters.IsDash(switchKey[0]))
{
switchKey = switchKey.Substring(1);
}
if (MatchSwitch(switchKey, "help", "h") || MatchSwitch(switchKey, "?", "?"))
{
showHelp = true;
abortStartup = true;
}
else if (MatchSwitch(switchKey, "noexit", "noe"))
{
noExit = true;
noexitSeen = true;
}
// else if (MatchSwitch(switchKey, "importsystemmodules", "imp"))
// {
// importSystemModules = true;
// }
// else if (MatchSwitch(switchKey, "showinitialprompt", "show"))
// {
// showInitialPrompt = true;
// }
else if (MatchSwitch(switchKey, "noprofile", "nop"))
{
skipUserInit = true;
}
else if (MatchSwitch(switchKey, "nologo", "nol"))
{
showBanner = false;
}
else if (MatchSwitch(switchKey, "noninteractive", "noni"))
{
noInteractive = true;
// We use RunspaceConfiguration instead of InitialSessionState. I
// don't know if there is a WarmUpTabCompletionOnIdle equivalent with
// that.
// if (ColorConsoleHost.DefaultInitialSessionState != null)
// {
// // TODO: [danthom] This would be nice to have. We could hack it with reflection.
// ColorConsoleHost.DefaultInitialSessionState.WarmUpTabCompletionOnIdle = false;
// }
}
// else if (MatchSwitch(switchKey, "servermode", "s"))
// {
// serverMode = true;
// }
else if (MatchSwitch(switchKey, "command", "c"))
{
if (!ParseCommand(args, ref i, noexitSeen, false))
{
break;
}
}
else if (MatchSwitch(switchKey, "windowstyle", "w"))
{
++i;
if (i >= args.Length)
{
ui.WriteErrorLine(
//CommandLineParameterParserStrings.MissingWindowStyleArgument);
"Missing WindowStyle argument." );
showHelp = false;
showBanner = false;
abortStartup = true;
exitCode = ExitCodeBadCommandLineParameter;
break;
}
try
{
ProcessWindowStyle style = (ProcessWindowStyle)LanguagePrimitives.ConvertTo(
args[i], typeof(ProcessWindowStyle), CultureInfo.InvariantCulture);
ConsoleControl.SetConsoleMode(style);
}
catch (PSInvalidCastException e)
{
ui.WriteErrorLine(string.Format(
CultureInfo.CurrentCulture,
//CommandLineParameterParserStrings.InvalidWindowStyleArgument,
"Bad WindowStyle argument.",
args[i], e.Message));
showHelp = false;
showBanner = false;
abortStartup = true;
exitCode = ExitCodeBadCommandLineParameter;
break;
}
}
else if (MatchSwitch(switchKey, "file", "f"))
{
// Process file execution. We don't need to worry about checking -command
// since if -command comes before -file, -file will be treated as part
// of the script to evaluate. If -file comes before -command, it will
// treat -command as an argument to the script...
++i;
if (i >= args.Length)
{
ui.WriteErrorLine(
//CommandLineParameterParserStrings.MissingFileArgument);
"Missing file argument." );
showHelp = true;
abortStartup = true;
exitCode = ExitCodeBadCommandLineParameter;
break;
}
// Don't show the startup banner unless -noexit has been specified.
if (!noexitSeen)
showBanner = false;
// Exit on script completion unless -noexit was specified...
if (!noexitSeen)
noExit = false;
// Process interactive input...
if (args[i] == "-")
{
// the arg to -file is -, which is secret code for "read the commands from stdin with prompts"
readFromStdin = true;
noPrompt = false;
}
else
{
// We need to get the full path to the script because it will be
// executed after the profiles are run and they may change the current
// directory.
string exceptionMessage = null;
// try
// {
Exception e = Util.TryIO( () => file = Path.GetFullPath( args[ i ] ) );
// }
// catch (Exception e)
// {
// // Catch all exceptions - we're just going to exit anyway so there's
// // no issue of the system begin destablized. We'll still
// // Watson on "severe" exceptions to get the reports.
// ColorConsoleHost.CheckForSevereException(e);
if( null != e )
exceptionMessage = e.Message;
// }
if (exceptionMessage != null)
{
ui.WriteErrorLine(string.Format(
CultureInfo.CurrentCulture,
//CommandLineParameterParserStrings.InvalidFileArgument,
"Invalid file argument.",
args[i], exceptionMessage));
showHelp = false;
abortStartup = true;
exitCode = ExitCodeBadCommandLineParameter;
break;
}
if (!Path.GetExtension(file).Equals(".ps1", StringComparison.OrdinalIgnoreCase))
{
ui.WriteErrorLine(string.Format(
CultureInfo.CurrentCulture,
//CommandLineParameterParserStrings.InvalidFileArgumentExtension,
"Invalid file argument extension.",
args[i]));
showHelp = false;
abortStartup = true;
exitCode = ExitCodeBadCommandLineParameter;
break;
}
if (!System.IO.File.Exists(file))
{
ui.WriteErrorLine(string.Format(
CultureInfo.CurrentCulture,
//CommandLineParameterParserStrings.ArgumentFileDoesNotExist,
"File argument does not exist.",
args[i]));
showHelp = false;
abortStartup = true;
exitCode = ExitCodeBadCommandLineParameter;
break;
}
i++;
Regex argPattern = new Regex(@"^.\w+\:", RegexOptions.CultureInvariant);
string pendingParameter = null;
// Accumulate the arguments to this script...
while (i < args.Length)
{
string arg = args[i];
// If there was a pending parameter, add a named parameter
// using the pending parameter and current argument
if (pendingParameter != null)
{
collectedArgs.Add(new CommandParameter(pendingParameter, arg));
pendingParameter = null;
}
else if (!string.IsNullOrEmpty(arg) && SpecialCharacters.IsDash(arg[0]))
{
Match m = argPattern.Match(arg);
if (m.Success)
{
int offset = arg.IndexOf(':');
if (offset == arg.Length - 1)
{
pendingParameter = arg.TrimEnd(':');
}
else
{
collectedArgs.Add(new CommandParameter(arg.Substring(0, offset), arg.Substring(offset + 1)));
}
}
else
{
collectedArgs.Add(new CommandParameter(arg));
}
}
else
{
collectedArgs.Add(new CommandParameter(null, arg));
}
++i;
}
}
break;
}
#if DEBUG
// // this option is useful when debugging ConsoleHost remotely using VS remote debugging, as you can only
// // attach to an already running process with that debugger.
// else if (MatchSwitch(switchKey, "wait", "w"))
// {
// // This does not need to be localized: its chk only
// ui.WriteToConsole("Waiting - type enter to continue:", false);
// ui.ReadLine();
// }
// // this option is useful for testing the initial InitialSessionState experience
// else if (MatchSwitch(switchKey, "iss", "iss"))
// {
// // Just toss this option, it was processed earlier...
// }
// // this option is useful for testing the initial InitialSessionState experience
// // this is independent of the normal wait switch because configuration processing
// // happens so early in the cycle...
// else if (MatchSwitch(switchKey, "isswait", "isswait"))
// {
// // Just toss this option, it was processed earlier...
// }
// else if (MatchSwitch(switchKey, "modules", "mod"))
// {
// if (ColorConsoleHost.DefaultInitialSessionState == null)
// {
// ui.WriteErrorLine("The -module option can only be specified with the -iss option.");
// showHelp = true;
// abortStartup = true;
// exitCode = ExitCodeBadCommandLineParameter;
// break;
// }
// ++i;
// int moduleCount = 0;
// // Accumulate the arguments to this script...
// while (i < args.Length)
// {
// string arg = args[i];
// if (!string.IsNullOrEmpty(arg) && SpecialCharacters.IsDash(arg[0]))
// {
// break;
// }
// else
// {
// ColorConsoleHost.DefaultInitialSessionState.ImportPSModule(new string[] { arg });
// moduleCount++;
// }
// ++i;
// }
// if (moduleCount < 1)
// {
// ui.WriteErrorLine("No modules specified for -module option");
// }
// }
#endif
// else if (MatchSwitch(switchKey, "outputformat", "o") || MatchSwitch(switchKey, "of", "o"))
// {
// ParseFormat(args, ref i, ref outFormat, CommandLineParameterParserStrings.MissingOutputFormatParameter);
// }
// else if (MatchSwitch(switchKey, "inputformat", "i") || MatchSwitch(switchKey, "if", "i"))
// {
// ParseFormat(args, ref i, ref inFormat, CommandLineParameterParserStrings.MissingInputFormatParameter);
// }
// else if (MatchSwitch(switchKey, "executionpolicy", "ex") || MatchSwitch(switchKey, "ep", "ep"))
// {
// ParseExecutionPolicy(args, ref i, ref executionPolicy, CommandLineParameterParserStrings.MissingExecutionPolicyParameter);
// }
else if (MatchSwitch(switchKey, "encodedcommand", "e") || MatchSwitch(switchKey, "ec", "e"))
{
wasCommandEncoded = true;
if (!ParseCommand(args, ref i, noexitSeen, true))
{
break;
}
}
// else if (MatchSwitch(switchKey, "encodedarguments", "encodeda") || MatchSwitch(switchKey, "ea", "ea"))
// {
// if (!CollectArgs(args, ref i))
// {
// break;
// }
// }
// else if (MatchSwitch(switchKey, "sta", "s"))
// {
// if (staMode.HasValue)
// {
// // -sta and -mta are mutually exclusive.
// ui.WriteErrorLine(
// CommandLineParameterParserStrings.MtaStaMutuallyExclusive);
// showHelp = false;
// showBanner = false;
// abortStartup = true;
// exitCode = ExitCodeBadCommandLineParameter;
// break;
// }
// staMode = true;
// }
// // Win8: 182409 PowerShell 3.0 should run in STA mode by default..so, consequently adding the switch -mta.
// // Not deleting -sta for backward compatability reasons
// else if (MatchSwitch(switchKey, "mta", "mta"))
// {
// if (staMode.HasValue)
// {
// // -sta and -mta are mutually exclusive.
// ui.WriteErrorLine(
// CommandLineParameterParserStrings.MtaStaMutuallyExclusive);
// showHelp = false;
// showBanner = false;
// abortStartup = true;
// exitCode = ExitCodeBadCommandLineParameter;
// break;
// }
// staMode = false;
// }
else if (MatchSwitch(switchKey, "z", "z"))
{
++i;
if (i >= args.Length)
{
ui.WriteErrorLine( "Missing dump file argument." );
showHelp = false;
showBanner = false;
abortStartup = true;
exitCode = ExitCodeBadCommandLineParameter;
break;
}
DumpFile = args[ i ];
}
else
{
// The first parameter we fail to recognize marks the beginning of the command string.
--i;
if (!ParseCommand(args, ref i, noexitSeen, false))
{
break;
}
}
}
if (showHelp)
{
ShowHelp();
}
if (showBanner && !showHelp)
{
ShowBanner();
}
Util.Assert(
((exitCode == ExitCodeBadCommandLineParameter) && abortStartup)
|| (exitCode == ExitCodeSuccess),
"if exit code is failure, then abortstartup should be true");
}