MegaBites-AI/Windows-powershell
0308
1// Copyright (c) Microsoft Corporation.2// Licensed under the MIT License.3 4using System.Collections.Generic;5using System.Collections.ObjectModel;6 7namespace System.Management.Automation8{9 /// <summary>10 /// Provides information about a mapping between a command name and a real command.11 /// </summary>12 public class AliasInfo : CommandInfo13 {14 #region ctor15 16 /// <summary>17 /// Creates an instance of the AliasInfo class with the specified name and referenced command.18 /// </summary>19 /// <param name="name">20 /// The name of the command.21 /// </param>22 /// <param name="definition">23 /// The token that the alias refers to.24 /// </param>25 /// <param name="context">26 /// The execution context for this engine, used to lookup the current session state.27 /// </param>28 /// <exception cref="ArgumentException">29 /// If <paramref name="definition"/> is null or empty.30 /// </exception>31 /// <exception cref="ArgumentNullException">32 /// If <paramref name="context"/> is null.33 /// </exception>34 internal AliasInfo(string name, string definition, ExecutionContext context) : base(name, CommandTypes.Alias)35 {36 _definition = definition;37 this.Context = context;38 39 if (context != null)40 {41 this.Module = context.SessionState.Internal.Module;42 }43 }44 45 /// <summary>46 /// Creates an instance of the AliasInfo class with the specified name and referenced command.47 /// </summary>48 /// <param name="name">49 /// The name of the command.50 /// </param>51 /// <param name="definition">52 /// The token that the alias refers to.53 /// </param>54 /// <param name="context">55 /// The execution context for this engine instance, used to look up session state.56 /// </param>57 /// <param name="options">58 /// The options to set on the alias. Note, Constant can only be set at creation time.59 /// </param>60 /// <exception cref="ArgumentException">61 /// If <paramref name="definition"/> is null or empty.62 /// </exception>63 /// <exception cref="ArgumentNullException">64 /// If <paramref name="context"/> is null.65 /// </exception>66 internal AliasInfo(67 string name,68 string definition,69 ExecutionContext context,70 ScopedItemOptions options) : base(name, CommandTypes.Alias)71 {72 _definition = definition;73 this.Context = context;74 _options = options;75 76 if (context != null)77 {78 this.Module = context.SessionState.Internal.Module;79 }80 }81 82 #endregion ctor83 84 internal override HelpCategory HelpCategory85 {86 get { return HelpCategory.Alias; }87 }88 89 /// <summary>90 /// Gets the command information for the command that is immediately referenced by this alias.91 /// </summary>92 public CommandInfo ReferencedCommand93 {94 get95 {96 // Need to lookup the referenced command every time97 // to ensure we get the latest session state information98 99 CommandInfo referencedCommand = null;100 101 if ((_definition != null) && (Context != null))102 {103 CommandSearcher commandSearcher =104 new CommandSearcher(105 _definition,106 SearchResolutionOptions.None,107 CommandTypes.All,108 Context);109 110 if (commandSearcher.MoveNext())111 {112 System.Collections.Generic.IEnumerator<CommandInfo> ie = commandSearcher;113 referencedCommand = ie.Current;114 // referencedCommand = commandSearcher.Current;115 }116 }117 118 return referencedCommand;119 }120 }121 122 /// <summary>123 /// Gets the command information for the command that124 /// the alias eventually resolves to.125 /// </summary>126 /// <remarks>127 /// An alias may reference another alias. This property follows the reference128 /// chain of aliases to its end.129 /// </remarks>130 /// <!--131 /// If the command didn't resolve to anything but aliases, the UnresolvedCommandName132 /// property contains the last name the resolution succeeded in finding.133 /// -->134 public CommandInfo ResolvedCommand135 {136 get137 {138 // Need to lookup the resolved command every time to ensure139 // we use the latest session state information140 141 CommandInfo result = null;142 143 if (_definition != null)144 {145 List<string> cyclePrevention = new List<string>();146 cyclePrevention.Add(Name);147 148 string commandNameToResolve = _definition;149 result = ReferencedCommand;150 while (result != null && result.CommandType == CommandTypes.Alias)151 {152 result = ((AliasInfo)result).ReferencedCommand;153 154 if (result is AliasInfo)155 {156 // Check for the cycle by checking for the alias name157 // in the cyclePrevention dictionary158 159 if (SessionStateUtilities.CollectionContainsValue(cyclePrevention, result.Name, StringComparer.OrdinalIgnoreCase))160 {161 result = null;162 break;163 }164 165 cyclePrevention.Add(result.Name);166 167 commandNameToResolve = result.Definition;168 }169 }170 171 if (result == null)172 {173 // Since we couldn't resolve the command that the alias174 // points to, remember the definition so that we can175 // provide better error reporting.176 177 UnresolvedCommandName = commandNameToResolve;178 }179 }180 181 return result;182 }183 }184 185 /// <summary>186 /// Gets the name of the command to which the alias refers.187 /// </summary>188 public override string Definition189 {190 get191 {192 return _definition;193 }194 }195 196 private string _definition = string.Empty;197 198 /// <summary>199 /// Sets the new definition for the alias.200 /// </summary>201 /// <param name="definition">202 /// The new definition for the alias.203 /// </param>204 /// <param name="force">205 /// If true, the value will be set even if the alias is ReadOnly.206 /// </param>207 /// <exception cref="SessionStateUnauthorizedAccessException">208 /// If the alias is readonly or constant.209 /// </exception>210 internal void SetDefinition(string definition, bool force)211 {212 // Check to see if the variable is writable213 214 if ((_options & ScopedItemOptions.Constant) != 0 ||215 (!force && (_options & ScopedItemOptions.ReadOnly) != 0))216 {217 SessionStateUnauthorizedAccessException e =218 new SessionStateUnauthorizedAccessException(219 Name,220 SessionStateCategory.Alias,221 "AliasNotWritable",222 SessionStateStrings.AliasNotWritable);223 224 throw e;225 }226 227 _definition = definition;228 }229 230 /// <summary>231 /// Gets or sets the scope options for the alias.232 /// </summary>233 /// <exception cref="System.Management.Automation.SessionStateUnauthorizedAccessException">234 /// If the trying to set an alias that is constant or235 /// if the value trying to be set is ScopedItemOptions.Constant236 /// </exception>237 public ScopedItemOptions Options238 {239 get240 {241 return _options;242 }243 244 set245 {246 SetOptions(value, false);247 }248 }249 250 /// <summary>251 /// Sets the options for the alias and allows changes ReadOnly options only if force is specified.252 /// </summary>253 /// <param name="newOptions">254 /// The new options value.255 /// </param>256 /// <param name="force">257 /// If true the change to the options will happen even if the existing options are read-only.258 /// </param>259 internal void SetOptions(ScopedItemOptions newOptions, bool force)260 {261 // Check to see if the variable is constant, if so262 // throw an exception because the options cannot be changed.263 264 if ((_options & ScopedItemOptions.Constant) != 0)265 {266 SessionStateUnauthorizedAccessException e =267 new SessionStateUnauthorizedAccessException(268 Name,269 SessionStateCategory.Alias,270 "AliasIsConstant",271 SessionStateStrings.AliasIsConstant);272 273 throw e;274 }275 276 // Check to see if the variable is readonly, if so277 // throw an exception because the options cannot be changed.278 279 if (!force && (_options & ScopedItemOptions.ReadOnly) != 0)280 {281 SessionStateUnauthorizedAccessException e =282 new SessionStateUnauthorizedAccessException(283 Name,284 SessionStateCategory.Alias,285 "AliasIsReadOnly",286 SessionStateStrings.AliasIsReadOnly);287 288 throw e;289 }290 291 // Now check to see if the caller is trying to set292 // the options to constant. This is only allowed at293 // variable creation294 295 if ((newOptions & ScopedItemOptions.Constant) != 0)296 {297 // user is trying to set the variable to constant after298 // creating the variable. Do not allow this (as per spec).299 300 SessionStateUnauthorizedAccessException e =301 new SessionStateUnauthorizedAccessException(302 Name,303 SessionStateCategory.Alias,304 "AliasCannotBeMadeConstant",305 SessionStateStrings.AliasCannotBeMadeConstant);306 307 throw e;308 }309 310 if ((newOptions & ScopedItemOptions.AllScope) == 0 &&311 (_options & ScopedItemOptions.AllScope) != 0)312 {313 // user is trying to remove the AllScope option from the alias.314 // Do not allow this (as per spec).315 316 SessionStateUnauthorizedAccessException e =317 new SessionStateUnauthorizedAccessException(318 this.Name,319 SessionStateCategory.Alias,320 "AliasAllScopeOptionCannotBeRemoved",321 SessionStateStrings.AliasAllScopeOptionCannotBeRemoved);322 323 throw e;324 }325 326 _options = newOptions;327 }328 329 private ScopedItemOptions _options = ScopedItemOptions.None;330 331 /// <summary>332 /// Gets or sets the description for the alias.333 /// </summary>334 public string Description { get; set; } = string.Empty;335 336 /// <summary>337 /// If ResolvedCommand returns null, this property will338 /// return the name of the command that could not be resolved.339 /// If ResolvedCommand has not yet been called or was able340 /// to resolve the command, this property will return null.341 /// </summary>342 internal string UnresolvedCommandName { get; private set; }343 344 /// <summary>345 /// The objects output from an alias are the objects output from the resolved346 /// command. If we can't resolve the command, assume nothing is output - so use void.347 /// </summary>348 public override ReadOnlyCollection<PSTypeName> OutputType349 {350 get351 {352 CommandInfo resolvedCommand = this.ResolvedCommand;353 if (resolvedCommand != null)354 {355 return resolvedCommand.OutputType;356 }357 358 return null;359 }360 }361 }362}363 