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