/// <summary>
        /// Gets the word in a switch from the current argument or parses a file.
        /// For example -foo, /foo, or --foo would return 'foo'.
        /// </summary>
        /// <param name="args">
        /// The command line parameters to be processed.
        /// </param>
        /// <param name="argIndex">
        /// The index in args to the argument to process.
        /// </param>
        /// <param name="parser">
        /// Used to parse files in the args.  If not supplied, Files will not be parsed.
        /// </param>
        /// <param name="noexitSeen">
        /// Used during parsing files.
        /// </param>
        /// <returns>
        /// Returns a Tuple:
        /// The first value is a String called SwitchKey with the word in a switch from the current argument or null.
        /// The second value is a bool called ShouldBreak, indicating if the parsing look should break.
        /// </returns>
        private static (string SwitchKey, bool ShouldBreak) GetSwitchKey(string[] args, ref int argIndex, CommandLineParameterParser parser, ref bool noexitSeen)
        {
            string switchKey = args[argIndex].Trim().ToLowerInvariant();

            if (string.IsNullOrEmpty(switchKey))
            {
                return(SwitchKey : null, ShouldBreak : false);
            }

            if (!SpecialCharacters.IsDash(switchKey[0]) && switchKey[0] != '/')
            {
                // then its a file
                if (parser != null)
                {
                    --argIndex;
                    parser.ParseFile(args, ref argIndex, noexitSeen);
                }

                return(SwitchKey : null, ShouldBreak : true);
            }

            // 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);
            }

            return(SwitchKey : switchKey, ShouldBreak : false);
        }
        private bool ParseFile(string[] args, ref int i, bool noexitSeen)
        {
            // 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...

            bool TryGetBoolValue(string arg, out bool boolValue)
            {
                if (arg.Equals("$true", StringComparison.OrdinalIgnoreCase) || arg.Equals("true", StringComparison.OrdinalIgnoreCase))
                {
                    boolValue = true;
                    return(true);
                }
                else if (arg.Equals("$false", StringComparison.OrdinalIgnoreCase) || arg.Equals("false", StringComparison.OrdinalIgnoreCase))
                {
                    boolValue = false;
                    return(true);
                }
                boolValue = false;
                return(false);
            }

            ++i;
            if (i >= args.Length)
            {
                WriteCommandLineError(
                    CommandLineParameterParserStrings.MissingFileArgument,
                    showHelp: true,
                    showBanner: false);
                return(false);
            }

            // Don't show the startup banner unless -noexit has been specified.
            if (!noexitSeen)
            {
                _showBanner = false;
            }

            // Process interactive input...
            if (args[i] == "-")
            {
                // the arg to -file is -, which is secret code for "read the commands from stdin with prompts"

                _explicitReadCommandsFromStdin = true;
                _noPrompt = false;
            }
            else
            {
                // Exit on script completion unless -noexit was specified...
                if (!noexitSeen)
                {
                    _noExit = false;
                }

                // 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
                {
                    _file = NormalizeFilePath(args[i]);
                }
                catch (Exception e)
                {
                    // Catch all exceptions - we're just going to exit anyway so there's
                    // no issue of the system being destabilized.
                    exceptionMessage = e.Message;
                }

                if (exceptionMessage != null)
                {
                    WriteCommandLineError(
                        string.Format(CultureInfo.CurrentCulture, CommandLineParameterParserStrings.InvalidFileArgument, args[i], exceptionMessage),
                        showBanner: false);
                    return(false);
                }

                if (!System.IO.File.Exists(_file))
                {
                    if (args[i].StartsWith("-") && args[i].Length > 1)
                    {
                        string        param = args[i].Substring(1, args[i].Length - 1).ToLower();
                        StringBuilder possibleParameters = new StringBuilder();
                        foreach (string validParameter in validParameters)
                        {
                            if (validParameter.Contains(param))
                            {
                                possibleParameters.Append("\n  -");
                                possibleParameters.Append(validParameter);
                            }
                        }
                        if (possibleParameters.Length > 0)
                        {
                            WriteCommandLineError(
                                string.Format(CultureInfo.CurrentCulture, CommandLineParameterParserStrings.InvalidArgument, args[i]),
                                showBanner: false);
                            WriteCommandLineError(possibleParameters.ToString(), showBanner: false);
                            return(false);
                        }
                    }
                    WriteCommandLineError(
                        string.Format(CultureInfo.CurrentCulture, CommandLineParameterParserStrings.ArgumentFileDoesNotExist, args[i]),
                        showHelp: true);
                    return(false);
                }

                i++;

                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]))
                    {
                        int offset = arg.IndexOf(':');
                        if (offset >= 0)
                        {
                            if (offset == arg.Length - 1)
                            {
                                pendingParameter = arg.TrimEnd(':');
                            }
                            else
                            {
                                string argValue = arg.Substring(offset + 1);
                                string argName  = arg.Substring(0, offset);
                                if (TryGetBoolValue(argValue, out bool boolValue))
                                {
                                    _collectedArgs.Add(new CommandParameter(argName, boolValue));
                                }
                                else
                                {
                                    _collectedArgs.Add(new CommandParameter(argName, argValue));
                                }
                            }
                        }
                        else
                        {
                            _collectedArgs.Add(new CommandParameter(arg));
                        }
                    }
                    else
                    {
                        _collectedArgs.Add(new CommandParameter(null, arg));
                    }
                    ++i;
                }
            }
            return(true);
        }
        private void ParseHelper(string[] args)
        {
            Dbg.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 file

                    --i;
                    ParseFile(args, ref i, noexitSeen);
                    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 version is in the commandline, don't continue to look at any other parameters
                if (MatchSwitch(switchKey, "version", "v"))
                {
                    _showVersion   = true;
                    _showBanner    = false;
                    _noInteractive = true;
                    _skipUserInit  = true;
                    _noExit        = false;
                    break;
                }
                else if (MatchSwitch(switchKey, "help", "h") || MatchSwitch(switchKey, "?", "?"))
                {
                    _showHelp         = true;
                    _showExtendedHelp = true;
                    _abortStartup     = true;
                }
                else if (MatchSwitch(switchKey, "noexit", "noe"))
                {
                    _noExit    = true;
                    noexitSeen = 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;
                }
                else if (MatchSwitch(switchKey, "socketservermode", "so"))
                {
                    _socketServerMode = true;
                }
                else if (MatchSwitch(switchKey, "servermode", "s"))
                {
                    _serverMode = true;
                }
                else if (MatchSwitch(switchKey, "namedpipeservermode", "nam"))
                {
                    _namedPipeServerMode = true;
                }
                else if (MatchSwitch(switchKey, "sshservermode", "sshs"))
                {
                    _sshServerMode = true;
                }
                else if (MatchSwitch(switchKey, "interactive", "i"))
                {
                    _noInteractive = false;
                }
                else if (MatchSwitch(switchKey, "configurationname", "config"))
                {
                    ++i;
                    if (i >= args.Length)
                    {
                        WriteCommandLineError(
                            CommandLineParameterParserStrings.MissingConfigurationNameArgument);
                        break;
                    }

                    _configurationName = args[i];
                }
                else if (MatchSwitch(switchKey, "command", "c"))
                {
                    if (!ParseCommand(args, ref i, noexitSeen, false))
                    {
                        break;
                    }
                }
                else if (MatchSwitch(switchKey, "windowstyle", "w"))
                {
#if UNIX
                    WriteCommandLineError(
                        CommandLineParameterParserStrings.WindowStyleArgumentNotImplemented);
                    break;
#else
                    ++i;
                    if (i >= args.Length)
                    {
                        WriteCommandLineError(
                            CommandLineParameterParserStrings.MissingWindowStyleArgument);
                        break;
                    }

                    try
                    {
                        ProcessWindowStyle style = (ProcessWindowStyle)LanguagePrimitives.ConvertTo(
                            args[i], typeof(ProcessWindowStyle), CultureInfo.InvariantCulture);
                        ConsoleControl.SetConsoleMode(style);
                    }
                    catch (PSInvalidCastException e)
                    {
                        WriteCommandLineError(
                            string.Format(CultureInfo.CurrentCulture, CommandLineParameterParserStrings.InvalidWindowStyleArgument, args[i], e.Message));
                        break;
                    }
#endif
                }
                else if (MatchSwitch(switchKey, "file", "f"))
                {
                    if (!ParseFile(args, ref i, noexitSeen))
                    {
                        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

                    ((ConsoleHostUserInterface)_hostUI).WriteToConsole("Waiting - type enter to continue:", false);
                    _hostUI.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 (ConsoleHost.DefaultInitialSessionState == null)
                    {
                        WriteCommandLineError(
                            "The -module option can only be specified with the -iss option.",
                            showHelp: true,
                            showBanner: false);
                        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
                        {
                            ConsoleHost.DefaultInitialSessionState.ImportPSModule(new string[] { arg });
                            moduleCount++;
                        }
                        ++i;
                    }
                    if (moduleCount < 1)
                    {
                        _hostUI.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", "in") || MatchSwitch(switchKey, "if", "if"))
                {
                    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, "settingsfile", "settings"))
                {
                    ++i;
                    if (i >= args.Length)
                    {
                        WriteCommandLineError(
                            CommandLineParameterParserStrings.MissingSettingsFileArgument);
                        break;
                    }
                    string configFile = null;
                    try
                    {
                        configFile = NormalizeFilePath(args[i]);
                    }
                    catch (Exception ex)
                    {
                        string error = string.Format(CultureInfo.CurrentCulture, CommandLineParameterParserStrings.InvalidSettingsFileArgument, args[i], ex.Message);
                        WriteCommandLineError(error);
                        break;
                    }

                    if (!System.IO.File.Exists(configFile))
                    {
                        string error = string.Format(CultureInfo.CurrentCulture, CommandLineParameterParserStrings.SettingsFileNotExists, configFile);
                        WriteCommandLineError(error);
                        break;
                    }
                    PowerShellConfig.Instance.SetSystemConfigFilePath(configFile);
                }
#if STAMODE
                // explicit setting of the ApartmentState Not supported on NanoServer
                else if (MatchSwitch(switchKey, "sta", "s"))
                {
                    if (_staMode.HasValue)
                    {
                        // -sta and -mta are mutually exclusive.
                        WriteCommandLineError(
                            CommandLineParameterParserStrings.MtaStaMutuallyExclusive);
                        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.
                        WriteCommandLineError(
                            CommandLineParameterParserStrings.MtaStaMutuallyExclusive);
                        break;
                    }

                    _staMode = false;
                }
#endif
                else if (MatchSwitch(switchKey, "workingdirectory", "wo") || MatchSwitch(switchKey, "wd", "wd"))
                {
                    ++i;
                    if (i >= args.Length)
                    {
                        WriteCommandLineError(
                            CommandLineParameterParserStrings.MissingWorkingDirectoryArgument);
                        break;
                    }

                    _workingDirectory = args[i];
                }
                else
                {
                    // The first parameter we fail to recognize marks the beginning of the file string.

                    --i;
                    if (!ParseFile(args, ref i, noexitSeen))
                    {
                        break;
                    }
                }
            }

            if (_showHelp)
            {
                ShowHelp();
            }

            if (_showBanner && !_showHelp)
            {
                DisplayBanner();
            }

            Dbg.Assert(
                ((_exitCode == ConsoleHost.ExitCodeBadCommandLineParameter) && _abortStartup) ||
                (_exitCode == ConsoleHost.ExitCodeSuccess),
                "if exit code is failure, then abortstartup should be true");
        }
        private void ParseHelper(string[] args)
        {
            Dbg.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, "noprofile", "nop"))
                {
                    _skipUserInit = true;
                }
                else if (MatchSwitch(switchKey, "nologo", "nol"))
                {
                    _showBanner = false;
                }
                else if (MatchSwitch(switchKey, "noninteractive", "noni"))
                {
                    _noInteractive = true;
                }
                else if (MatchSwitch(switchKey, "socketservermode", "so"))
                {
                    _socketServerMode = true;
                }
                else if (MatchSwitch(switchKey, "servermode", "s"))
                {
                    _serverMode = true;
                }
                else if (MatchSwitch(switchKey, "namedpipeservermode", "nam"))
                {
                    _namedPipeServerMode = true;
                }
                else if (MatchSwitch(switchKey, "sshservermode", "sshs"))
                {
                    _sshServerMode = true;
                }
                else if (MatchSwitch(switchKey, "configurationname", "config"))
                {
                    ++i;
                    if (i >= args.Length)
                    {
                        WriteCommandLineError(
                            CommandLineParameterParserStrings.MissingConfigurationNameArgument);
                        break;
                    }

                    _configurationName = args[i];
                }
                else if (MatchSwitch(switchKey, "command", "c"))
                {
                    if (!ParseCommand(args, ref i, noexitSeen, false))
                    {
                        break;
                    }
                }
#if !CORECLR  // windowstyle parameter not supported on NanoServer because ProcessWindowStyle does Not exist on CoreCLR
                else if (MatchSwitch(switchKey, "windowstyle", "w"))
                {
                    ++i;
                    if (i >= args.Length)
                    {
                        WriteCommandLineError(
                            CommandLineParameterParserStrings.MissingWindowStyleArgument);
                        break;
                    }

                    try
                    {
                        ProcessWindowStyle style = (ProcessWindowStyle)LanguagePrimitives.ConvertTo(
                            args[i], typeof(ProcessWindowStyle), CultureInfo.InvariantCulture);
                        ConsoleControl.SetConsoleMode(style);
                    }
                    catch (PSInvalidCastException e)
                    {
                        WriteCommandLineError(
                            string.Format(CultureInfo.CurrentCulture, CommandLineParameterParserStrings.InvalidWindowStyleArgument, args[i], e.Message));
                        break;
                    }
                }
#endif
                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)
                    {
                        WriteCommandLineError(
                            CommandLineParameterParserStrings.MissingFileArgument,
                            showHelp: true,
                            showBanner: true);
                        break;
                    }

                    // Don't show the startup banner unless -noexit has been specified.
                    if (!noexitSeen)
                    {
                        _showBanner = false;
                    }

                    // Process interactive input...
                    if (args[i] == "-")
                    {
                        // the arg to -file is -, which is secret code for "read the commands from stdin with prompts"

                        _explicitReadCommandsFromStdin = true;
                        _noPrompt = false;
                    }
                    else
                    {
                        // Exit on script completion unless -noexit was specified...
                        if (!noexitSeen)
                        {
                            _noExit = false;
                        }

                        // 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
                        {
                            // Normalize slashes
                            _file = args[i].Replace(StringLiterals.AlternatePathSeparator,
                                                    StringLiterals.DefaultPathSeparator);
                            _file = Path.GetFullPath(_file);
                        }
                        catch (Exception e)
                        {
                            // Catch all exceptions - we're just going to exit anyway so there's
                            // no issue of the system being destabilized.
                            exceptionMessage = e.Message;
                        }

                        if (exceptionMessage != null)
                        {
                            WriteCommandLineError(
                                string.Format(CultureInfo.CurrentCulture, CommandLineParameterParserStrings.InvalidFileArgument, args[i], exceptionMessage),
                                showBanner: true);
                            break;
                        }

                        if (!Path.GetExtension(_file).Equals(".ps1", StringComparison.OrdinalIgnoreCase))
                        {
                            WriteCommandLineError(
                                string.Format(CultureInfo.CurrentCulture, CommandLineParameterParserStrings.InvalidFileArgumentExtension, args[i]),
                                showBanner: true);
                            break;
                        }

                        if (!System.IO.File.Exists(_file))
                        {
                            WriteCommandLineError(
                                string.Format(CultureInfo.CurrentCulture, CommandLineParameterParserStrings.ArgumentFileDoesNotExist, args[i]),
                                showBanner: true);
                            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

                    ((ConsoleHostUserInterface)_hostUI).WriteToConsole("Waiting - type enter to continue:", false);
                    _hostUI.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 (ConsoleHost.DefaultInitialSessionState == null)
                    {
                        WriteCommandLineError(
                            "The -module option can only be specified with the -iss option.",
                            showHelp: true,
                            showBanner: true);
                        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
                        {
                            ConsoleHost.DefaultInitialSessionState.ImportPSModule(new string[] { arg });
                            moduleCount++;
                        }
                        ++i;
                    }
                    if (moduleCount < 1)
                    {
                        _hostUI.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;
                    }
                }
#if !CORECLR  // explicit setting of the ApartmentState Not supported on NanoServer
                else if (MatchSwitch(switchKey, "sta", "s"))
                {
                    if (_staMode.HasValue)
                    {
                        // -sta and -mta are mutually exclusive.
                        WriteCommandLineError(
                            CommandLineParameterParserStrings.MtaStaMutuallyExclusive);
                        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.
                        WriteCommandLineError(
                            CommandLineParameterParserStrings.MtaStaMutuallyExclusive);
                        break;
                    }

                    _staMode = false;
                }
#endif
                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)
            {
                DisplayBanner();
            }

            Dbg.Assert(
                ((_exitCode == ConsoleHost.ExitCodeBadCommandLineParameter) && _abortStartup) ||
                (_exitCode == ConsoleHost.ExitCodeSuccess),
                "if exit code is failure, then abortstartup should be true");
        }
        private bool ParseFile(string[] args, ref int i, bool noexitSeen)
        {
            // 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)
            {
                WriteCommandLineError(
                    CommandLineParameterParserStrings.MissingFileArgument,
                    showHelp: true,
                    showBanner: true);
                return(false);
            }

            // Don't show the startup banner unless -noexit has been specified.
            if (!noexitSeen)
            {
                _showBanner = false;
            }

            // Process interactive input...
            if (args[i] == "-")
            {
                // the arg to -file is -, which is secret code for "read the commands from stdin with prompts"

                _explicitReadCommandsFromStdin = true;
                _noPrompt = false;
            }
            else
            {
                // Exit on script completion unless -noexit was specified...
                if (!noexitSeen)
                {
                    _noExit = false;
                }

                // 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
                {
                    // Normalize slashes
                    _file = args[i].Replace(StringLiterals.AlternatePathSeparator,
                                            StringLiterals.DefaultPathSeparator);
                    _file = Path.GetFullPath(_file);
                }
                catch (Exception e)
                {
                    // Catch all exceptions - we're just going to exit anyway so there's
                    // no issue of the system being destabilized.
                    exceptionMessage = e.Message;
                }

                if (exceptionMessage != null)
                {
                    WriteCommandLineError(
                        string.Format(CultureInfo.CurrentCulture, CommandLineParameterParserStrings.InvalidFileArgument, args[i], exceptionMessage),
                        showBanner: true);
                    return(false);
                }

                if (!System.IO.File.Exists(_file))
                {
                    WriteCommandLineError(
                        string.Format(CultureInfo.CurrentCulture, CommandLineParameterParserStrings.ArgumentFileDoesNotExist, args[i]),
                        showBanner: true);
                    return(false);
                }

                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;
                }
            }
            return(true);
        }
Пример #6
0
        private void ParseHelper(string[] args)
        {
            bool flag = false;

            for (int i = 0; i < (int)args.Length; i++)
            {
                string lowerInvariant = args[i].Trim().ToLowerInvariant();
                if (!string.IsNullOrEmpty(lowerInvariant))
                {
                    if (SpecialCharacters.IsDash(lowerInvariant[0]) || lowerInvariant[0] == '/')
                    {
                        lowerInvariant = lowerInvariant.Substring(1);
                        if (this.MatchSwitch(lowerInvariant, "help", "h") || this.MatchSwitch(lowerInvariant, "?", "?"))
                        {
                            this.showHelp     = true;
                            this.abortStartup = true;
                        }
                        else
                        {
                            if (!this.MatchSwitch(lowerInvariant, "noexit", "noe"))
                            {
                                if (!this.MatchSwitch(lowerInvariant, "importsystemmodules", "imp"))
                                {
                                    if (!this.MatchSwitch(lowerInvariant, "showinitialprompt", "show"))
                                    {
                                        if (!this.MatchSwitch(lowerInvariant, "noprofile", "nop"))
                                        {
                                            if (!this.MatchSwitch(lowerInvariant, "nologo", "nol"))
                                            {
                                                if (!this.MatchSwitch(lowerInvariant, "noninteractive", "noni"))
                                                {
                                                    if (!this.MatchSwitch(lowerInvariant, "servermode", "s"))
                                                    {
                                                        if (!this.MatchSwitch(lowerInvariant, "command", "c"))
                                                        {
                                                            if (!this.MatchSwitch(lowerInvariant, "windowstyle", "w"))
                                                            {
                                                                if (!this.MatchSwitch(lowerInvariant, "file", "f"))
                                                                {
                                                                    if (this.MatchSwitch(lowerInvariant, "outputformat", "o") || this.MatchSwitch(lowerInvariant, "of", "o"))
                                                                    {
                                                                        this.ParseFormat(args, ref i, ref this.outFormat, CommandLineParameterParserStrings.MissingOutputFormatParameter);
                                                                    }
                                                                    else
                                                                    {
                                                                        if (this.MatchSwitch(lowerInvariant, "inputformat", "i") || this.MatchSwitch(lowerInvariant, "if", "i"))
                                                                        {
                                                                            this.ParseFormat(args, ref i, ref this.inFormat, CommandLineParameterParserStrings.MissingInputFormatParameter);
                                                                        }
                                                                        else
                                                                        {
                                                                            if (this.MatchSwitch(lowerInvariant, "executionpolicy", "ex") || this.MatchSwitch(lowerInvariant, "ep", "ep"))
                                                                            {
                                                                                this.ParseExecutionPolicy(args, ref i, ref this.executionPolicy, CommandLineParameterParserStrings.MissingExecutionPolicyParameter);
                                                                            }
                                                                            else
                                                                            {
                                                                                if (this.MatchSwitch(lowerInvariant, "encodedcommand", "e") || this.MatchSwitch(lowerInvariant, "ec", "e"))
                                                                                {
                                                                                    this.wasCommandEncoded = true;
                                                                                    if (!this.ParseCommand(args, ref i, flag, true))
                                                                                    {
                                                                                        break;
                                                                                    }
                                                                                }
                                                                                else
                                                                                {
                                                                                    if (this.MatchSwitch(lowerInvariant, "encodedarguments", "encodeda") || this.MatchSwitch(lowerInvariant, "ea", "ea"))
                                                                                    {
                                                                                        if (!this.CollectArgs(args, ref i))
                                                                                        {
                                                                                            break;
                                                                                        }
                                                                                    }
                                                                                    else
                                                                                    {
                                                                                        if (!this.MatchSwitch(lowerInvariant, "sta", "s"))
                                                                                        {
                                                                                            if (!this.MatchSwitch(lowerInvariant, "mta", "mta"))
                                                                                            {
                                                                                                i--;
                                                                                                if (!this.ParseCommand(args, ref i, flag, false))
                                                                                                {
                                                                                                    break;
                                                                                                }
                                                                                            }
                                                                                            else
                                                                                            {
                                                                                                if (!this.staMode.HasValue)
                                                                                                {
                                                                                                    this.staMode = new bool?(false);
                                                                                                }
                                                                                                else
                                                                                                {
                                                                                                    this.ui.WriteErrorLine(CommandLineParameterParserStrings.MtaStaMutuallyExclusive);
                                                                                                    this.showHelp     = false;
                                                                                                    this.showBanner   = false;
                                                                                                    this.abortStartup = true;
                                                                                                    this.exitCode     = -196608;
                                                                                                    break;
                                                                                                }
                                                                                            }
                                                                                        }
                                                                                        else
                                                                                        {
                                                                                            if (!this.staMode.HasValue)
                                                                                            {
                                                                                                this.staMode = new bool?(true);
                                                                                            }
                                                                                            else
                                                                                            {
                                                                                                this.ui.WriteErrorLine(CommandLineParameterParserStrings.MtaStaMutuallyExclusive);
                                                                                                this.showHelp     = false;
                                                                                                this.showBanner   = false;
                                                                                                this.abortStartup = true;
                                                                                                this.exitCode     = -196608;
                                                                                                break;
                                                                                            }
                                                                                        }
                                                                                    }
                                                                                }
                                                                            }
                                                                        }
                                                                    }
                                                                }
                                                                else
                                                                {
                                                                    i++;
                                                                    if (i < (int)args.Length)
                                                                    {
                                                                        if (!flag)
                                                                        {
                                                                            this.showBanner = false;
                                                                        }
                                                                        if (!flag)
                                                                        {
                                                                            this.noExit = false;
                                                                        }
                                                                        if (args[i] != "-")
                                                                        {
                                                                            string message = null;
                                                                            try
                                                                            {
                                                                                this.file = Path.GetFullPath(args[i]);
                                                                            }
                                                                            catch (Exception exception1)
                                                                            {
                                                                                Exception exception = exception1;
                                                                                ConsoleHost.CheckForSevereException(exception);
                                                                                message = exception.Message;
                                                                            }
                                                                            if (message == null)
                                                                            {
                                                                                if (Path.GetExtension(this.file).Equals(".ps1", StringComparison.OrdinalIgnoreCase))
                                                                                {
                                                                                    if (System.IO.File.Exists(this.file))
                                                                                    {
                                                                                        i++;
                                                                                        Regex  regex = new Regex("^.\\w+\\:", RegexOptions.CultureInvariant);
                                                                                        string str   = null;
                                                                                        while (i < (int)args.Length)
                                                                                        {
                                                                                            string str1 = args[i];
                                                                                            if (str == null)
                                                                                            {
                                                                                                if (string.IsNullOrEmpty(str1) || !SpecialCharacters.IsDash(str1[0]))
                                                                                                {
                                                                                                    this.collectedArgs.Add(new CommandParameter(null, str1));
                                                                                                }
                                                                                                else
                                                                                                {
                                                                                                    Match match = regex.Match(str1);
                                                                                                    if (!match.Success)
                                                                                                    {
                                                                                                        this.collectedArgs.Add(new CommandParameter(str1));
                                                                                                    }
                                                                                                    else
                                                                                                    {
                                                                                                        int num = str1.IndexOf(':');
                                                                                                        if (num != str1.Length - 1)
                                                                                                        {
                                                                                                            this.collectedArgs.Add(new CommandParameter(str1.Substring(0, num), str1.Substring(num + 1)));
                                                                                                        }
                                                                                                        else
                                                                                                        {
                                                                                                            char[] chrArray = new char[1];
                                                                                                            chrArray[0] = ':';
                                                                                                            str         = str1.TrimEnd(chrArray);
                                                                                                        }
                                                                                                    }
                                                                                                }
                                                                                            }
                                                                                            else
                                                                                            {
                                                                                                this.collectedArgs.Add(new CommandParameter(str, str1));
                                                                                                str = null;
                                                                                            }
                                                                                            i++;
                                                                                        }
                                                                                        break;
                                                                                    }
                                                                                    else
                                                                                    {
                                                                                        object[] objArray = new object[1];
                                                                                        objArray[0] = args[i];
                                                                                        this.ui.WriteErrorLine(string.Format(CultureInfo.CurrentCulture, CommandLineParameterParserStrings.ArgumentFileDoesNotExist, objArray));
                                                                                        this.showHelp     = false;
                                                                                        this.abortStartup = true;
                                                                                        this.exitCode     = -196608;
                                                                                        break;
                                                                                    }
                                                                                }
                                                                                else
                                                                                {
                                                                                    object[] objArray1 = new object[1];
                                                                                    objArray1[0] = args[i];
                                                                                    this.ui.WriteErrorLine(string.Format(CultureInfo.CurrentCulture, CommandLineParameterParserStrings.InvalidFileArgumentExtension, objArray1));
                                                                                    this.showHelp     = false;
                                                                                    this.abortStartup = true;
                                                                                    this.exitCode     = -196608;
                                                                                    break;
                                                                                }
                                                                            }
                                                                            else
                                                                            {
                                                                                object[] objArray2 = new object[2];
                                                                                objArray2[0] = args[i];
                                                                                objArray2[1] = message;
                                                                                this.ui.WriteErrorLine(string.Format(CultureInfo.CurrentCulture, CommandLineParameterParserStrings.InvalidFileArgument, objArray2));
                                                                                this.showHelp     = false;
                                                                                this.abortStartup = true;
                                                                                this.exitCode     = -196608;
                                                                                break;
                                                                            }
                                                                        }
                                                                        else
                                                                        {
                                                                            this.readFromStdin = true;
                                                                            this.noPrompt      = false;
                                                                            break;
                                                                        }
                                                                    }
                                                                    else
                                                                    {
                                                                        this.ui.WriteErrorLine(CommandLineParameterParserStrings.MissingFileArgument);
                                                                        this.showHelp     = true;
                                                                        this.abortStartup = true;
                                                                        this.exitCode     = -196608;
                                                                        break;
                                                                    }
                                                                }
                                                            }
                                                            else
                                                            {
                                                                i++;
                                                                if (i < (int)args.Length)
                                                                {
                                                                    try
                                                                    {
                                                                        ProcessWindowStyle processWindowStyle = (ProcessWindowStyle)LanguagePrimitives.ConvertTo(args[i], typeof(ProcessWindowStyle), CultureInfo.InvariantCulture);
                                                                        ConsoleControl.SetConsoleMode(processWindowStyle);
                                                                    }
                                                                    catch (PSInvalidCastException pSInvalidCastException1)
                                                                    {
                                                                        PSInvalidCastException pSInvalidCastException = pSInvalidCastException1;
                                                                        object[] message1 = new object[2];
                                                                        message1[0] = args[i];
                                                                        message1[1] = pSInvalidCastException.Message;
                                                                        this.ui.WriteErrorLine(string.Format(CultureInfo.CurrentCulture, CommandLineParameterParserStrings.InvalidWindowStyleArgument, message1));
                                                                        this.showHelp     = false;
                                                                        this.showBanner   = false;
                                                                        this.abortStartup = true;
                                                                        this.exitCode     = -196608;
                                                                        break;
                                                                    }
                                                                }
                                                                else
                                                                {
                                                                    this.ui.WriteErrorLine(CommandLineParameterParserStrings.MissingWindowStyleArgument);
                                                                    this.showHelp     = false;
                                                                    this.showBanner   = false;
                                                                    this.abortStartup = true;
                                                                    this.exitCode     = -196608;
                                                                    break;
                                                                }
                                                            }
                                                        }
                                                        else
                                                        {
                                                            if (!this.ParseCommand(args, ref i, flag, false))
                                                            {
                                                                break;
                                                            }
                                                        }
                                                    }
                                                    else
                                                    {
                                                        this.serverMode = true;
                                                    }
                                                }
                                                else
                                                {
                                                    this.noInteractive = true;
                                                    if (ConsoleHost.DefaultInitialSessionState != null)
                                                    {
                                                        ConsoleHost.DefaultInitialSessionState.WarmUpTabCompletionOnIdle = false;
                                                    }
                                                }
                                            }
                                            else
                                            {
                                                this.showBanner = false;
                                            }
                                        }
                                        else
                                        {
                                            this.skipUserInit = true;
                                        }
                                    }
                                    else
                                    {
                                        this.showInitialPrompt = true;
                                    }
                                }
                                else
                                {
                                    this.importSystemModules = true;
                                }
                            }
                            else
                            {
                                this.noExit = true;
                                flag        = true;
                            }
                        }
                    }
                    else
                    {
                        i--;
                        this.ParseCommand(args, ref i, flag, false);
                        break;
                    }
                }
            }
            if (this.showHelp)
            {
                this.ShowHelp();
            }
            if (this.showBanner && !this.showHelp)
            {
                this.ShowBanner();
            }
        }