MegaBites-AI/Windows-powershell
0372
1// Copyright (c) Microsoft Corporation.2// Licensed under the MIT License.3 4using System.Management.Automation.Host;5using System.Management.Automation.Language;6using System.Management.Automation.Runspaces;7using System.Text;8 9namespace System.Management.Automation10{11 /// <summary>12 /// This class aggregates the objects necessary for the Monad13 /// engine to run.14 /// </summary>15 internal class AutomationEngine16 {17 static AutomationEngine()18 {19 // Register the encoding provider to load encodings that are not supported by default,20 // so as to allow them to be used in user's script/code.21 Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);22 }23 24 // Holds the parser to use for this instance of the engine...25 internal Parser EngineParser;26 27 /// <summary>28 /// Returns the handle to the execution context29 /// for this instance of the automation engine.30 /// </summary>31 internal ExecutionContext Context { get; }32 33 /// <summary>34 /// Gets the CommandDiscovery instance for the current engine.35 /// </summary>36 internal CommandDiscovery CommandDiscovery { get; }37 38 /// <summary>39 /// The principal constructor that most hosts will use when creating40 /// an instance of the automation engine. It allows you to pass in an41 /// instance of PSHost that provides the host-specific I/O routines, etc.42 /// </summary>43 internal AutomationEngine(PSHost hostInterface, InitialSessionState iss)44 {45#if !UNIX46 // Update the env variable PATHEXT to contain .CPL47 var pathext = Environment.GetEnvironmentVariable("PATHEXT");48 49 if (string.IsNullOrEmpty(pathext))50 {51 Environment.SetEnvironmentVariable("PATHEXT", ".CPL");52 }53 else if (!(pathext.EndsWith(";.CPL", StringComparison.OrdinalIgnoreCase) ||54 pathext.StartsWith(".CPL;", StringComparison.OrdinalIgnoreCase) ||55 pathext.Contains(";.CPL;", StringComparison.OrdinalIgnoreCase) ||56 pathext.Equals(".CPL", StringComparison.OrdinalIgnoreCase)))57 {58 // Fast skip if we already added the extention as ";.CPL".59 // Fast skip if user already added the extention.60 pathext += pathext[pathext.Length - 1] == ';' ? ".CPL" : ";.CPL";61 Environment.SetEnvironmentVariable("PATHEXT", pathext);62 }63#endif64 65 Context = new ExecutionContext(this, hostInterface, iss);66 67 EngineParser = new Language.Parser();68 CommandDiscovery = new CommandDiscovery(Context);69 70 // Load the iss, resetting everything to it's defaults...71 iss.Bind(Context, updateOnly: false, module: null, noClobber: false, local: false, setLocation: true);72 }73 74 /// <summary>75 /// Method to take a string and expand any metachars in it.76 /// </summary>77 internal string Expand(string s)78 {79 var ast = Parser.ScanString(s);80 81 // ExpandString is assumed to invoke code, so passing 'IsTrustedInput'82 return Compiler.GetExpressionValue(ast, true, Context, Context.EngineSessionState) as string ?? string.Empty;83 }84 85 /// <summary>86 /// Compile a piece of text into a parse tree for later execution.87 /// </summary>88 /// <param name="script">The text to parse.</param>89 /// <param name="addToHistory">True if-and-only-if the scriptblock will be added to history.</param>90 /// <returns>The parse text as a parsetree node.</returns>91 internal ScriptBlock ParseScriptBlock(string script, bool addToHistory)92 {93 return ParseScriptBlock(script, null, addToHistory);94 }95 96 internal ScriptBlock ParseScriptBlock(string script, string fileName, bool addToHistory)97 {98 ParseError[] errors;99 var ast = EngineParser.Parse(fileName, script, null, out errors, ParseMode.Default);100 101 if (addToHistory)102 {103 EngineParser.SetPreviousFirstLastToken(Context);104 }105 106 if (errors.Length > 0)107 {108 ParseException ex = errors[0].IncompleteInput109 ? new IncompleteParseException(errors[0].Message, errors[0].ErrorId)110 : new ParseException(errors);111 112 if (addToHistory)113 {114 // Try associating the parsing error with the history item if we can.115 InvocationInfo invInfo = ex.ErrorRecord.InvocationInfo;116 LocalRunspace localRunspace = Context.CurrentRunspace as LocalRunspace;117 if (invInfo is not null && localRunspace?.History is not null)118 {119 invInfo.HistoryId = localRunspace.History.GetNextHistoryId();120 }121 }122 123 throw ex;124 }125 126 return new ScriptBlock(ast, isFilter: false);127 }128 }129}130 