Example #1
0
        /// <summary>
        /// Processes the -SettingFile Argument.
        /// </summary>
        /// <param name="args">
        /// The command line parameters to be processed.
        /// </param>
        /// <param name="settingFileArgIndex">
        /// The index in args to the argument following '-SettingFile'.
        /// </param>
        /// <param name="parser">
        /// Used to allow the helper to write errors to the console.  If not supplied, no errors will be written.
        /// </param>
        /// <returns>
        /// Returns true if the argument was parsed successfully and false if not.
        /// </returns>
        private static bool TryParseSettingFileHelper(string[] args, int settingFileArgIndex, CommandLineParameterParser parser)
        {
            if (settingFileArgIndex >= args.Length)
            {
                if (parser != null)
                {
                    parser.WriteCommandLineError(
                        CommandLineParameterParserStrings.MissingSettingsFileArgument);
                }

                return(false);
            }

            string configFile = null;

            try
            {
                configFile = NormalizeFilePath(args[settingFileArgIndex]);
            }
            catch (Exception ex)
            {
                if (parser != null)
                {
                    string error = string.Format(CultureInfo.CurrentCulture, CommandLineParameterParserStrings.InvalidSettingsFileArgument, args[settingFileArgIndex], ex.Message);
                    parser.WriteCommandLineError(error);
                }

                return(false);
            }

            if (!System.IO.File.Exists(configFile))
            {
                if (parser != null)
                {
                    string error = string.Format(CultureInfo.CurrentCulture, CommandLineParameterParserStrings.SettingsFileNotExists, configFile);
                    parser.WriteCommandLineError(error);
                }

                return(false);
            }

            PowerShellConfig.Instance.SetSystemConfigFilePath(configFile);
            return(true);
        }
Example #2
0
        /// <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 (!CharExtensions.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) && CharExtensions.IsDash(switchKey[0]))
            {
                switchKey = switchKey.Substring(1);
            }

            return(SwitchKey : switchKey, ShouldBreak : false);
        }
Example #3
0
 private uint Run(string bannerText, string helpText, bool isPrestartWarned, string[] args)
 {
     s_cpp = new CommandLineParameterParser(this, _ver, bannerText, helpText);
     s_cpp.Parse(args);
     return Run(s_cpp, isPrestartWarned);
 }
Example #4
0
        // NTRAID#Windows Out Of Band Releases-915506-2005/09/09
        // Removed HandleUnexpectedExceptions infrastructure
        /// <summary>
        ///
        /// internal Entry point in msh console host implementation
        ///
        /// </summary>
        /// 
        /// <param name="configuration">
        /// Configuration information to use for creating runspace.
        /// </param>
        /// 
        /// <param name="bannerText">
        /// Banner text to be displayed by ConsoleHost
        /// </param>
        ///
        /// <param name="helpText">
        /// Help text for minishell. This is displayed on 'minishell -?'.
        /// </param>
        ///
        /// <param name="preStartWarning">
        /// 
        /// Warning occurred prior to this point, for example, a snap-in fails to load beforehand.
        /// This string will be printed out.
        /// 
        /// </param>
        /// <param name = "args">
        /// 
        /// Command line parameters to powershell.exe
        /// 
        /// </param>
        /// <returns>
        /// 
        /// The exit code for the shell.
        /// 
        /// NTRAID#Windows OS Bugs-1036968-2005/01/20-sburns The behavior here is related to monitor work.  The low word of the 
        /// exit code is available for the user.  The high word is reserved for the shell and monitor.
        /// 
        /// The shell process needs to return:
        /// 
        /// - if the shell.exe fails init, 0xFFFF0000
        /// - if the exit keyword is called with no parameter at the point of top-level prompt, 0x80000000 (e.g. 0 with the high 
        /// bit set)
        /// - if the exit keyword is called with any int param less than or equal to 0xFFFF, then that int masked with the high 
        /// bit set.  e.g. "exit 3" results in 0x80000003
        /// - if the script ends (in the case of msh -command or msh -commandfile), then 0x80000000.
        /// - if ctrl-break is pressed, with 0xFFFE0000
        /// - if the shell.exe is passed a bad command-line parameter, with 0xFFFD0000.
        /// - if the shell.exe crashes, with 0x00000000
        ///
        /// The monitor process gets the exit code.  If the high bit is set, then the shell process exited normally (though
        /// possibly due to an error).  If not, the shell process crashed.  If the shell.exe exit code is x00000000 (crashed) 
        /// or 0xFFFE0000 (user hit ctrl-break), the monitor should restart the shell.exe. Otherwise, the monitor should exit 
        /// with the same exit code as the shell.exe.
        ///
        /// Anyone checking the exit code of the shell or monitor can mask off the hiword to determine the exit code passed
        /// by the script that the shell last executed.
        /// 
        /// </returns>
        internal static int Start(
            RunspaceConfiguration configuration,
            string bannerText,
            string helpText,
            string preStartWarning,
            string[] args)
        {
#if DEBUG
            if (Environment.GetEnvironmentVariable("POWERSHELL_DEBUG_STARTUP") != null)
            {
                while (!System.Diagnostics.Debugger.IsAttached)
                {
                    Thread.Sleep(1000);
                }
            }
#endif

            try
            {
                string profileDir;
#if UNIX
                profileDir = Platform.SelectProductNameForDirectory(Platform.XDG_Type.CACHE);
#else
                profileDir = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) + 
                    @"\Microsoft\Windows\PowerShell";

                if (!Directory.Exists(profileDir))
                {
                    Directory.CreateDirectory(profileDir);
                }
#endif
                ClrFacade.SetProfileOptimizationRoot(profileDir);
            }
            catch
            {
                // It's safe to ignore errors, the guarded code is just there to try and
                // improve startup performance.
            }

            uint exitCode = ExitCodeSuccess;

            System.Threading.Thread.CurrentThread.Name = "ConsoleHost main thread";

            s_theConsoleHost = ConsoleHost.CreateSingletonInstance(configuration);
            s_theConsoleHost.BindBreakHandler();

            PSHost.IsStdOutputRedirected = Console.IsOutputRedirected;

            if (args == null)
            {
                args = new string[0];
            }

            if (!string.IsNullOrEmpty(preStartWarning))
            {
                s_theConsoleHost.UI.WriteWarningLine(preStartWarning);
            }

            try
            {
                s_cpp = new CommandLineParameterParser(s_theConsoleHost, s_theConsoleHost._ver, bannerText, helpText);
                string[] tempArgs = new string[args.GetLength(0)];
                args.CopyTo(tempArgs, 0);

                s_cpp.Parse(tempArgs);

                // Servermode parameter validation check.
                if ((s_cpp.ServerMode && s_cpp.NamedPipeServerMode) || (s_cpp.ServerMode && s_cpp.SocketServerMode) || (s_cpp.NamedPipeServerMode && s_cpp.SocketServerMode))
                {
                    s_tracer.TraceError("Conflicting server mode parameters, parameters must be used exclusively.");
                    s_theConsoleHost.ui.WriteErrorLine(ConsoleHostStrings.ConflictingServerModeParameters);
                    unchecked
                    {
                        return (int)ExitCodeBadCommandLineParameter;
                    }
                }

                if (s_cpp.ServerMode)
                {
                    ClrFacade.StartProfileOptimization("StartupProfileData-ServerMode");
                    System.Management.Automation.Remoting.Server.OutOfProcessMediator.Run(s_cpp.InitialCommand);
                    exitCode = 0;
                }
                else if (s_cpp.NamedPipeServerMode)
                {
                    ClrFacade.StartProfileOptimization("StartupProfileData-NamedPipeServerMode");
                    System.Management.Automation.Remoting.RemoteSessionNamedPipeServer.RunServerMode(
                        s_cpp.ConfigurationName);
                    exitCode = 0;
                }
                else if (s_cpp.SSHServerMode)
                {
                    ClrFacade.StartProfileOptimization("StartupProfileData-SSHServerMode");
                    System.Management.Automation.Remoting.Server.SSHProcessMediator.Run(s_cpp.InitialCommand);
                    exitCode = 0;
                }
                else if (s_cpp.SocketServerMode)
                {
                    ClrFacade.StartProfileOptimization("StartupProfileData-SocketServerMode");
                    System.Management.Automation.Remoting.Server.HyperVSocketMediator.Run(s_cpp.InitialCommand,
                        s_cpp.ConfigurationName);
                    exitCode = 0;
                }
                else
                {
                    ClrFacade.StartProfileOptimization(
                        s_theConsoleHost.LoadPSReadline()
                            ? "StartupProfileData-Interactive"
                            : "StartupProfileData-NonInteractive");
                    exitCode = s_theConsoleHost.Run(s_cpp, !string.IsNullOrEmpty(preStartWarning));
                }
            }
            finally
            {
                TelemetryAPI.ReportExitTelemetry(s_theConsoleHost);
                s_theConsoleHost.Dispose();
            }

            unchecked
            {
                return (int)exitCode;
            }
        }
Example #5
0
        /// <summary>
        /// 
        /// The main run loop of the program: processes command line parameters, and starts up a runspace.
        /// 
        /// </summary>
        /// 
        /// <param name="cpp">
        /// Commandline parameter parser. The commandline parameter parser is expected to parse all the 
        /// arguments before calling this method.
        /// </param>
        /// 
        /// <param name="isPrestartWarned">
        /// Is there any warning at startup
        /// </param>
        /// 
        /// <returns>
        /// 
        /// The process exit code to be returned by Main.
        /// 
        /// </returns>

        private uint Run(CommandLineParameterParser cpp, bool isPrestartWarned)
        {
            Dbg.Assert(null != cpp, "CommandLine parameter parser cannot be null.");
            uint exitCode = ExitCodeSuccess;

            do
            {
                s_runspaceInitTracer.WriteLine("starting parse of command line parameters");

                exitCode = ExitCodeSuccess;
                if (!string.IsNullOrEmpty(cpp.InitialCommand) && isPrestartWarned)
                {
                    s_tracer.TraceError("Start up warnings made command \"{0}\" not executed", cpp.InitialCommand);
                    string msg = StringUtil.Format(ConsoleHostStrings.InitialCommandNotExecuted, cpp.InitialCommand);
                    ui.WriteErrorLine(msg);
                    exitCode = ExitCodeInitFailure;
                    break;
                }

                if (cpp.AbortStartup)
                {
                    s_tracer.WriteLine("processing of cmdline args failed, exiting");
                    exitCode = cpp.ExitCode;
                    break;
                }

                OutputFormat = cpp.OutputFormat;
                InputFormat = cpp.InputFormat;
                _wasInitialCommandEncoded = cpp.WasInitialCommandEncoded;

                ui.ReadFromStdin = cpp.ExplicitReadCommandsFromStdin || Console.IsInputRedirected;
                ui.NoPrompt = cpp.NoPrompt;
                ui.ThrowOnReadAndPrompt = cpp.ThrowOnReadAndPrompt;
                _noExit = cpp.NoExit;

                // See if we need to change the process-wide execution
                // policy
                if (!String.IsNullOrEmpty(cpp.ExecutionPolicy))
                {
                    ExecutionPolicy executionPolicy = SecuritySupport.ParseExecutionPolicy(cpp.ExecutionPolicy);
                    SecuritySupport.SetExecutionPolicy(ExecutionPolicyScope.Process, executionPolicy, null);
                }

                // NTRAID#Windows Out Of Band Releases-915506-2005/09/09
                // Removed HandleUnexpectedExceptions infrastructure
                exitCode = DoRunspaceLoop(cpp.InitialCommand, cpp.SkipProfiles, cpp.Args, cpp.StaMode, cpp.ImportSystemModules, cpp.ConfigurationName);
            }
            while (false);

            return exitCode;
        }
Example #6
0
        /// <summary>
        /// Starts managed MSH.
        /// </summary>
        /// <param name="consoleFilePath">
        /// Deprecated: Console file used to create a runspace configuration to start MSH
        /// </param>
        /// <param name="args">
        /// Command line arguments to the managed MSH
        /// </param>
        /// <param name="argc">
        /// Length of the passed in argument array.
        /// </param>
        public static int Start(string consoleFilePath, [MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.LPWStr, SizeParamIndex = 2)] string[] args, int argc)
        {
            // Warm up some components concurrently on background threads.
            EarlyStartup.Init();

            // We need to read the settings file before we create the console host
            CommandLineParameterParser.EarlyParse(args);

#if !UNIX
            // NOTE: On Unix, logging has to be deferred until after command-line parsing
            // complete. On Windows, deferring the call is not needed.
            PSEtwLog.LogConsoleStartup();
#endif

            // Windows Vista and later support non-traditional UI fallback ie., a
            // user on an Arabic machine can choose either French or English(US) as
            // UI fallback language.
            // CLR does not support this (non-traditional) fallback mechanism.
            // The currentUICulture returned NativeCultureResolver supports this non
            // traditional fallback on Vista. So it is important to set currentUICulture
            // in the beginning before we do anything.
            Thread.CurrentThread.CurrentUICulture = NativeCultureResolver.UICulture;
            Thread.CurrentThread.CurrentCulture   = NativeCultureResolver.Culture;

#if DEBUG
            if (args.Length > 0 && !string.IsNullOrEmpty(args[0]) && args[0].Equals("-isswait", StringComparison.OrdinalIgnoreCase))
            {
                Console.WriteLine("Attach the debugger to continue...");
                while (!System.Diagnostics.Debugger.IsAttached)
                {
                    Thread.Sleep(100);
                }

                System.Diagnostics.Debugger.Break();
            }
#endif
            int exitCode = 0;
            try
            {
                var banner = string.Format(
                    CultureInfo.InvariantCulture,
                    ManagedEntranceStrings.ShellBannerNonWindowsPowerShell,
                    PSVersionInfo.GitCommitId);

                exitCode = ConsoleShell.Start(banner, ManagedEntranceStrings.UsageHelp, args);
            }
            catch (HostException e)
            {
                if (e.InnerException != null && e.InnerException.GetType() == typeof(Win32Exception))
                {
                    Win32Exception win32e = e.InnerException as Win32Exception;

                    // These exceptions are caused by killing conhost.exe
                    // 1236, network connection aborted by local system
                    // 0x6, invalid console handle
                    if (win32e.NativeErrorCode == 0x6 || win32e.NativeErrorCode == 1236)
                    {
                        return(exitCode);
                    }
                }

                System.Environment.FailFast(e.Message, e);
            }
            catch (Exception e)
            {
                System.Environment.FailFast(e.Message, e);
            }

            return(exitCode);
        }
Example #7
0
		internal static int Start(RunspaceConfiguration configuration, string bannerText, string helpText, string preStartWarning, string[] args)
		{
			int num = 0;
			Thread.CurrentThread.Name = "ConsoleHost main thread";
			ConsoleHost.theConsoleHost = ConsoleHost.CreateSingletonInstance(configuration);
			ConsoleHost.theConsoleHost.BindBreakHandler();
			PSHost.IsStdOutputRedirected = ConsoleHost.theConsoleHost.IsStandardOutputRedirected;
			if (args == null)
			{
				args = new string[0];
			}
			if (!string.IsNullOrEmpty(preStartWarning))
			{
				ConsoleHost.theConsoleHost.UI.WriteWarningLine(preStartWarning);
			}
			using (ConsoleHost.theConsoleHost)
			{
				ConsoleHost.cpp = new CommandLineParameterParser(ConsoleHost.theConsoleHost, ConsoleHost.theConsoleHost.ver, bannerText, helpText);
				string[] strArrays = new string[args.GetLength(0)];
				args.CopyTo(strArrays, 0);
				ConsoleHost.cpp.Parse(strArrays);
				if (!ConsoleHost.cpp.ServerMode)
				{
					num = ConsoleHost.theConsoleHost.Run(ConsoleHost.cpp, !string.IsNullOrEmpty(preStartWarning));
				}
				else
				{
					OutOfProcessMediator.Run(ConsoleHost.cpp.InitialCommand);
					num = 0;
				}
			}
			return num;
		}
Example #8
0
		private int Run(string bannerText, string helpText, bool isPrestartWarned, string[] args)
		{
			ConsoleHost.cpp = new CommandLineParameterParser(this, this.ver, bannerText, helpText);
			ConsoleHost.cpp.Parse(args);
			return this.Run(ConsoleHost.cpp, isPrestartWarned);
		}
Example #9
0
		private int Run(CommandLineParameterParser cpp, bool isPrestartWarned)
		{
			int exitCode;
			ConsoleHost.runspaceInitTracer.WriteLine("starting parse of command line parameters", new object[0]);
			if (string.IsNullOrEmpty(cpp.InitialCommand) || !isPrestartWarned)
			{
				if (!cpp.AbortStartup)
				{
					this.outputFormat = cpp.OutputFormat;
					this.inputFormat = cpp.InputFormat;
					this.wasInitialCommandEncoded = cpp.WasInitialCommandEncoded;
					this.ui.ReadFromStdin = cpp.ReadFromStdin;
					this.ui.NoPrompt = cpp.NoPrompt;
					this.ui.ThrowOnReadAndPrompt = cpp.ThrowOnReadAndPrompt;
					this.noExit = cpp.NoExit;
					if (!string.IsNullOrEmpty(cpp.ExecutionPolicy))
					{
						ExecutionPolicy executionPolicy = SecuritySupport.ParseExecutionPolicy(cpp.ExecutionPolicy);
						SecuritySupport.SetExecutionPolicy(ExecutionPolicyScope.Process, executionPolicy, null);
					}
					exitCode = this.DoRunspaceLoop(cpp.InitialCommand, cpp.SkipProfiles, cpp.Args, cpp.StaMode, cpp.ImportSystemModules, cpp.ShowInitialPrompt);
				}
				else
				{
					ConsoleHost.tracer.WriteLine("processing of cmdline args failed, exiting", new object[0]);
					exitCode = cpp.ExitCode;
				}
			}
			else
			{
				object[] initialCommand = new object[1];
				initialCommand[0] = cpp.InitialCommand;
				ConsoleHost.tracer.TraceError("Start up warnings made command \"{0}\" not executed", initialCommand);
				string str = StringUtil.Format(ConsoleHostStrings.InitialCommandNotExecuted, cpp.InitialCommand);
				this.ui.WriteErrorLine(str);
				exitCode = -65536;
			}
			return exitCode;
		}