コード例 #1
0
        /// <summary>
        /// Takes the remaining arguments that haven't been bound, and binds
        /// them to $args.
        /// </summary>
        /// <param name="arguments">
        ///     The remaining unbound arguments.
        /// </param>
        /// <remarks>
        /// An array containing the values that were bound to $args.
        /// </remarks>
        private void HandleRemainingArguments(Collection <CommandParameterInternal> arguments)
        {
            List <object> args = new List <object>();

            foreach (CommandParameterInternal parameter in arguments)
            {
                object argValue = parameter.ArgumentSpecified ? parameter.ArgumentValue : null;

                // Proper automatic proxy generation requires the ability to prevent unbound arguments
                // in the proxy from binding to positional parameters in the proxied command.  We use
                // a special key ("$args") when splatting @CommandLineArguments to package up $args.
                // This special key is not created automatically because it is useful to splat @args,
                // just not in the automatically generated proxy.
                //
                // Example usage:
                //
                //   function foo { param($a, $b) $a; $b; $args }
                //   function foo_proxy { param($a) ; $CommandLineArguments.Add('$args', $args); foo @CommandLineArguments }
                //   foo_proxy 1 2 3
                //
                // Then in foo, $a=1, $b=, $args=2,3
                //
                // Here, we want $b in foo to be unbound because the proxy doesn't have $b (an Exchange scenario.)
                // So we pass $args (2,3) in the special entry in @CommandLineArguments.  If we had instead written:
                //
                //   function foo_proxy { param($a) ; foo @CommandLineArguments @args }
                //   foo_proxy 1 2 3
                //
                // Then in foo, $a=1, $b=2, $args=3
                //
                // Note that the name $args is chosen to be:
                //   * descriptive
                //   * obscure (it can't be a property/field name in C#, and is an unlikely variable in script)
                // So we shouldn't have any real conflict.  Note that if someone actually puts ${$args} in their
                // param block, then the value will be bound and we won't have an unbound argument for "$args" here.
                if (parameter.ParameterAndArgumentSpecified &&
                    parameter.ParameterName.Equals("$args", StringComparison.OrdinalIgnoreCase))
                {
                    // $args is normally an object[], but because this feature is accessible from script, it's possible
                    // for it to contain anything.
                    if (argValue is object[])
                    {
                        args.AddRange(argValue as object[]);
                    }
                    else
                    {
                        args.Add(argValue);
                    }

                    continue;
                }

                if (parameter.ParameterNameSpecified)
                {
                    // Add a property to the string so we can tell the difference between:
                    //    foo -abc
                    //    foo "-abc"
                    // This is important when splatting, we reconstruct the parameter if the
                    // value is splatted.
                    var parameterText = new PSObject(new string(parameter.ParameterText.ToCharArray()));
                    if (parameterText.Properties[NotePropertyNameForSplattingParametersInArgs] == null)
                    {
                        var noteProperty = new PSNoteProperty(NotePropertyNameForSplattingParametersInArgs,
                                                              parameter.ParameterName)
                        {
                            IsHidden = true
                        };
                        parameterText.Properties.Add(noteProperty);
                    }

                    args.Add(parameterText);
                }

                if (parameter.ArgumentSpecified)
                {
                    args.Add(argValue);
                }
            }

            object[] argsArray = args.ToArray();

            DefaultParameterBinder.BindParameter(SpecialVariables.Args, argsArray, parameterMetadata: null);

            DollarArgs.AddRange(argsArray);

            return;
        }
コード例 #2
0
 /// <summary>
 /// Passes the binding directly through to the parameter binder.
 /// It does no verification against metadata.
 /// </summary>
 /// <param name="argument">
 /// The name and value of the variable to bind.
 /// </param>
 /// <param name="flags">
 /// Ignored.
 /// </param>
 /// <returns>
 /// True if the parameter was successfully bound. Any error condition
 /// produces an exception.
 /// </returns>
 internal override bool BindParameter(CommandParameterInternal argument, ParameterBindingFlags flags)
 {
     // Just pass the binding straight through.  No metadata to verify the parameter against.
     DefaultParameterBinder.BindParameter(argument.ParameterName, argument.ArgumentValue, parameterMetadata: null);
     return(true);
 }