Team Ai
Datasetpublic

MegaBites-AI/Windows-powershell

sourceHugging Facemitupdated 6mo agoView on Hugging Face
0likes372downloads
AutomationEngine.cs130 linesDownload Raw Back to engine
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