Beispiel #1
0
        // internals
        //internal CmdletInfo CreateGetCommandCopy(CmdletInfo cmdletInfo, object[] arguments);
        //internal object[] Arguments { set; get; }
        //internal string FullName { get; }
        //internal bool IsGetCommandCopy { set; get; }

        private CommandParameterInfo AddParameterToParameterSet(Dictionary <string, Collection <CommandParameterInfo> > paramSets,
                                                                MemberInfo memberInfo, Type type, ParameterAttribute paramAttr)
        {
            CommandParameterInfo pi = new CommandParameterInfo(memberInfo, type, paramAttr);
            var paramSetName        = paramAttr.ParameterSetName;

            // Determine if this parameter is uniquely defined for one set and rember it
            if (!String.IsNullOrEmpty(paramSetName) && !paramSetName.Equals(ParameterAttribute.AllParameterSets))
            {
                var parameterName = pi.Name;
                // check if we already defined that parameter for another set
                if (UniqueSetParameters.ContainsKey(parameterName))
                {
                    UniqueSetParameters[parameterName] = null;
                }
                else
                {
                    // not yet in any set, it's a candidate for a unique parameter
                    UniqueSetParameters[parameterName] = paramSetName;
                }
            }

            paramSetName = paramSetName ?? ParameterAttribute.AllParameterSets;

            if (!paramSets.ContainsKey(paramSetName))
            {
                paramSets.Add(paramSetName, new Collection <CommandParameterInfo>());
            }

            Collection <CommandParameterInfo> paramSet = paramSets[paramSetName];

            paramSet.Add(pi);
            return(pi);
        }
Beispiel #2
0
        private static void AppendFormatCommandParameterInfo(CommandParameterInfo parameter, Text.StringBuilder result)
        {
            if (result.Length > 0)
            {
                // Add a space between parameters
                result.Append(" ");
            }

            if (parameter.ParameterType == typeof(SwitchParameter))
            {
                result.AppendFormat(CultureInfo.InvariantCulture, parameter.IsMandatory ? "-{0}" : "[-{0}]", parameter.Name);
            }
            else
            {
                string parameterTypeString = GetParameterTypeString(parameter.ParameterType, parameter.Attributes);

                if (parameter.IsMandatory)
                {
                    result.AppendFormat(CultureInfo.InvariantCulture,
                                        parameter.Position != int.MinValue ? "[-{0}] <{1}>" : "-{0} <{1}>",
                                        parameter.Name, parameterTypeString);
                }
                else
                {
                    result.AppendFormat(CultureInfo.InvariantCulture,
                                        parameter.Position != int.MinValue ? "[[-{0}] <{1}>]" : "[-{0} <{1}>]",
                                        parameter.Name, parameterTypeString);
                }
            }
        }
        private void BindParameter(CommandParameterInfo info, object value, bool doConvert)
        {
            var memberInfo = info.MemberInfo;

            if (_boundParameters.Contains(memberInfo))
            {
                var msg = String.Format("Parameter '{0}' has already been bound!", info.Name);
                throw new ParameterBindingException(msg);
            }

            foreach (var attr in info.TransformationAttributes)
            {
                value = attr.Transform(_engineIntrinsics, value);
            }

            // ConvertTo throws an exception if conversion isn't possible. That's just fine.
            if (doConvert)
            {
                value = LanguagePrimitives.ConvertTo(value, info.ParameterType);
            }
            // TODO: validate value with Attributes (ValidateNotNullOrEmpty, etc)
            SetCommandValue(memberInfo, value);
            // make sure to update the candidate set to only consider parameter sets with the newly bound parameter
            RestrictCandidatesByBoundParameter(info);
            _boundParameters.Add(memberInfo);
        }
 private bool TryBindParameter(CommandParameterInfo info, object value, bool doConvert)
 {
     try
     {
         BindParameter(info, value, doConvert);
         return(true);
     }
     catch (Exception)
     {
         return(false);
     }
 }
Beispiel #5
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="obj"></param>
        /// <remarks>
        /// All abount Cmdlet parameters: http://msdn2.microsoft.com/en-us/library/ms714433(VS.85).aspx
        /// </remarks>
        internal override void BindArguments(PSObject obj)
        {
            if ((obj == null) && (Parameters.Count == 0))
            {
                return;
            }

            // TODO: bind the arguments to the parameters
            CommandParameterSetInfo paramSetInfo = _cmdletInfo.GetDefaultParameterSet();

            // TODO: refer to the Command._ParameterSetName for a param set name

            if (obj != null)
            {
                foreach (CommandParameterInfo paramInfo in paramSetInfo.Parameters)
                {
                    if (paramInfo.ValueFromPipeline)
                    {
                        BindArgument(paramInfo.Name, obj, paramInfo.ParameterType);
                    }
                }
            }

            if (Parameters.Count > 0)
            {
                // bind by position location
                for (int i = 0; i < Parameters.Count; i++)
                {
                    CommandParameterInfo paramInfo = null;

                    CommandParameter parameter = Parameters[i];

                    if (string.IsNullOrEmpty(parameter.Name))
                    {
                        paramInfo = paramSetInfo.GetParameterByPosition(i);

                        if (paramInfo != null)
                        {
                            BindArgument(paramInfo.Name, parameter.Value, paramInfo.ParameterType);
                        }
                    }
                    else
                    {
                        paramInfo = paramSetInfo.GetParameterByName(parameter.Name);

                        if (paramInfo != null)
                        {
                            BindArgument(paramInfo.Name, parameter.Value, paramInfo.ParameterType);
                        }
                    }
                }
            }
        }
        // restricts the candidate parameter sets by the newly bound parameters
        private void RestrictCandidatesByBoundParameter(CommandParameterInfo info)
        {
            var setsContaining = from paramSet in _cmdletInfo.ParameterSets
                                 where paramSet.Contains(info) select paramSet;

            _candidateParameterSets = _candidateParameterSets.Intersect(setsContaining).ToList();
            if (_candidateParameterSets.Count == 0)
            {
                ThrowAmbiguousParameterSetException();
            }
            else if (_candidateParameterSets.Count == 1)
            {
                _activeSet = _candidateParameterSets[0];
            }
        }
Beispiel #7
0
        private void AddParameterToParameterSet(Dictionary <string, Collection <CommandParameterInfo> > paramSets,
                                                CommandParameterInfo paramInfo)
        {
            var paramSetName = paramInfo.ParameterSetName;

            // create the parameter set if it doesn't exist, yet
            if (!paramSets.ContainsKey(paramSetName))
            {
                paramSets.Add(paramSetName, new Collection <CommandParameterInfo>());
            }
            Collection <CommandParameterInfo> paramSet = paramSets[paramSetName];

            // actually add parameter to the set
            paramSet.Add(paramInfo);
        }
Beispiel #8
0
        private void BindParameter(CommandParameterInfo info, object value, bool doConvert)
        {
            var memberInfo = info.MemberInfo;

            if (_boundParameters.Contains(memberInfo))
            {
                var msg = String.Format("Parameter '{0}' has already been bound!", info.Name);
                throw new ParameterBindingException(msg);
            }
            // ConvertTo throws an exception if conversion isn't possible. That's just fine.
            if (doConvert)
            {
                value = LanguagePrimitives.ConvertTo(value, info.ParameterType);
            }
            SetCommandValue(memberInfo, value);
            _boundParameters.Add(memberInfo);
        }
Beispiel #9
0
        private void RegisterParameter(CommandParameterInfo parameterInfo)
        {
            // also add it to lookuptable and check for unuque names/aliases
            var allNames = parameterInfo.Aliases.ToList();

            allNames.Add(parameterInfo.Name);
            foreach (var curName in allNames)
            {
                if (ParameterInfoLookupTable.ContainsKey(curName))
                {
                    // save exception to be thrown when this object is validated, not now
                    var msg = String.Format("The name or alias '{0}' is used multiple times.", curName);
                    _validationException = new MetadataException(msg);
                    continue;
                }
                ParameterInfoLookupTable[curName] = parameterInfo;
            }
        }
        /// <summary>
        /// Creates an instance of the ShowCommandParameterInfo class based on a CommandParameterInfo object
        /// </summary>
        /// 
        /// <param name="other">
        /// The object to wrap.
        /// </param>
        public ShowCommandParameterInfo(CommandParameterInfo other)
        {
            if (null == other)
            {
                throw new ArgumentNullException("other");
            }

            this.Name = other.Name;
            this.IsMandatory = other.IsMandatory;
            this.ValueFromPipeline = other.ValueFromPipeline;
            this.ParameterType = new ShowCommandParameterType(other.ParameterType);
            this.Position = other.Position;

            var validateSetAttribute = other.Attributes.Where(x => typeof(ValidateSetAttribute).IsAssignableFrom(x.GetType())).Cast<ValidateSetAttribute>().LastOrDefault();
            if (validateSetAttribute != null)
            {
                this.HasParameterSet = true;
                this.ValidParamSetValues = validateSetAttribute.ValidValues;
            }
        }
Beispiel #11
0
        // internals
        //internal CmdletInfo CreateGetCommandCopy(CmdletInfo cmdletInfo, object[] arguments);
        //internal object[] Arguments { set; get; }
        //internal string FullName { get; }
        //internal bool IsGetCommandCopy { set; get; }

        private CommandParameterInfo AddParameterToParameterSet(Dictionary <string, Collection <CommandParameterInfo> > paramSets,
                                                                MemberInfo memberInfo, Type type, ParameterAttribute paramAttr)
        {
            CommandParameterInfo pi = new CommandParameterInfo(memberInfo, type, paramAttr);
            var paramSetName        = paramAttr.ParameterSetName;

            // Determine if this parameter is uniquely defined for one set and rember it

            paramSetName = paramSetName ?? ParameterAttribute.AllParameterSets;

            if (!paramSets.ContainsKey(paramSetName))
            {
                paramSets.Add(paramSetName, new Collection <CommandParameterInfo>());
            }

            Collection <CommandParameterInfo> paramSet = paramSets[paramSetName];

            paramSet.Add(pi);
            return(pi);
        }
        internal CommandParameterInfo LookupParameter(string name)
        {
            CommandParameterInfo found = null;

            foreach (CommandParameterInfo parameter in Parameters)
            {
                if (parameter.Name.StartsWith(name, StringComparison.CurrentCultureIgnoreCase) ||
                    (parameter.Aliases != null && parameter.Aliases.Where(a => a.StartsWith(name, StringComparison.CurrentCultureIgnoreCase)).Count() > 0))
                {
                    // If match already found, name is ambiguous
                    if (found != null)
                    {
                        //TODO: Throw ParameterBindingException when implemented
                        throw new ArgumentException("Supplied parmameter '" + name + "' is ambiguous, possibilities include '" + found.Name + "' and '" + parameter.Name + "'");
                    }
                    found = parameter;
                }
            }

            return(found);
        }
 private static void AppendFormatCommandParameterInfo(
     CommandParameterInfo parameter,
     ref StringBuilder result)
 {
     if (result.Length > 0)
     {
         result.Append(" ");
     }
     if (parameter.ParameterType == typeof(bool) || parameter.ParameterType == typeof(SwitchParameter))
     {
         if (parameter.IsMandatory)
         {
             result.AppendFormat("-{0}", (object)parameter.Name);
         }
         else
         {
             result.AppendFormat("[-{0}]", (object)parameter.Name);
         }
     }
     else if (parameter.IsMandatory)
     {
         if (parameter.Position != int.MinValue)
         {
             result.AppendFormat("[-{0}] <{1}>", (object)parameter.Name, (object)parameter.ParameterType.Name.ToString());
         }
         else
         {
             result.AppendFormat("-{0} <{1}>", (object)parameter.Name, (object)parameter.ParameterType.Name.ToString());
         }
     }
     else if (parameter.Position != int.MinValue)
     {
         result.AppendFormat("[[-{0}] <{1}>]", (object)parameter.Name, (object)parameter.ParameterType.Name.ToString());
     }
     else
     {
         result.AppendFormat("[-{0} <{1}>]", (object)parameter.Name, (object)parameter.ParameterType.Name.ToString());
     }
 }
 private static void AppendFormatCommandParameterInfo(CommandParameterInfo parameter, ref StringBuilder result)
 {
     if (result.Length > 0)
     {
         result.Append(" ");
     }
     if (parameter.ParameterType == typeof(SwitchParameter))
     {
         result.AppendFormat(parameter.IsMandatory ? "-{0}" : "[-{0}]", parameter.Name);
     }
     else
     {
         string parameterTypeString = GetParameterTypeString(parameter.ParameterType, parameter.Attributes);
         if (parameter.IsMandatory)
         {
             result.AppendFormat((parameter.Position != -2147483648) ? "[-{0}] <{1}>" : "-{0} <{1}>", parameter.Name, parameterTypeString);
         }
         else
         {
             result.AppendFormat((parameter.Position != -2147483648) ? "[[-{0}] <{1}>]" : "[-{0} <{1}>]", parameter.Name, parameterTypeString);
         }
     }
 }
Beispiel #15
0
 private static void AppendFormatCommandParameterInfo(CommandParameterInfo parameter, ref StringBuilder result)
 {
     if (result.Length > 0)
     {
         result.Append(" ");
     }
     if (parameter.ParameterType == typeof(SwitchParameter))
     {
         result.AppendFormat(parameter.IsMandatory ? "-{0}" : "[-{0}]", parameter.Name);
     }
     else
     {
         string parameterTypeString = GetParameterTypeString(parameter.ParameterType, parameter.Attributes);
         if (parameter.IsMandatory)
         {
             result.AppendFormat((parameter.Position != -2147483648) ? "[-{0}] <{1}>" : "-{0} <{1}>", parameter.Name, parameterTypeString);
         }
         else
         {
             result.AppendFormat((parameter.Position != -2147483648) ? "[[-{0}] <{1}>]" : "[-{0} <{1}>]", parameter.Name, parameterTypeString);
         }
     }
 }
Beispiel #16
0
        /// <remarks>
        /// From MSDN article: http://msdn2.microsoft.com/en-us/library/ms714348(VS.85).aspx
        ///
        /// * A cmdlet can have any number of parameters. However, for a better user experience the number
        ///   of parameters should be limited when possible.
        /// * Parameters must be declared on public non-static fields or properties. It is preferred for
        ///   parameters to be declared on properties. The property must have a public setter, and if ValueFromPipeline
        ///   or ValueFromPipelineByPropertyName is specified the property must have a public getter.
        /// * When specifying positional parameters, note the following.
        ///   * Limit the number of positional parameters in a parameter set to less than five if possible.
        ///   * Positional parameters do not have to be sequential; positions 5, 100, 250 works the same as positions 0, 1, 2.
        /// * When the Position keyword is not specified, the cmdlet parameter must be referenced by its name.
        /// * When using parameter sets, no parameter set should contain more than one positional parameter with the same position.
        /// * In addition, only one parameter in a set should declare ValueFromPipeline = true. Multiple parameters may define ValueFromPipelineByPropertyName = true.
        ///
        /// </remarks>
        private void GetParameterSetInfo(Type cmdletType)
        {
            Dictionary <string, Collection <CommandParameterInfo> > paramSets = new Dictionary <string, Collection <CommandParameterInfo> >(StringComparer.CurrentCultureIgnoreCase);

            // TODO: When using parameter sets, no parameter set should contain more than one positional parameter with the same position.
            // TODO: If not parameters have a position declared then positions for all the parameters should be automatically declaredin the order they are specified
            // TODO: Only one parameter in a set should declare ValueFromRemainingArguments = true
            // TODO: Only one parameter in a set should declare ValueFromPipeline = true. Multiple parameters may define ValueFromPipelineByPropertyName = true.
            // TODO: Currently due to the way parameters are loaded into sets from all set at the end the parameter end up in incorrect order.

            // get the name of the default parameter set
            string strDefaultParameterSetName = null;

            object[] cmdLetAttrs = cmdletType.GetCustomAttributes(typeof(CmdletAttribute), false);
            if (cmdLetAttrs.Length > 0)
            {
                strDefaultParameterSetName = ((CmdletAttribute)cmdLetAttrs[0]).DefaultParameterSetName;
                // If a default set is specified, it has to exist, even if it's empty.
                // See NonExisitingDefaultParameterSetIsEmptyPatameterSet reference test
                if (!String.IsNullOrEmpty(strDefaultParameterSetName))
                {
                    paramSets.Add(strDefaultParameterSetName, new Collection <CommandParameterInfo>());
                }
            }

            // always have a parameter set for all parameters. even if we don't have any parameters or no parameters
            // that are in all sets. This will nevertheless save various checks
            if (!paramSets.ContainsKey(ParameterAttribute.AllParameterSets))
            {
                paramSets.Add(ParameterAttribute.AllParameterSets, new Collection <CommandParameterInfo>());
            }

            // Add fields with ParameterAttribute
            foreach (FieldInfo fieldInfo in cmdletType.GetFields(BindingFlags.Public | BindingFlags.Instance))
            {
                System.Diagnostics.Debug.WriteLine(fieldInfo.ToString());

                object[]             attributes = fieldInfo.GetCustomAttributes(false);
                CommandParameterInfo last       = null;

                // Find all [Parameter] attributes on the property
                foreach (object attr in attributes)
                {
                    if (attr is ParameterAttribute)
                    {
                        last = AddParameterToParameterSet(paramSets, fieldInfo, fieldInfo.FieldType, (ParameterAttribute)attr);
                    }
                }
                if (last != null)
                {
                    RegisterParameter(last);
                }
            }

            // Add properties with ParameterAttribute
            foreach (PropertyInfo propertyInfo in cmdletType.GetProperties(BindingFlags.Public | BindingFlags.Instance))
            {
                System.Diagnostics.Debug.WriteLine(propertyInfo.ToString());

                object[] attributes = propertyInfo.GetCustomAttributes(false);

                // Get info for the setter and getter
                MethodInfo getter = propertyInfo.GetAccessors().FirstOrDefault(i => i.IsSpecialName && i.Name.StartsWith("get_"));
                MethodInfo setter = propertyInfo.GetSetMethod();

                // Find all [Parameter] attributes on the property
                CommandParameterInfo last      = null;
                ParameterAttribute   paramAttr = null;
                foreach (object attr in attributes)
                {
                    if (attr is ParameterAttribute)
                    {
                        paramAttr = (ParameterAttribute)attr;

                        // if ValueFromPipeline or ValueFromPipelineByPropertyName is specified the property must have a public getter
                        if ((paramAttr.ValueFromPipeline || paramAttr.ValueFromPipelineByPropertyName) && (getter == null || !getter.IsPublic))
                        {
                            break;
                        }

                        // The property must have a public setter
                        if (setter == null || !setter.IsPublic)
                        {
                            break;
                        }

                        last = AddParameterToParameterSet(paramSets, propertyInfo, propertyInfo.PropertyType, paramAttr);
                    }
                }
                if (last != null)
                {
                    RegisterParameter(last);
                }
            }

            // Clean the UniqueSetParameters
            foreach (var cur in UniqueSetParameters.Where(keyValue => (keyValue.Value == null)).ToList())
            {
                UniqueSetParameters.Remove(cur.Key);
            }

            // Create param-sets collection
            Collection <CommandParameterSetInfo> paramSetInfo = new Collection <CommandParameterSetInfo>();

            foreach (string paramSetName in paramSets.Keys)
            {
                bool bIsDefaultParamSet = paramSetName.Equals(strDefaultParameterSetName);

                paramSetInfo.Add(new CommandParameterSetInfo(paramSetName, bIsDefaultParamSet, paramSets[paramSetName]));

                // If a parameter set is not specified for a parmeter, then the parameter belongs to all the parameter sets,
                // therefore if this is not the AllParameterSets Set then add all parameters from the AllParameterSets Set to it...
                if (string.Compare(paramSetName, ParameterAttribute.AllParameterSets) != 0 && paramSets.ContainsKey(ParameterAttribute.AllParameterSets))
                {
                    foreach (CommandParameterInfo cpi in paramSets[ParameterAttribute.AllParameterSets])
                    {
                        paramSets[paramSetName].Add(cpi);
                    }
                }
            }

            ParameterSets = new ReadOnlyCollection <CommandParameterSetInfo>(paramSetInfo);
        }
Beispiel #17
0
 private void AddParameterToParameterSet(Dictionary<string, Collection<CommandParameterInfo>> paramSets,
                                         CommandParameterInfo paramInfo)
 {
     var paramSetName = paramInfo.ParameterSetName;
     // create the parameter set if it doesn't exist, yet
     if (!paramSets.ContainsKey(paramSetName))
     {
         paramSets.Add(paramSetName, new Collection<CommandParameterInfo>());
     }
     Collection<CommandParameterInfo> paramSet = paramSets[paramSetName];
     // actually add parameter to the set
     paramSet.Add(paramInfo);
 }
 internal void Add(CommandParameterInfo info)
 {
     _parameters.Add(info);
 }
Beispiel #19
0
        // internals
        //internal CmdletInfo CreateGetCommandCopy(CmdletInfo cmdletInfo, object[] arguments);
        //internal object[] Arguments { set; get; }
        //internal string FullName { get; }
        //internal bool IsGetCommandCopy { set; get; }
        /// <remarks>
        /// From MSDN article: http://msdn2.microsoft.com/en-us/library/ms714348(VS.85).aspx
        /// 
        /// * A cmdlet can have any number of parameters. However, for a better user experience the number 
        ///   of parameters should be limited when possible. 
        /// * Parameters must be declared on public non-static fields or properties. It is preferred for 
        ///   parameters to be declared on properties. The property must have a public setter, and if ValueFromPipeline 
        ///   or ValueFromPipelineByPropertyName is specified the property must have a public getter.
        /// * When specifying positional parameters, note the following.
        ///   * Limit the number of positional parameters in a parameter set to less than five if possible.
        ///   * Positional parameters do not have to be sequential; positions 5, 100, 250 works the same as positions 0, 1, 2.
        /// * When the Position keyword is not specified, the cmdlet parameter must be referenced by its name.
        /// * When using parameter sets, no parameter set should contain more than one positional parameter with the same position. 
        /// * In addition, only one parameter in a set should declare ValueFromPipeline = true. Multiple parameters may define ValueFromPipelineByPropertyName = true.
        /// 
        /// </remarks>
        private static ReadOnlyCollection<CommandParameterSetInfo> GetParameterSetInfo(Type cmdletType)
        {
            Dictionary<string, Collection<CommandParameterInfo>> paramSets = new Dictionary<string, Collection<CommandParameterInfo>>(StringComparer.CurrentCultureIgnoreCase);

            // TODO: Ensure there are no duplicate named or aliased parameters inside scope of a single parameter set.
            // TODO: When using parameter sets, no parameter set should contain more than one positional parameter with the same position.
            // TODO: If not parameters have a position declared then positions for all the parameters should be automatically declaredin the order they are specified
            // TODO: Only one parameter in a set should declare ValueFromRemainingArguments = true
            // TODO: Only one parameter in a set should declare ValueFromPipeline = true. Multiple parameters may define ValueFromPipelineByPropertyName = true.
            // TODO: Currently due to the way parameters are loaded into sets from all set at the end the parameter end up in incorrect order.

            // Add fields with ParameterAttribute
            foreach (FieldInfo filedInfo in cmdletType.GetFields(BindingFlags.Public | BindingFlags.Instance))
            {
                System.Diagnostics.Debug.WriteLine(filedInfo.ToString());

                object[] attributes = filedInfo.GetCustomAttributes(false);

                // Find all [Parameter] attributes on the property
                ParameterAttribute paramAttr = null;
                foreach (object attr in attributes)
                {
                    if (attr is ParameterAttribute)
                    {
                        paramAttr = (ParameterAttribute)attr;

                        CommandParameterInfo pi = new CommandParameterInfo(filedInfo, filedInfo.FieldType, paramAttr);

                        string paramSetName = paramAttr.ParameterSetName ?? ParameterAttribute.AllParameterSets;

                        if (!paramSets.ContainsKey(paramSetName))
                        {
                            paramSets.Add(paramSetName, new Collection<CommandParameterInfo>());
                        }

                        Collection<CommandParameterInfo> paramSet = paramSets[paramSetName];
                        paramSet.Add(pi);
                    }
                }
            }

            // Add properties with ParameterAttribute
            foreach (PropertyInfo filedInfo in cmdletType.GetProperties(BindingFlags.Public | BindingFlags.Instance))
            {
                System.Diagnostics.Debug.WriteLine(filedInfo.ToString());

                object[] attributes = filedInfo.GetCustomAttributes(false);

                // Get info for the setter and getter
                MethodInfo getter = filedInfo.GetAccessors().FirstOrDefault(i => i.IsSpecialName && i.Name.StartsWith("get_"));
                MethodInfo setter = filedInfo.GetSetMethod();

                // Find all [Parameter] attributes on the property
                ParameterAttribute paramAttr = null;
                foreach (object attr in attributes)
                {
                    if (attr is ParameterAttribute)
                    {
                        paramAttr = (ParameterAttribute)attr;

                        // if ValueFromPipeline or ValueFromPipelineByPropertyName is specified the property must have a public getter
                        if ((paramAttr.ValueFromPipeline || paramAttr.ValueFromPipelineByPropertyName) && (getter == null || !getter.IsPublic))
                        {
                            break;
                        }

                        // The property must have a public setter
                        if (setter == null || !setter.IsPublic)
                        {
                            break;
                        }

                        CommandParameterInfo pi = new CommandParameterInfo(filedInfo, filedInfo.PropertyType, paramAttr);

                        string paramSetName = paramAttr.ParameterSetName ?? ParameterAttribute.AllParameterSets;

                        if (!paramSets.ContainsKey(paramSetName))
                        {
                            paramSets.Add(paramSetName, new Collection<CommandParameterInfo>());
                        }

                        Collection<CommandParameterInfo> paramSet = paramSets[paramSetName];
                        paramSet.Add(pi);
                    }
                }
            }

            // Create param-sets collection
            Collection<CommandParameterSetInfo> paramSetInfo = new Collection<CommandParameterSetInfo>();

            // TODO: find the name of the default param set
            string strDefaultParameterSetName = ParameterAttribute.AllParameterSets;
            object[] cmdLetAttrs = cmdletType.GetCustomAttributes(typeof(CmdletAttribute), false);
            if (cmdLetAttrs.Length > 0)
                strDefaultParameterSetName = ((CmdletAttribute)cmdLetAttrs[0]).DefaultParameterSetName ?? strDefaultParameterSetName;

            foreach (string paramSetName in paramSets.Keys)
            {
                bool bIsDefaultParamSet = paramSetName == strDefaultParameterSetName;

                paramSetInfo.Add(new CommandParameterSetInfo(paramSetName, bIsDefaultParamSet, paramSets[paramSetName]));

                // If a parameter set is not specified for a parmeter, then the parameter belongs to all the parameter sets,
                // therefore if this is not the AllParameterSets Set then add all parameters from the AllParameterSets Set to it...
                if (string.Compare(paramSetName, ParameterAttribute.AllParameterSets) != 0 && paramSets.ContainsKey(ParameterAttribute.AllParameterSets))
                {
                    foreach (CommandParameterInfo cpi in paramSets[ParameterAttribute.AllParameterSets])
                    {
                        paramSets[paramSetName].Add(cpi);
                    }
                }
            }

            return new ReadOnlyCollection<CommandParameterSetInfo>(paramSetInfo);
        }
Beispiel #20
0
        // internals
        //internal CmdletInfo CreateGetCommandCopy(CmdletInfo cmdletInfo, object[] arguments);
        //internal object[] Arguments { set; get; }
        //internal string FullName { get; }
        //internal bool IsGetCommandCopy { set; get; }
        private CommandParameterInfo AddParameterToParameterSet(Dictionary<string, Collection<CommandParameterInfo>> paramSets,
                                                MemberInfo memberInfo, Type type, ParameterAttribute paramAttr)
        {
            CommandParameterInfo pi = new CommandParameterInfo(memberInfo, type, paramAttr);
            var paramSetName = paramAttr.ParameterSetName;
            // Determine if this parameter is uniquely defined for one set and rember it

            paramSetName = paramSetName ?? ParameterAttribute.AllParameterSets;

            if (!paramSets.ContainsKey(paramSetName))
            {
                paramSets.Add(paramSetName, new Collection<CommandParameterInfo>());
            }

            Collection<CommandParameterInfo> paramSet = paramSets[paramSetName];
            paramSet.Add(pi);
            return pi;
        }
Beispiel #21
0
 private void RegisterParameter(CommandParameterInfo parameterInfo)
 {
     // also add it to lookuptable and check for unuque names/aliases
     var allNames = parameterInfo.Aliases.ToList();
     allNames.Add(parameterInfo.Name);
     foreach (var curName in allNames)
     {
         if (ParameterInfoLookupTable.ContainsKey(curName))
         {
             // save exception to be thrown when this object is validated, not now
             var msg = String.Format("The name or alias '{0}' is used multiple times.", curName);
             _validationException = new MetadataException(msg);
             continue;
         }
         ParameterInfoLookupTable[curName] = parameterInfo;
     }
 }
Beispiel #22
0
        // internals
        //internal CmdletInfo CreateGetCommandCopy(CmdletInfo cmdletInfo, object[] arguments);
        //internal object[] Arguments { set; get; }
        //internal string FullName { get; }
        //internal bool IsGetCommandCopy { set; get; }

        /// <remarks>
        /// From MSDN article: http://msdn2.microsoft.com/en-us/library/ms714348(VS.85).aspx
        ///
        /// * A cmdlet can have any number of parameters. However, for a better user experience the number
        ///   of parameters should be limited when possible.
        /// * Parameters must be declared on public non-static fields or properties. It is preferred for
        ///   parameters to be declared on properties. The property must have a public setter, and if ValueFromPipeline
        ///   or ValueFromPipelineByPropertyName is specified the property must have a public getter.
        /// * When specifying positional parameters, note the following.
        ///   * Limit the number of positional parameters in a parameter set to less than five if possible.
        ///   * Positional parameters do not have to be sequential; positions 5, 100, 250 works the same as positions 0, 1, 2.
        /// * When the Position keyword is not specified, the cmdlet parameter must be referenced by its name.
        /// * When using parameter sets, no parameter set should contain more than one positional parameter with the same position.
        /// * In addition, only one parameter in a set should declare ValueFromPipeline = true. Multiple parameters may define ValueFromPipelineByPropertyName = true.
        ///
        /// </remarks>
        private static ReadOnlyCollection <CommandParameterSetInfo> GetParameterSetInfo(Type cmdletType)
        {
            Dictionary <string, Collection <CommandParameterInfo> > paramSets = new Dictionary <string, Collection <CommandParameterInfo> >(StringComparer.CurrentCultureIgnoreCase);

            // TODO: Ensure there are no duplicate named or aliased parameters inside scope of a single parameter set.
            // TODO: When using parameter sets, no parameter set should contain more than one positional parameter with the same position.
            // TODO: If not parameters have a position declared then positions for all the parameters should be automatically declaredin the order they are specified
            // TODO: Only one parameter in a set should declare ValueFromRemainingArguments = true
            // TODO: Only one parameter in a set should declare ValueFromPipeline = true. Multiple parameters may define ValueFromPipelineByPropertyName = true.
            // TODO: Currently due to the way parameters are loaded into sets from all set at the end the parameter end up in incorrect order.

            // Add fields with ParameterAttribute
            foreach (FieldInfo filedInfo in cmdletType.GetFields(BindingFlags.Public | BindingFlags.Instance))
            {
                System.Diagnostics.Debug.WriteLine(filedInfo.ToString());

                object[] attributes = filedInfo.GetCustomAttributes(false);

                // Find all [Parameter] attributes on the property
                ParameterAttribute paramAttr = null;
                foreach (object attr in attributes)
                {
                    if (attr is ParameterAttribute)
                    {
                        paramAttr = (ParameterAttribute)attr;

                        CommandParameterInfo pi = new CommandParameterInfo(filedInfo, filedInfo.FieldType, paramAttr);

                        string paramSetName = paramAttr.ParameterSetName ?? ParameterAttribute.AllParameterSets;

                        if (!paramSets.ContainsKey(paramSetName))
                        {
                            paramSets.Add(paramSetName, new Collection <CommandParameterInfo>());
                        }

                        Collection <CommandParameterInfo> paramSet = paramSets[paramSetName];
                        paramSet.Add(pi);
                    }
                }
            }

            // Add properties with ParameterAttribute
            foreach (PropertyInfo filedInfo in cmdletType.GetProperties(BindingFlags.Public | BindingFlags.Instance))
            {
                System.Diagnostics.Debug.WriteLine(filedInfo.ToString());

                object[] attributes = filedInfo.GetCustomAttributes(false);

                // Get info for the setter and getter
                MethodInfo getter = filedInfo.GetAccessors().FirstOrDefault(i => i.IsSpecialName && i.Name.StartsWith("get_"));
                MethodInfo setter = filedInfo.GetSetMethod();

                // Find all [Parameter] attributes on the property
                ParameterAttribute paramAttr = null;
                foreach (object attr in attributes)
                {
                    if (attr is ParameterAttribute)
                    {
                        paramAttr = (ParameterAttribute)attr;

                        // if ValueFromPipeline or ValueFromPipelineByPropertyName is specified the property must have a public getter
                        if ((paramAttr.ValueFromPipeline || paramAttr.ValueFromPipelineByPropertyName) && (getter == null || !getter.IsPublic))
                        {
                            break;
                        }

                        // The property must have a public setter
                        if (setter == null || !setter.IsPublic)
                        {
                            break;
                        }

                        CommandParameterInfo pi = new CommandParameterInfo(filedInfo, filedInfo.PropertyType, paramAttr);

                        string paramSetName = paramAttr.ParameterSetName ?? ParameterAttribute.AllParameterSets;

                        if (!paramSets.ContainsKey(paramSetName))
                        {
                            paramSets.Add(paramSetName, new Collection <CommandParameterInfo>());
                        }

                        Collection <CommandParameterInfo> paramSet = paramSets[paramSetName];
                        paramSet.Add(pi);
                    }
                }
            }

            // Create param-sets collection
            Collection <CommandParameterSetInfo> paramSetInfo = new Collection <CommandParameterSetInfo>();

            // TODO: find the name of the default param set
            string strDefaultParameterSetName = ParameterAttribute.AllParameterSets;

            object[] cmdLetAttrs = cmdletType.GetCustomAttributes(typeof(CmdletAttribute), false);
            if (cmdLetAttrs.Length > 0)
            {
                strDefaultParameterSetName = ((CmdletAttribute)cmdLetAttrs[0]).DefaultParameterSetName ?? strDefaultParameterSetName;
            }

            foreach (string paramSetName in paramSets.Keys)
            {
                bool bIsDefaultParamSet = paramSetName == strDefaultParameterSetName;

                paramSetInfo.Add(new CommandParameterSetInfo(paramSetName, bIsDefaultParamSet, paramSets[paramSetName]));

                // If a parameter set is not specified for a parmeter, then the parameter belongs to all the parameter sets,
                // therefore if this is not the AllParameterSets Set then add all parameters from the AllParameterSets Set to it...
                if (string.Compare(paramSetName, ParameterAttribute.AllParameterSets) != 0 && paramSets.ContainsKey(ParameterAttribute.AllParameterSets))
                {
                    foreach (CommandParameterInfo cpi in paramSets[ParameterAttribute.AllParameterSets])
                    {
                        paramSets[paramSetName].Add(cpi);
                    }
                }
            }

            return(new ReadOnlyCollection <CommandParameterSetInfo>(paramSetInfo));
        }
Beispiel #23
0
 internal bool Contains(CommandParameterInfo param)
 {
     return Parameters.Contains(param);
 }
Beispiel #24
0
        private static void AppendFormatCommandParameterInfo(CommandParameterInfo parameter, ref Text.StringBuilder result)
        {
            if (result.Length > 0)
            {
                // Add a space between parameters
                result.Append(" ");
            }

            if (parameter.ParameterType == typeof(SwitchParameter))
            {
                result.AppendFormat(CultureInfo.InvariantCulture, parameter.IsMandatory ? "-{0}" : "[-{0}]", parameter.Name);
            }
            else
            {
                string parameterTypeString = GetParameterTypeString(parameter.ParameterType, parameter.Attributes);

                if (parameter.IsMandatory)
                {
                    result.AppendFormat(CultureInfo.InvariantCulture,
                                        parameter.Position != int.MinValue ? "[-{0}] <{1}>" : "-{0} <{1}>",
                                        parameter.Name, parameterTypeString);
                }
                else
                {
                    result.AppendFormat(CultureInfo.InvariantCulture,
                                        parameter.Position != int.MinValue ? "[[-{0}] <{1}>]" : "[-{0} <{1}>]",
                                        parameter.Name, parameterTypeString);
                }
            }
        }
Beispiel #25
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="obj"></param>
        /// <remarks>
        /// All abount Cmdlet parameters: http://msdn2.microsoft.com/en-us/library/ms714433(VS.85).aspx
        /// </remarks>
        internal override void BindArguments(PSObject obj)
        {
            // TODO: Bind obj properties to ValueFromPipelinebyPropertyName parameters
            // TODO: If parameter has ValueFromRemainingArguments any unmatched arguments should be bound to this parameter as an array
            // TODO: If no parameter has ValueFromRemainingArguments any supplied parameters are unmatched then fail with exception

            if ((obj == null) && (Parameters.Count == 0))
            {
                return;
            }

            // TODO: Perform analysis on passed arguments and obj to identify which parameter set to select for binding
            CommandParameterSetInfo paramSetInfo = _cmdletInfo.GetDefaultParameterSet();

            if (obj != null)
            {
                var valueFromPipelineParameter = paramSetInfo.Parameters.Where(paramInfo => paramInfo.ValueFromPipeline).SingleOrDefault();

                if (valueFromPipelineParameter != null)
                {
                    BindArgument(valueFromPipelineParameter.Name, obj, valueFromPipelineParameter.ParameterType);
                }
            }

            if (Parameters.Count > 0)
            {
                // bind by position location
                for (int i = 0; i < Parameters.Count; i++)
                {
                    CommandParameterInfo paramInfo = null;

                    CommandParameter parameter = Parameters[i];

                    if (string.IsNullOrEmpty(parameter.Name))
                    {
                        paramInfo = paramSetInfo.GetParameterByPosition(i);

                        if (paramInfo != null)
                        {
                            BindArgument(paramInfo.Name, parameter.Value, paramInfo.ParameterType);
                        }
                    }
                    else
                    {
                        paramInfo = paramSetInfo.LookupParameter(parameter.Name);

                        if (paramInfo != null)
                        {
                            if (parameter.Value == null && paramInfo.ParameterType != typeof(SwitchParameter) &&
                                i < Parameters.Count - 1 && Parameters[i + 1].Name == null)
                            {
                                BindArgument(paramInfo.Name, Parameters[i + 1].Value, paramInfo.ParameterType);
                                i++;
                            }
                            else
                            {
                                BindArgument(paramInfo.Name, parameter.Value, paramInfo.ParameterType);
                            }
                        }
                        else
                        {
                            //TODO: Throw ParameterBindingException when implemented
                            throw(new Exception("No parameter found matching '" + parameter.Name + "'"));
                        }
                    }
                }
            }
        }
Beispiel #26
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="obj"></param>
        /// <remarks>
        /// All abount Cmdlet parameters: http://msdn2.microsoft.com/en-us/library/ms714433(VS.85).aspx
        /// </remarks>
        internal override void BindArguments(PSObject obj)
        {
            if ((obj == null) && (Parameters.Count == 0))
            {
                return;
            }

            // TODO: bind the arguments to the parameters
            CommandParameterSetInfo paramSetInfo = _cmdletInfo.GetDefaultParameterSet();

            // TODO: refer to the Command._ParameterSetName for a param set name

            if (obj != null)
            {
                foreach (CommandParameterInfo paramInfo in paramSetInfo.Parameters)
                {
                    if (paramInfo.ValueFromPipeline)
                    {
                        // TODO: extract this into a method
                        PropertyInfo pi = Command.GetType().GetProperty(paramInfo.Name, paramInfo.ParameterType);
                        pi.SetValue(Command, obj, null);
                    }
                }
            }

            if (Parameters.Count > 0)
            {
                // bind by position location
                for (int i = 0; i < Parameters.Count; i++)
                {
                    CommandParameterInfo paramInfo = null;

                    CommandParameter parameter = Parameters[i];

                    if (string.IsNullOrEmpty(parameter.Name))
                    {
                        paramInfo = paramSetInfo.GetParameterByPosition(i);

                        if (paramInfo != null)
                        {
                            // TODO: extract this into a method
                            PropertyInfo pi = Command.GetType().GetProperty(paramInfo.Name, paramInfo.ParameterType);
                            // TODO: make this generic
                            if (pi.PropertyType == typeof(PSObject[]))
                            {
                                PSObject[] arr = new PSObject[] { PSObject.AsPSObject(Parameters[i].Value) };
                                pi.SetValue(Command, arr, null);
                            }
                            else if (pi.PropertyType == typeof(String[]))
                            {
                                String[] arr = new String[] { Parameters[i].Value.ToString() };
                                pi.SetValue(Command, arr, null);
                            }
                            else
                            {
                                pi.SetValue(Command, Parameters[i].Value, null);
                            }
                        }
                    }
                    else
                    {
                        paramInfo = paramSetInfo.GetParameterByName(parameter.Name);

                        if (paramInfo != null)
                        {
                            // TODO: extract this into a method
                            PropertyInfo pi = Command.GetType().GetProperty(paramInfo.Name, paramInfo.ParameterType);
                            pi.SetValue(Command, Parameters[i].Value, null);
                        }
                    }
                }
            }
        }
Beispiel #27
0
 private void AddParameter(MemberInfo info, Type parameterType, ParameterAttribute paramAttribute)
 {
     var paramInfo = new CommandParameterInfo(info, parameterType, paramAttribute);
     if (!NamedParameters.ContainsKey(paramInfo.Name))
     {
         NamedParameters[paramInfo.Name] = paramInfo;
     }
     AllParameters.Add(paramInfo);
 }
Beispiel #28
0
 private void BindParameter(CommandParameterInfo info, object value, bool doConvert)
 {
     var memberInfo = info.MemberInfo;
     if (_boundParameters.Contains(memberInfo))
     {
         var msg = String.Format("Parameter '{0}' has already been bound!", info.Name);
         throw new ParameterBindingException(msg);
     }
     // ConvertTo throws an exception if conversion isn't possible. That's just fine.
     if (doConvert)
     {
         value = LanguagePrimitives.ConvertTo(value, info.ParameterType);
     }
     // TODO: validate value with Attributes (ValidateNotNullOrEmpty, etc)
     SetCommandValue(memberInfo, value);
     _boundParameters.Add(memberInfo);
 }
Beispiel #29
0
 internal ParameterBindingException(string message, string errorId, CommandParameterInfo target)
     : base(message, errorId, ErrorCategory.InvalidArgument, target)
 {
     ParameterName = target.Name;
     ParameterType = target.ParameterType;
 }
Beispiel #30
0
 internal ParameterBindingException(string message, string errorId, CommandParameterInfo target)
     : base(message, errorId, ErrorCategory.InvalidArgument, target)
 {
     ParameterName = target.Name;
     ParameterType = target.ParameterType;
 }
 /// <summary>
 /// Constructs an instance of a ParameterInfo object
 /// </summary>
 /// <param name="parameterInfo">Parameter info of the parameter</param>
 public ParameterInfo(CommandParameterInfo parameterInfo)
 {
     this.Name = "-" + parameterInfo.Name;
     this.ParameterType = parameterInfo.ParameterType.FullName;
     this.Position = parameterInfo.Position;
     this.IsMandatory = parameterInfo.IsMandatory;
     this.HelpMessage = parameterInfo.HelpMessage;
 }
Beispiel #32
0
 private object GatherParameterValue(CommandParameterInfo param)
 {
     // TODO: implement asking the user for a value
     return null;
 }
Beispiel #33
0
 // restricts the candidate parameter sets by the newly bound parameters
 private void RestrictCandidatesByBoundParameter(CommandParameterInfo info)
 {
     var setsContaining = from paramSet in _cmdletInfo.ParameterSets
         where paramSet.Contains(info) select paramSet;
     _candidateParameterSets = _candidateParameterSets.Intersect(setsContaining).ToList();
     if (_candidateParameterSets.Count == 0)
     {
         ThrowAmbiguousParameterSetException();
     }
     else if (_candidateParameterSets.Count == 1)
     {
         _activeSet = _candidateParameterSets[0];
     }
 }
Beispiel #34
0
        private void BindParameter(CommandParameterInfo info, object value, bool doConvert)
        {
            var memberInfo = info.MemberInfo;
            if (_boundParameters.Contains(memberInfo))
            {
                var msg = String.Format("Parameter '{0}' has already been bound!", info.Name);
                throw new ParameterBindingException(msg);
            }

            foreach (var attr in info.TransformationAttributes)
            {
                value = attr.Transform(_engineIntrinsics, value);
            }

            // ConvertTo throws an exception if conversion isn't possible. That's just fine.
            if (doConvert)
            {
                value = LanguagePrimitives.ConvertTo(value, info.ParameterType);
            }
            // TODO: validate value with Attributes (ValidateNotNullOrEmpty, etc)
            SetCommandValue(memberInfo, value);
            // make sure to update the candidate set to only consider parameter sets with the newly bound parameter
            RestrictCandidatesByBoundParameter(info);
            _boundParameters.Add(memberInfo);
        }
Beispiel #35
0
 private bool TryBindParameter(CommandParameterInfo info, object value, bool doConvert)
 {
     try
     {
         BindParameter(info, value, doConvert);
         return true;
     }
     catch (Exception)
     {
         return false;
     }
 }
Beispiel #36
0
        // internals
        //internal CmdletInfo CreateGetCommandCopy(CmdletInfo cmdletInfo, object[] arguments);
        //internal object[] Arguments { set; get; }
        //internal string FullName { get; }
        //internal bool IsGetCommandCopy { set; get; }

        /// <remarks>
        /// From MSDN article: http://msdn2.microsoft.com/en-us/library/ms714348(VS.85).aspx
        ///
        /// * A cmdlet can have any number of parameters. However, for a better user experience the number
        ///   of parameters should be limited when possible.
        /// * Parameters must be declared on public non-static fields or properties. It is preferred for
        ///   parameters to be declared on properties. The property must have a public setter, and if ValueFromPipeline
        ///   or ValueFromPipelineByPropertyName is specified the property must have a public getter.
        /// * When specifying positional parameters, note the following.
        ///   * Limit the number of positional parameters in a parameter set to less than five if possible.
        ///   * Positional parameters do not have to be sequential; positions 5, 100, 250 works the same as positions 0, 1, 2.
        /// * When the Position keyword is not specified, the cmdlet parameter must be referenced by its name.
        /// * When using parameter sets, no parameter set should contain more than one positional parameter with the same position.
        /// * In addition, only one parameter in a set should declare ValueFromPipeline = true. Multiple parameters may define ValueFromPipelineByPropertyName = true.
        ///
        /// </remarks>
        private static ReadOnlyCollection <CommandParameterSetInfo> GetParameterSetInfo(Type cmdletType)
        {
            Dictionary <string, Collection <CommandParameterInfo> > paramSets = new Dictionary <string, Collection <CommandParameterInfo> >(StringComparer.CurrentCultureIgnoreCase);

            // Extract all the public parameters from the Cmdlet

            /* TODO: gather all the field parameters
             * foreach(var filedInfo in cmdletType.GetFields(BindingFlags.Public | BindingFlags.Instance))
             * {
             *  System.Diagnostics.Debug.WriteLine(filedInfo.ToString());
             * }
             */

            foreach (PropertyInfo filedInfo in cmdletType.GetProperties(BindingFlags.Public | BindingFlags.Instance))
            {
                System.Diagnostics.Debug.WriteLine(filedInfo.ToString());

                object[] attributes = filedInfo.GetCustomAttributes(false);

                // Find if there are any [Parameter] attributes on the property
                ParameterAttribute paramAttr = null;
                foreach (object attr in attributes)
                {
                    if (attr is ParameterAttribute)
                    {
                        paramAttr = (ParameterAttribute)attr;
                        break;
                    }
                }

                // TODO: make sure that the PropertyInfo.GetAccessors() returns the appropriate set of accessors

                if (paramAttr != null)
                {
                    CommandParameterInfo pi = new CommandParameterInfo(filedInfo.Name, filedInfo.PropertyType, paramAttr);

                    string paramSetName = paramAttr.ParameterSetName ?? ParameterAttribute.AllParameterSets;

                    if (!paramSets.ContainsKey(paramSetName))
                    {
                        paramSets.Add(paramSetName, new Collection <CommandParameterInfo>());
                    }

                    Collection <CommandParameterInfo> paramSet = paramSets[paramSetName];
                    paramSet.Add(pi);
                }
            }

            // Create param-sets collection
            Collection <CommandParameterSetInfo> paramSetInfo = new Collection <CommandParameterSetInfo>();

            // TODO: find the name of the default param set
            string strDefaultParameterSetName = ParameterAttribute.AllParameterSets;

            object[] cmdLetAttrs = cmdletType.GetCustomAttributes(typeof(CmdletAttribute), false);
            if (cmdLetAttrs.Length > 0)
            {
                strDefaultParameterSetName = ((CmdletAttribute)cmdLetAttrs[0]).DefaultParameterSetName ?? strDefaultParameterSetName;
            }

            foreach (string paramSetName in paramSets.Keys)
            {
                bool bIsDefaultParamSet = paramSetName == strDefaultParameterSetName;

                paramSetInfo.Add(new CommandParameterSetInfo(paramSetName, bIsDefaultParamSet, paramSets[paramSetName]));
            }

            return(new ReadOnlyCollection <CommandParameterSetInfo>(paramSetInfo));
        }
Beispiel #37
0
        // internals
        //internal CmdletInfo CreateGetCommandCopy(CmdletInfo cmdletInfo, object[] arguments);
        //internal object[] Arguments { set; get; }
        //internal string FullName { get; }
        //internal bool IsGetCommandCopy { set; get; }
        /// <remarks>
        /// From MSDN article: http://msdn2.microsoft.com/en-us/library/ms714348(VS.85).aspx
        /// 
        /// * A cmdlet can have any number of parameters. However, for a better user experience the number 
        ///   of parameters should be limited when possible. 
        /// * Parameters must be declared on public non-static fields or properties. It is preferred for 
        ///   parameters to be declared on properties. The property must have a public setter, and if ValueFromPipeline 
        ///   or ValueFromPipelineByPropertyName is specified the property must have a public getter.
        /// * When specifying positional parameters, note the following.
        ///   * Limit the number of positional parameters in a parameter set to less than five if possible.
        ///   * Positional parameters do not have to be sequential; positions 5, 100, 250 works the same as positions 0, 1, 2.
        /// * When the Position keyword is not specified, the cmdlet parameter must be referenced by its name.
        /// * When using parameter sets, no parameter set should contain more than one positional parameter with the same position. 
        /// * In addition, only one parameter in a set should declare ValueFromPipeline = true. Multiple parameters may define ValueFromPipelineByPropertyName = true.
        /// 
        /// </remarks>
        private static ReadOnlyCollection<CommandParameterSetInfo> GetParameterSetInfo(Type cmdletType)
        {
            Dictionary<string, Collection<CommandParameterInfo>> paramSets = new Dictionary<string, Collection<CommandParameterInfo>>(StringComparer.CurrentCultureIgnoreCase);

            // Extract all the public parameters from the Cmdlet
            /* TODO: gather all the field parameters
            foreach(var filedInfo in cmdletType.GetFields(BindingFlags.Public | BindingFlags.Instance))
            {
                System.Diagnostics.Debug.WriteLine(filedInfo.ToString());
            }
            */

            foreach (PropertyInfo filedInfo in cmdletType.GetProperties(BindingFlags.Public | BindingFlags.Instance))
            {
                System.Diagnostics.Debug.WriteLine(filedInfo.ToString());

                object[] attributes = filedInfo.GetCustomAttributes(false);

                // Find if there are any [Parameter] attributes on the property
                ParameterAttribute paramAttr = null;
                foreach (object attr in attributes)
                {
                    if (attr is ParameterAttribute)
                    {
                        paramAttr = (ParameterAttribute) attr;
                        break;
                    }
                }

                // TODO: make sure that the PropertyInfo.GetAccessors() returns the appropriate set of accessors

                if (paramAttr != null)
                {
                    CommandParameterInfo pi = new CommandParameterInfo(filedInfo.Name, filedInfo.PropertyType, paramAttr);

                    string paramSetName = paramAttr.ParameterSetName ?? ParameterAttribute.AllParameterSets;

                    if (!paramSets.ContainsKey(paramSetName))
                    {
                        paramSets.Add(paramSetName, new Collection<CommandParameterInfo>());
                    }

                    Collection<CommandParameterInfo> paramSet = paramSets[paramSetName];
                    paramSet.Add(pi);
                }
            }

            // Create param-sets collection
            Collection<CommandParameterSetInfo> paramSetInfo = new Collection<CommandParameterSetInfo>();

            // TODO: find the name of the default param set
            string strDefaultParameterSetName = ParameterAttribute.AllParameterSets;
            object[] cmdLetAttrs = cmdletType.GetCustomAttributes(typeof (CmdletAttribute), false);
            if (cmdLetAttrs.Length > 0)
                strDefaultParameterSetName = ((CmdletAttribute)cmdLetAttrs[0]).DefaultParameterSetName ?? strDefaultParameterSetName;

            foreach(string paramSetName in paramSets.Keys)
            {
                bool bIsDefaultParamSet = paramSetName == strDefaultParameterSetName;

                paramSetInfo.Add(new CommandParameterSetInfo(paramSetName, bIsDefaultParamSet, paramSets[paramSetName]));
            }

            return new ReadOnlyCollection<CommandParameterSetInfo>(paramSetInfo);
        }
Beispiel #38
0
        // internals
        //internal CmdletInfo CreateGetCommandCopy(CmdletInfo cmdletInfo, object[] arguments);
        //internal object[] Arguments { set; get; }
        //internal string FullName { get; }
        //internal bool IsGetCommandCopy { set; get; }
        private CommandParameterInfo AddParameterToParameterSet(Dictionary<string, Collection<CommandParameterInfo>> paramSets,
                                                MemberInfo memberInfo, Type type, ParameterAttribute paramAttr)
        {
            CommandParameterInfo pi = new CommandParameterInfo(memberInfo, type, paramAttr);
            var paramSetName = paramAttr.ParameterSetName;
            // Determine if this parameter is uniquely defined for one set and rember it
            if (!String.IsNullOrEmpty(paramSetName) && !paramSetName.Equals(ParameterAttribute.AllParameterSets))
            {
                var parameterName = pi.Name;
                // check if we already defined that parameter for another set
                if (UniqueSetParameters.ContainsKey(parameterName))
                {
                    UniqueSetParameters[parameterName] = null;
                }
                else
                {
                    // not yet in any set, it's a candidate for a unique parameter
                    UniqueSetParameters[parameterName] = paramSetName;
                }
            }

            paramSetName = paramSetName ?? ParameterAttribute.AllParameterSets;

            if (!paramSets.ContainsKey(paramSetName))
            {
                paramSets.Add(paramSetName, new Collection<CommandParameterInfo>());
            }

            Collection<CommandParameterInfo> paramSet = paramSets[paramSetName];
            paramSet.Add(pi);
            return pi;
        }
Beispiel #39
0
 internal bool Contains(CommandParameterInfo param)
 {
     return(Parameters.Contains(param));
 }
Beispiel #40
0
 private object GatherParameterValue(CommandParameterInfo param)
 {
     // TODO: implement asking the user for a value
     return(null);
 }