/
githubmirror
/
PowerShell
Обзор
Документация
Войти
/
githubmirror
/
PowerShell
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
src/System.Management.Automation/engine/hostifaces/PSCommand.cs
517 строк
17 KB
Frode Flaten
Use null propagation operator in /engine (#17789)
29 июл 2022, 07:06
Не верифицирован
29 июл 2022, 07:06
4b4f1d1
Код
Авторство
О чём код?
// Copyright (c) Microsoft Corporation. // Licensed under the MIT License. using System.Management.Automation.Runspaces; using Dbg = System.Management.Automation.Diagnostics; namespace System.Management.Automation { /// <summary> /// Defines a PowerShell command / script object which can be used with /// <see cref="PowerShell"/> object. /// </summary> public sealed class PSCommand { #region Private Fields private PowerShell _owner; private CommandCollection _commands; private Command _currentCommand; #endregion #region Constructor /// <summary> /// Creates an empty PSCommand; a command or script must be added to this PSCommand before it can be executed. /// </summary> public PSCommand() { Initialize(null, false, null); } /// <summary> /// Internal copy constructor. /// </summary> /// <param name="commandToClone"></param> internal PSCommand(PSCommand commandToClone) { _commands = new CommandCollection(); foreach (Command command in commandToClone.Commands) { Command clone = command.Clone(); // Attach the cloned Command to this instance. _commands.Add(clone); _currentCommand = clone; } } /// <summary> /// Creates a PSCommand from the specified command. /// </summary> /// <param name="command">Command object to use.</param> internal PSCommand(Command command) { _currentCommand = command; _commands = new CommandCollection(); _commands.Add(_currentCommand); } #endregion #region Command / Parameter Construction /// <summary> /// Add a command to construct a command pipeline. /// For example, to construct a command string "get-process | sort-object", /// <code> /// PSCommand command = new PSCommand("get-process").AddCommand("sort-object"); /// </code> /// </summary> /// <param name="command"> /// A string representing the command. /// </param> /// <exception cref="InvalidPowerShellStateException"> /// Powershell instance cannot be changed in its /// current state. /// </exception> /// <returns> /// A PSCommand instance with <paramref name="command"/> added. /// </returns> /// <remarks> /// This method is not thread safe. /// </remarks> /// <exception cref="ArgumentNullException"> /// cmdlet is null. /// </exception> public PSCommand AddCommand(string command) { if (command == null) { throw PSTraceSource.NewArgumentNullException(nameof(command)); } _owner?.AssertChangesAreAccepted(); _currentCommand = new Command(command, false); _commands.Add(_currentCommand); return this; } /// <summary> /// Add a cmdlet to construct a command pipeline. /// For example, to construct a command string "get-process | sort-object", /// <code> /// PSCommand command = new PSCommand("get-process").AddCommand("sort-object"); /// </code> /// </summary> /// <param name="cmdlet"> /// A string representing cmdlet. /// </param> /// <param name="useLocalScope"> /// if true local scope is used to run the script command. /// </param> /// <exception cref="InvalidPowerShellStateException"> /// Powershell instance cannot be changed in its /// current state. /// </exception> /// <returns> /// A PSCommand instance with <paramref name="cmdlet"/> added. /// </returns> /// <remarks> /// This method is not thread safe. /// </remarks> /// <exception cref="ArgumentNullException"> /// cmdlet is null. /// </exception> public PSCommand AddCommand(string cmdlet, bool useLocalScope) { if (cmdlet == null) { throw PSTraceSource.NewArgumentNullException(nameof(cmdlet)); } _owner?.AssertChangesAreAccepted(); _currentCommand = new Command(cmdlet, false, useLocalScope); _commands.Add(_currentCommand); return this; } /// <summary> /// Add a piece of script to construct a command pipeline. /// For example, to construct a command string "get-process | foreach { $_.Name }" /// <code> /// PSCommand command = new PSCommand("get-process") /// .AddScript("foreach { $_.Name }", true); /// </code> /// </summary> /// <param name="script"> /// A string representing the script. /// </param> /// <returns> /// A PSCommand instance with <paramref name="script"/> added. /// </returns> /// <remarks> /// This method is not thread-safe. /// </remarks> /// <exception cref="ArgumentNullException"> /// command is null. /// </exception> /// <exception cref="InvalidPowerShellStateException"> /// Powershell instance cannot be changed in its /// current state. /// </exception> public PSCommand AddScript(string script) { if (script == null) { throw PSTraceSource.NewArgumentNullException(nameof(script)); } _owner?.AssertChangesAreAccepted(); _currentCommand = new Command(script, true); _commands.Add(_currentCommand); return this; } /// <summary> /// Add a piece of script to construct a command pipeline. /// For example, to construct a command string "get-process | foreach { $_.Name }" /// <code> /// PSCommand command = new PSCommand("get-process") /// .AddScript("foreach { $_.Name }", true); /// </code> /// </summary> /// <param name="script"> /// A string representing the script. /// </param> /// <param name="useLocalScope"> /// if true local scope is used to run the script command. /// </param> /// <returns> /// A PSCommand instance with <paramref name="script"/> added. /// </returns> /// <remarks> /// This method is not thread-safe. /// </remarks> /// <exception cref="ArgumentNullException"> /// command is null. /// </exception> /// <exception cref="InvalidPowerShellStateException"> /// Powershell instance cannot be changed in its /// current state. /// </exception> public PSCommand AddScript(string script, bool useLocalScope) { if (script == null) { throw PSTraceSource.NewArgumentNullException(nameof(script)); } _owner?.AssertChangesAreAccepted(); _currentCommand = new Command(script, true, useLocalScope); _commands.Add(_currentCommand); return this; } /// <summary> /// Add a <see cref="Command"/> element to the current command /// pipeline. /// </summary> /// <param name="command"> /// Command to add. /// </param> /// <returns> /// A PSCommand instance with <paramref name="command"/> added. /// </returns> /// <remarks> /// This method is not thread-safe. /// </remarks> /// <exception cref="ArgumentNullException"> /// command is null. /// </exception> /// <exception cref="InvalidPowerShellStateException"> /// Powershell instance cannot be changed in its /// current state. /// </exception> public PSCommand AddCommand(Command command) { if (command == null) { throw PSTraceSource.NewArgumentNullException(nameof(command)); } _owner?.AssertChangesAreAccepted(); _currentCommand = command; _commands.Add(_currentCommand); return this; } /// <summary> /// Add a parameter to the last added command. /// For example, to construct a command string "get-process | select-object -property name" /// <code> /// PSCommand command = new PSCommand("get-process") /// .AddCommand("select-object") /// .AddParameter("property", "name"); /// </code> /// </summary> /// <param name="parameterName"> /// Name of the parameter. /// </param> /// <param name="value"> /// Value for the parameter. /// </param> /// <returns> /// A PSCommand instance with <paramref name="parameterName"/> added /// to the parameter list of the last command. /// </returns> /// <remarks> /// This method is not thread safe. /// </remarks> /// <exception cref="ArgumentException"> /// Name is non null and name length is zero after trimming whitespace. /// </exception> /// <exception cref="InvalidPowerShellStateException"> /// Powershell instance cannot be changed in its /// current state. /// </exception> public PSCommand AddParameter(string parameterName, object value) { if (_currentCommand == null) { throw PSTraceSource.NewInvalidOperationException(PSCommandStrings.ParameterRequiresCommand, new object[] { "PSCommand" }); } _owner?.AssertChangesAreAccepted(); _currentCommand.Parameters.Add(parameterName, value); return this; } /// <summary> /// Adds a switch parameter to the last added command. /// For example, to construct a command string "get-process | sort-object -descending" /// <code> /// PSCommand command = new PSCommand("get-process") /// .AddCommand("sort-object") /// .AddParameter("descending"); /// </code> /// </summary> /// <param name="parameterName"> /// Name of the parameter. /// </param> /// <returns> /// A PSCommand instance with <paramref name="parameterName"/> added /// to the parameter list of the last command. /// </returns> /// <remarks> /// This method is not thread safe. /// </remarks> /// <exception cref="ArgumentException"> /// Name is non null and name length is zero after trimming whitespace. /// </exception> /// <exception cref="InvalidPowerShellStateException"> /// Powershell instance cannot be changed in its /// current state. /// </exception> public PSCommand AddParameter(string parameterName) { if (_currentCommand == null) { throw PSTraceSource.NewInvalidOperationException(PSCommandStrings.ParameterRequiresCommand, new object[] { "PSCommand" }); } _owner?.AssertChangesAreAccepted(); _currentCommand.Parameters.Add(parameterName, true); return this; } /// <summary> /// Adds a <see cref="CommandParameter"/> instance to the last added command. /// </summary> internal PSCommand AddParameter(CommandParameter parameter) { if (_currentCommand == null) { throw PSTraceSource.NewInvalidOperationException(PSCommandStrings.ParameterRequiresCommand, new object[] { "PSCommand" }); } _owner?.AssertChangesAreAccepted(); _currentCommand.Parameters.Add(parameter); return this; } /// <summary> /// Adds an argument to the last added command. /// For example, to construct a command string "get-process | select-object name" /// <code> /// PSCommand command = new PSCommand("get-process") /// .AddCommand("select-object") /// .AddArgument("name"); /// </code> /// This will add the value "name" to the positional parameter list of "select-object" /// cmdlet. When the command is invoked, this value will get bound to positional parameter 0 /// of the "select-object" cmdlet which is "Property". /// </summary> /// <param name="value"> /// Value for the parameter. /// </param> /// <returns> /// A PSCommand instance parameter value <paramref name="value"/> added /// to the parameter list of the last command. /// </returns> /// <exception cref="InvalidPowerShellStateException"> /// Powershell instance cannot be changed in its /// current state. /// </exception> /// <remarks> /// This method is not thread safe. /// </remarks> public PSCommand AddArgument(object value) { if (_currentCommand == null) { throw PSTraceSource.NewInvalidOperationException(PSCommandStrings.ParameterRequiresCommand, new object[] { "PSCommand" }); } _owner?.AssertChangesAreAccepted(); _currentCommand.Parameters.Add(null, value); return this; } /// <summary> /// Adds an additional statement for execution /// /// For example, /// <code> /// Runspace rs = RunspaceFactory.CreateRunspace(); /// PowerShell ps = PowerShell.Create(); /// /// ps.Runspace = rs; /// ps.AddCommand("Get-Process").AddArgument("idle"); /// ps.AddStatement().AddCommand("Get-Service").AddArgument("audiosrv"); /// ps.Invoke(); /// </code> /// </summary> /// <returns> /// A PowerShell instance with the items in <paramref name="parameters"/> added /// to the parameter list of the last command. /// </returns> public PSCommand AddStatement() { if (_commands.Count == 0) { return this; } _commands[_commands.Count - 1].IsEndOfStatement = true; return this; } #endregion #region Properties and Methods /// <summary> /// Gets the collection of commands from this PSCommand /// instance. /// </summary> public CommandCollection Commands { get { return _commands; } } /// <summary> /// The PowerShell instance this PSCommand is associated to, or null if it is an standalone command. /// </summary> internal PowerShell Owner { get { return _owner; } set { _owner = value; } } /// <summary> /// Clears the command(s). /// </summary> public void Clear() { _commands.Clear(); _currentCommand = null; } /// <summary> /// Creates a shallow copy of the current PSCommand. /// </summary> /// <returns> /// A shallow copy of the current PSCommand /// </returns> public PSCommand Clone() { return new PSCommand(this); } #endregion #region Private Methods /// <summary> /// Initializes the instance. Called from the constructor. /// </summary> /// <param name="command"> /// Command to initialize the instance with. /// </param> /// <param name="isScript"> /// true if the <paramref name="command"/> is script, /// false otherwise. /// </param> /// <param name="useLocalScope"> /// if true local scope is used to run the script command. /// </param> /// <remarks> /// Caller should check the input. /// </remarks> /// <exception cref="ArgumentNullException"> /// command is null /// </exception> private void Initialize(string command, bool isScript, bool? useLocalScope) { _commands = new CommandCollection(); if (command != null) { _currentCommand = new Command(command, isScript, useLocalScope); _commands.Add(_currentCommand); } } #endregion } }