Team Ai
Datasetpublic

MegaBites-AI/Windows-powershell

sourceHugging Facemitupdated 6mo agoView on Hugging Face
0likes372downloads
CmdletInfo.cs559 linesDownload Raw Back to engine
1// Copyright (c) Microsoft Corporation.2// Licensed under the MIT License.3 4using System.Collections.Generic;5using System.Collections.ObjectModel;6using System.Management.Automation.Language;7using System.Text;8 9namespace System.Management.Automation10{11    /// <summary>12    /// The command information for cmdlets that are directly executable by PowerShell.13    /// </summary>14    public class CmdletInfo : CommandInfo15    {16        #region ctor17 18        /// <summary>19        /// Constructs a CmdletInfo object from the raw cmdlet data.  This should only20        /// be used for Intrinsic commands.21        /// </summary>22        /// <param name="name">23        /// The name of the cmdlet.24        /// </param>25        /// <param name="implementingType">26        /// The type information about the class that implements the cmdlet.27        /// </param>28        /// <param name="helpFile">29        /// The name of the help file associated with the cmdlet30        /// </param>31        /// <param name="PSSnapin">32        /// The PSSnapInInfo of the PSSnapin the cmdlet comes from.33        /// </param>34        /// <param name="context">35        /// The current engine context.36        /// </param>37        internal CmdletInfo(38            string name,39            Type implementingType,40            string helpFile,41            PSSnapInInfo PSSnapin,42            ExecutionContext context)43            : base(name, CommandTypes.Cmdlet, context)44        {45            if (string.IsNullOrEmpty(name))46            {47                throw PSTraceSource.NewArgumentException(nameof(name));48            }49 50            // Get the verb and noun from the name51            if (!SplitCmdletName(name, out _verb, out _noun))52            {53                throw54                    PSTraceSource.NewArgumentException(55                        nameof(name),56                        DiscoveryExceptions.InvalidCmdletNameFormat,57                        name);58            }59 60            _implementingType = implementingType;61            _helpFilePath = helpFile;62            _PSSnapin = PSSnapin;63            _options = ScopedItemOptions.ReadOnly;64 65            // CmdletInfo represents cmdlets exposed from assemblies.  On a locked down system, only trusted66            // assemblies will be loaded.  Therefore, a CmdletInfo instance will always be trusted.67            this.DefiningLanguageMode = PSLanguageMode.FullLanguage;68        }69 70        /// <summary>71        /// This is a copy constructor, used primarily for get-command.72        /// </summary>73        internal CmdletInfo(CmdletInfo other)74            : base(other)75        {76            _verb = other._verb;77            _noun = other._noun;78            _implementingType = other._implementingType;79            _helpFilePath = other._helpFilePath;80            _PSSnapin = other._PSSnapin;81            _options = ScopedItemOptions.ReadOnly;82        }83 84        /// <summary>85        /// Create a copy of commandInfo for GetCommandCommand so that we can generate parameter86        /// sets based on an argument list (so we can get the dynamic parameters.)87        /// </summary>88        internal override CommandInfo CreateGetCommandCopy(object[] arguments)89        {90            CmdletInfo copy = new CmdletInfo(this);91            copy.IsGetCommandCopy = true;92            copy.Arguments = arguments;93            return copy;94        }95 96        /// <summary>97        /// Directly create a cmdlet object from a type. This allows98        /// unregistered commands to be called. It also allows the overhead of99        /// command discovery to be bypassed.100        /// </summary>101        /// <param name="name">The name to use for the cmdlet, must be in the form Noun-Verb.</param>102        /// <param name="implementingType">The .NET class implementing this cmdlet.</param>103        public CmdletInfo(string name, Type implementingType)104            : base(name, CommandTypes.Cmdlet, null)105        {106            if (string.IsNullOrEmpty(name))107            {108                throw PSTraceSource.NewArgumentNullException(nameof(name));109            }110 111            if (implementingType == null)112            {113                throw PSTraceSource.NewArgumentNullException(nameof(name));114            }115 116            if (!typeof(Cmdlet).IsAssignableFrom(implementingType))117            {118                throw PSTraceSource.NewInvalidOperationException(DiscoveryExceptions.CmdletDoesNotDeriveFromCmdletType, "implementingType", implementingType.FullName);119            }120 121            // Get the verb and noun from the name122            if (!SplitCmdletName(name, out _verb, out _noun))123            {124                throw125                    PSTraceSource.NewArgumentException(126                        nameof(name),127                        DiscoveryExceptions.InvalidCmdletNameFormat,128                        name);129            }130 131            _implementingType = implementingType;132            _helpFilePath = string.Empty;133            _PSSnapin = null;134            _options = ScopedItemOptions.ReadOnly;135        }136 137        #endregion ctor138 139        #region public members140 141        /// <summary>142        /// Gets the verb of the cmdlet.143        /// </summary>144        public string Verb145        {146            get147            {148                return _verb;149            }150        }151 152        private readonly string _verb = string.Empty;153 154        /// <summary>155        /// Gets the noun of the cmdlet.156        /// </summary>157        public string Noun158        {159            get160            {161                return _noun;162            }163        }164 165        private readonly string _noun = string.Empty;166 167        internal static bool SplitCmdletName(string name, out string verb, out string noun)168        {169            noun = verb = string.Empty;170            if (string.IsNullOrEmpty(name))171                return false;172 173            int index = 0;174            for (int i = 0; i < name.Length; i++)175            {176                if (CharExtensions.IsDash(name[i]))177                {178                    index = i;179                    break;180                }181            }182 183            if (index > 0)184            {185                verb = name.Substring(0, index);186                noun = name.Substring(index + 1);187                return true;188            }189 190            return false;191        }192 193        /// <summary>194        /// Gets the help file path for the cmdlet.195        /// </summary>196        public string HelpFile197        {198            get199            {200                return _helpFilePath;201            }202 203            internal set204            {205                _helpFilePath = value;206            }207        }208 209        private string _helpFilePath = string.Empty;210 211        internal override HelpCategory HelpCategory212        {213            get { return HelpCategory.Cmdlet; }214        }215 216        /// <summary>217        /// Gets the Snap-in in which the cmdlet is implemented.218        /// </summary>219        public PSSnapInInfo PSSnapIn220        {221            get222            {223                return _PSSnapin;224            }225        }226 227        private readonly PSSnapInInfo _PSSnapin;228 229        /// <summary>230        /// Gets the name of the PSSnapin the cmdlet is implemented in.231        /// </summary>232        internal string PSSnapInName233        {234            get235            {236                string result = null;237                if (_PSSnapin != null)238                {239                    result = _PSSnapin.Name;240                }241 242                return result;243            }244        }245 246        /// <summary>247        /// Gets the source version.248        /// </summary>249        public override Version Version250        {251            get252            {253                if (_version == null)254                {255                    if (Module != null)256                    {257                        _version = base.Version;258                    }259                    else if (_PSSnapin != null)260                    {261                        _version = _PSSnapin.Version;262                    }263                }264 265                return _version;266            }267        }268 269        private Version _version;270 271        /// <summary>272        /// Gets the type that implements the cmdlet.273        /// </summary>274        public Type ImplementingType275        {276            get277            {278                return _implementingType;279            }280        }281 282        private readonly Type _implementingType = null;283 284        /// <summary>285        /// Gets the synopsis of the cmdlet.286        /// </summary>287        public override string Definition288        {289            get290            {291                StringBuilder synopsis = new StringBuilder();292 293                if (this.ImplementingType != null)294                {295                    foreach (CommandParameterSetInfo parameterSet in ParameterSets)296                    {297                        synopsis.AppendLine();298                        synopsis.AppendLine(299                            string.Format(300                                System.Globalization.CultureInfo.CurrentCulture,301                                "{0}{1}{2} {3}",302                                _verb,303                                StringLiterals.CommandVerbNounSeparator,304                                _noun,305                                parameterSet.ToString()));306                    }307                }308                else309                {310                    // Skip the synopsis documentation if the cmdlet hasn't been loaded yet.311                    synopsis.AppendLine(312                        string.Format(313                            System.Globalization.CultureInfo.CurrentCulture,314                            "{0}{1}{2}",315                            _verb,316                            StringLiterals.CommandVerbNounSeparator,317                            _noun));318                }319 320                return synopsis.ToString();321            }322        }323 324        /// <summary>325        /// Gets the name of the default parameter set.326        /// </summary>327        public string DefaultParameterSet328        {329            get330            {331                return this.CommandMetadata.DefaultParameterSetName;332            }333        }334 335        /// <summary>336        /// Return the output types specified on the cmdlet.337        /// </summary>338        public override ReadOnlyCollection<PSTypeName> OutputType339        {340            get341            {342                if (_outputType == null)343                {344                    _outputType = new List<PSTypeName>();345 346                    if (ImplementingType != null)347                    {348                        foreach (object o in ImplementingType.GetCustomAttributes(typeof(OutputTypeAttribute), false))349                        {350                            OutputTypeAttribute attr = (OutputTypeAttribute)o;351                            _outputType.AddRange(attr.Type);352                        }353                    }354                }355 356                List<PSTypeName> providerTypes = new List<PSTypeName>();357 358                if (Context != null)359                {360                    ProviderInfo provider = null;361                    if (Arguments != null)362                    {363                        // See if we have a path argument - we only consider named arguments -Path and -LiteralPath,364                        // and only if they are fully specified (no prefixes allowed, so we don't need to deal with365                        // ambiguities that the parameter binder would resolve for us.366 367                        for (int i = 0; i < Arguments.Length - 1; i++)368                        {369                            var arg = Arguments[i] as string;370                            if (arg != null &&371                                (arg.Equals("-Path", StringComparison.OrdinalIgnoreCase) ||372                                (arg.Equals("-LiteralPath", StringComparison.OrdinalIgnoreCase))))373                            {374                                var path = Arguments[i + 1] as string;375                                if (path != null)376                                {377                                    Context.SessionState.Path.GetResolvedProviderPathFromPSPath(path, true, out provider);378                                }379                            }380                        }381                    }382 383                    // If no path argument, just use the current path to choose the provider.384                    provider ??= Context.SessionState.Path.CurrentLocation.Provider;385 386                    provider.GetOutputTypes(Name, providerTypes);387                    if (providerTypes.Count > 0)388                    {389                        providerTypes.InsertRange(0, _outputType);390                        return new ReadOnlyCollection<PSTypeName>(providerTypes);391                    }392                }393 394                return new ReadOnlyCollection<PSTypeName>(_outputType);395            }396        }397 398        private List<PSTypeName> _outputType = null;399 400        /// <summary>401        /// Gets or sets the scope options for the alias.402        /// </summary>403        /// <exception cref="System.Management.Automation.SessionStateUnauthorizedAccessException">404        /// If the trying to set an cmdlet that is constant or405        ///     if the value trying to be set is ScopedItemOptions.Constant406        /// </exception>407        public ScopedItemOptions Options408        {409            get410            {411                return _options;412            }413 414            set415            {416                SetOptions(value, false);417            }418        }419 420        private ScopedItemOptions _options = ScopedItemOptions.None;421 422        /// <summary>423        /// Sets the options for the cmdlet and allows changes ReadOnly options only if force is specified.424        /// </summary>425        /// <param name="newOptions">426        /// The new options value.427        /// </param>428        /// <param name="force">429        /// If true the change to the options will happen even if the existing options are read-only.430        /// </param>431        internal void SetOptions(ScopedItemOptions newOptions, bool force)432        {433            // Check to see if the cmdlet is readonly, if so434            // throw an exception because the options cannot be changed.435 436            if ((_options & ScopedItemOptions.ReadOnly) != 0)437            {438                SessionStateUnauthorizedAccessException e =439                    new SessionStateUnauthorizedAccessException(440                            Name,441                            SessionStateCategory.Cmdlet,442                            "CmdletIsReadOnly",443                            SessionStateStrings.CmdletIsReadOnly);444 445                throw e;446            }447 448            _options = newOptions;449        }450 451        #endregion public members452 453        #region internal/private members454 455        /// <summary>456        /// Gets the full name of the cmdlet including the PSSnapin name.457        /// </summary>458        private static string GetFullName(string moduleName, string cmdletName)459        {460            System.Diagnostics.Debug.Assert(cmdletName != null, "cmdletName != null");461            string result = cmdletName;462            if (!string.IsNullOrEmpty(moduleName))463            {464                result = moduleName + '\\' + result;465            }466 467            return result;468        }469 470        /// <summary>471        /// Gets the full name of the cmdlet including the PSSnapin name.472        /// </summary>473        private static string GetFullName(CmdletInfo cmdletInfo)474        {475            return GetFullName(cmdletInfo.ModuleName, cmdletInfo.Name);476        }477 478        /// <summary>479        /// Gets the full name of the cmdlet including the PSSnapin name.480        /// </summary>481        internal static string GetFullName(PSObject psObject)482        {483            // If this is a high-fidelity object then extract full-name normally.484            if (psObject.BaseObject is CmdletInfo)485            {486                CmdletInfo cmdletInfo = (CmdletInfo)psObject.BaseObject;487                return GetFullName(cmdletInfo);488            }489 490            // Otherwise, it is a PSCustomObject shredded in a remote call: extract name as a property.491            else492            {493                // Handle the case in one or both of the properties might not be defined.494                PSPropertyInfo nameProperty = psObject.Properties["Name"];495                PSPropertyInfo psSnapInProperty = psObject.Properties["PSSnapIn"];496                string nameString = nameProperty == null ? string.Empty : (string)nameProperty.Value;497                string psSnapInString = psSnapInProperty == null ? string.Empty : (string)psSnapInProperty.Value;498                return GetFullName(psSnapInString, nameString);499            }500        }501 502        /// <summary>503        /// Gets the full name of the cmdlet including the PSSnapin name.504        /// </summary>505        internal string FullName506        {507            get508            {509                return GetFullName(this);510            }511        }512 513        /// <summary>514        /// Gets the CommandMetadata for this cmdlet.515        /// </summary>516        /// <exception cref="ArgumentException">517        /// The type name is invalid or the length of the type name518        /// exceeds 1024 characters.519        /// </exception>520        /// <exception cref="System.Security.SecurityException">521        /// The caller does not have the required permission to load the assembly522        /// or create the type.523        /// </exception>524        /// <exception cref="ParsingMetadataException">525        /// If more than int.MaxValue parameter-sets are defined for the command.526        /// </exception>527        /// <exception cref="MetadataException">528        /// If a parameter defines the same parameter-set name multiple times.529        /// If the attributes could not be read from a property or field.530        /// </exception>531        internal override CommandMetadata CommandMetadata532        {533            get534            {535                return _cmdletMetadata ??= CommandMetadata.Get(this.Name, this.ImplementingType, Context);536            }537        }538 539        private CommandMetadata _cmdletMetadata;540 541        internal override bool ImplementsDynamicParameters542        {543            get544            {545                if (ImplementingType != null)546                {547                    return (ImplementingType.GetInterface(nameof(IDynamicParameters), true) != null);548                }549                else550                {551                    return false;552                }553            }554        }555 556        #endregion internal/private members557    }558}559