コード例 #1
0
ファイル: ConsoleHost.cs プロジェクト: dfinke/powershell
        // 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;
            }
        }
コード例 #2
0
ファイル: ConsoleHost.cs プロジェクト: dfinke/powershell
 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);
 }