private void HandleMissingMandatoryParameters(CommandParameterSetInfo parameterSet, bool considerPipeline, bool askUser) { // select mandatory parametes var unsetMandatories = GetMandatoryUnboundParameters(parameterSet, considerPipeline); foreach (var curParam in unsetMandatories) { object value = null; // check if we should try to gather it if (askUser) { // try to get this value from UI GatherParameterValue(curParam); } // check if we had success, fail otherwise if (value == null) { // WORKAROUND: PS throws a MethodInvocationException when binding pipeline parameters // that is when a user shouldn't be asked anymore... let's do the same if (askUser) { var msg = String.Format("Missing value for mandatory parameter '{0}'.", curParam.Name); throw new ParameterBindingException(msg, "MissingMandatoryParameter"); } else { var msg = "The input object cannot be bound as it doesn't provide some mandatory information: " + curParam.Name; throw new MethodInvocationException(msg); } } BindParameter(curParam, value, true); } }
private void ChooseParameterSet(CommandParameterSetInfo chosenSet) { _activeSet = chosenSet; _candidateParameterSets.Clear(); _candidateParameterSets.Add(chosenSet); SetCmdletParameterSetName(chosenSet); }
private void ThrowMissingParametersExcpetion(CommandParameterSetInfo paramSet) { var missing = GetMandatoryUnboundParameters(paramSet, true); var msg = "Missing value for mandatory parameter(s): " + String.Join(", ", missing); throw new ParameterBindingException(msg, "MissingMandatoryParameter"); }
private CommandParameterSetInfo SelectObviousActiveParameterSet() { // if we only have one parameter set, this is always the active one (e.g. AllParametersSets) CommandParameterSetInfo active = null; var setCount = _cmdletInfo.ParameterSets.Count; if (setCount == 1) { active = _cmdletInfo.ParameterSets[0]; } // if we have two sets and one is AllParametersSets, then the other one is naturally the default else if (setCount == 2) { var firstSet = _cmdletInfo.ParameterSets[0]; var secondSet = _cmdletInfo.ParameterSets[1]; if (firstSet.IsAllParameterSets) { active = secondSet; } else if (secondSet.IsAllParameterSets) { active = firstSet; } } if (active != null) { _candidateParameterSets = new List <CommandParameterSetInfo>() { active }; } return(active); }
private void ChooseParameterSet(CommandParameterSetInfo chosenSet) { if (chosenSet != null) { _cmdlet.ParameterSetName = chosenSet.Name; } }
private CommandParameterCollection BindDynamicParameters(CommandParameterCollection parameters) { var dynamicParamsCmdlet = _cmdlet as IDynamicParameters; if (dynamicParamsCmdlet == null) // no support for dynamic parameters { return(parameters); } // get the object with dynamic parameters var parameterObject = dynamicParamsCmdlet.GetDynamicParameters(); if (parameterObject == null) { return(parameters); } var discovery = new CommandParameterDiscovery(parameterObject.GetType()); // add the parameters to the cmdletInfo _cmdletInfo.AddParametersToAllSets(discovery); // as we updated parameter sets, we need to rebuild some cached values _activeSet = _activeSet == null ? null : GetParameterSet(_activeSet.Name); _defaultSet = _defaultSet == null ? null : GetParameterSet(_defaultSet.Name); _candidateParameterSets = (from p in _candidateParameterSets select GetParameterSet(p.Name)).ToList(); AddBindDestionations(discovery, parameterObject); // now try to rebind the parameters parameters = BindNamedParameters(parameters); return(BindPositionalParameters(parameters, ActiveOrDefaultParameterSet)); }
private void SetCmdletParameterSetName(CommandParameterSetInfo chosenSet) { if (_cmdlet is PSCmdlet) { ((PSCmdlet)_cmdlet).ParameterSetName = chosenSet != null ? chosenSet.Name : ParameterAttribute.AllParameterSets; } }
/// <summary> /// Binds the parameters from the command line to the command. /// </summary> /// <remarks> /// All abount Cmdlet parameters: http://msdn2.microsoft.com/en-us/library/ms714433(VS.85).aspx /// About the lifecycle: http://msdn.microsoft.com/en-us/library/ms714429(v=vs.85).aspx /// </remarks> public void BindCommandLineParameters(CommandParameterCollection parameters) { // How command line parameters are bound: // In general: We will bind first named parameters, then positionals, and then maybe gather some. // While parameters are being bound, a list of _candidateParameterSets is maintained that keeps track // of those sets that are eligible for being taken. // As we might have an early choice that can be handled, an _activeSet is maintained in addition. // The _candidateSet will be restricted to the _activeSet if we found one early // Check if one obvious choice for a parameter set to be chosen (e.g. if there is only one) _activeSet = SelectObviousActiveParameterSet(); // Bind all named parameters, fail if some name is bound twice or if the selection is already ambiguos parameters = BindNamedParameters(parameters); // Bind positional parameters per parameter set // To do so, sort parameters of set by position, ignore bound parameters and set the first unbound position // Note: if we don't know the active parameter set, yet, we will bind it by Default, this is PS behavior // Binding will also restrict the candidate set and check for ambiguity parameters = BindPositionalParameters(parameters, ActiveOrDefaultParameterSet); // Bind dynamic parameters based on what's already bound. // TODO: this is also the place to support ShouldProcess parameters = BindDynamicParameters(parameters); // Make sure that there are no parameters that couldn't be bound ValidateAllParametersBound(parameters); // There might be parameter sets with parameters that are still unbound but will be set by pipeline. // If not, and if we have an (active or default) parameter set that is still a candidate, then get the // missing parameters. if (!HasParameterSetsWithUnboundMandatoryPipelineParameters() && _candidateParameterSets.Contains(ActiveOrDefaultParameterSet)) { HandleMissingMandatoryParameters(ActiveOrDefaultParameterSet, false, true); } // We finished binding parameters without pipeline. Therefore we can restrict the candidate set to those // sets that have all mandatory parameters set or are able to set them by pipeline RestrictCandidatesByBoundParameter(false); // Check if we have unbound parameters that can be set by pipeline. If not and we can already do // our final choice (and throw an error on problems) if (!HasUnboundPipelineParameters()) { DoFinalChoiceOfParameterSet(); } // Back up the bound parameters BackupCommandLineParameterValues(); // For the beginning phase: Tell the cmdlet which parameter set is likely to be used (if we know it) // If there is only one candidate, use it at least temporarily. Otherwise the active or default SetCmdletParameterSetName(_candidateParameterSets.Count == 1 ? _candidateParameterSets[0] : ActiveOrDefaultParameterSet); }
/// <summary> /// Binds the parameters from the command line to the command. /// </summary> /// <remarks> /// All abount Cmdlet parameters: http://msdn2.microsoft.com/en-us/library/ms714433(VS.85).aspx /// About the lifecycle: http://msdn.microsoft.com/en-us/library/ms714429(v=vs.85).aspx /// </remarks> public void BindCommandLineParameters(CommandParameterCollection parameters) { // How command line parameters are bound: // In general: We will bind first named parameters, then positionals, and then maybe gather some. // While parameters are being bound, a list of _candidateParameterSets is maintained that keeps track // of those sets that are eligible for being taken. // As we might have an early choice that can be handled, an _activeSet is maintained in addition. // The _candidateSet will be restricted to the _activeSet if we found one early // Check if one obvious choice for a parameter set to be chosen (e.g. if there is only one) _activeSet = SelectObviousActiveParameterSet(); // Bind all named parameters, fail if some name is bound twice or if the selection is already ambiguos parameters = BindNamedParameters(parameters); // Bind positional parameters per parameter set // To do so, sort parameters of set by position, ignore bound parameters and set the first unbound position // Note: if we don't know the active parameter set, yet, we will bind it by Default, this is PS behavior // Binding will also restrict the candidate set and check for ambiguity parameters = BindPositionalParameters(parameters, ActiveOrDefaultParameterSet); // Bind dynamic parameters based on what's already bound. // TODO: this is also the place to support ShouldProcess parameters = BindDynamicParameters(parameters); // Make sure that there are no parameters that couldn't be bound ValidateAllParametersBound(parameters); // There might be parameter sets with parameters that are still unbound but will be set by pipeline. // If not, and if we have an (active or default) parameter set that is still a candidate, then get the // missing parameters. if (!HasParameterSetsWithUnboundMandatoryPipelineParameters() && _candidateParameterSets.Contains(ActiveOrDefaultParameterSet)) { HandleMissingMandatoryParameters(ActiveOrDefaultParameterSet, false, true); } // We finished binding parameters without pipeline. Therefore we can restrict the candidate set to those // sets that have all mandatory parameters set or are able to set them by pipeline RestrictCandidatesByBoundParameter(false); // Check if we have unbound parameters that can be set by pipeline. If not and we can already do // our final choice (and throw an error on problems) if (!HasUnboundPipelineParameters()) { DoFinalChoiceOfParameterSet(); } // Back up the bound parameters BackupCommandLineParameterValues(); // For the beginning phase: Tell the cmdlet which parameter set is likely to be used (if we know it) // If there is only one candidate, use it at least temporarily. Otherwise the active or default SetCmdletParameterSetName(_candidateParameterSets.Count == 1 ? _candidateParameterSets[0] : ActiveOrDefaultParameterSet); }
/// <summary> /// Creates an instance of the ShowCommandParameterSetInfo class based on a CommandParameterSetInfo object /// </summary> /// /// <param name="other"> /// The object to wrap. /// </param> public ShowCommandParameterSetInfo(CommandParameterSetInfo other) { if (null == other) { throw new ArgumentNullException("other"); } this.Name = other.Name; this.IsDefault = other.IsDefault; this.Parameters = other.Parameters.Select(x => new ShowCommandParameterInfo(x)).ToArray(); }
/// <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); } } } } }
public CmdletParameterBinder(CmdletInfo cmdletInfo, Cmdlet cmdlet) { _cmdletInfo = cmdletInfo; _cmdlet = cmdlet; _defaultValues = new Dictionary <MemberInfo, object>(); _boundParameters = new Collection <MemberInfo>(); _candidateParameterSets = new Collection <CommandParameterSetInfo>(); _commandLineValuesBackup = new Dictionary <MemberInfo, object>(); _activeSet = null; _defaultSet = null; _hasDefaultSet = true; }
public CmdletParameterBinder(CmdletInfo cmdletInfo, Cmdlet cmdlet) { _cmdletInfo = cmdletInfo; _cmdlet = cmdlet; _defaultValues = new Dictionary<MemberInfo, object>(); _boundParameters = new Collection<MemberInfo>(); _candidateParameterSets = new Collection<CommandParameterSetInfo>(); _commandLineValuesBackup = new Dictionary<MemberInfo, object>(); _activeSet = null; _defaultSet = null; _hasDefaultSet = true; }
private IEnumerable <CommandParameterInfo> GetMandatoryUnboundParameters(CommandParameterSetInfo parameterSet, bool considerPipeline) { if (parameterSet == null) { return(Enumerable.Empty <CommandParameterInfo>()); } return(from param in parameterSet.Parameters where param.IsMandatory && !_boundParameters.Contains(param.MemberInfo) && (considerPipeline || !(param.ValueFromPipeline || param.ValueFromPipelineByPropertyName) ) select param); }
// 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]; } }
public CmdletParameterBinder(CmdletInfo cmdletInfo, Cmdlet cmdlet) { _cmdletInfo = cmdletInfo; _cmdlet = cmdlet; _defaultValues = new Dictionary <MemberInfo, object>(); _boundParameters = new Collection <MemberInfo>(); _candidateParameterSets = _cmdletInfo.ParameterSets.ToList(); _commandLineValuesBackup = new Dictionary <MemberInfo, object>(); _activeSet = null; _defaultSet = null; _hasDefaultSet = true; _commonParameters = (from parameter in CommonCmdletParameters.CommonParameterSetInfo.Parameters select parameter.MemberInfo).ToList(); _engineIntrinsics = new EngineIntrinsics(_cmdlet.ExecutionContext); }
public CmdletParameterBinder(CmdletInfo cmdletInfo, Cmdlet cmdlet) { _cmdletInfo = cmdletInfo; _cmdlet = cmdlet; _defaultValues = new Dictionary<MemberInfo, object>(); _boundParameters = new Collection<MemberInfo>(); _candidateParameterSets = _cmdletInfo.ParameterSets.ToList(); _commandLineValuesBackup = new Dictionary<MemberInfo, object>(); _activeSet = null; _defaultSet = null; _hasDefaultSet = true; _commonParameters = (from parameter in CommonCmdletParameters.CommonParameterSetInfo.Parameters select parameter.MemberInfo).ToList(); _engineIntrinsics = new EngineIntrinsics(_cmdlet.ExecutionContext); }
public CmdletParameterBinder(CmdletInfo cmdletInfo, Cmdlet cmdlet) { _cmdletInfo = cmdletInfo; _cmdlet = cmdlet; _defaultValues = new Dictionary <MemberInfo, object>(); _boundParameters = new Collection <MemberInfo>(); _candidateParameterSets = _cmdletInfo.ParameterSets.ToList(); _commandLineValuesBackup = new Dictionary <MemberInfo, object>(); _activeSet = null; _defaultSet = null; _hasDefaultSet = true; _bindDestinationLookup = new Dictionary <MemberInfo, object>(); _engineIntrinsics = new EngineIntrinsics(_cmdlet.ExecutionContext); // make sure common parameters are set in the CommonParameter member object, not the cmdlet itself AddBindDestionations(CommonCmdletParameters.ParameterDiscovery, _cmdlet.CommonParameters); }
public CmdletParameterBinder(CmdletInfo cmdletInfo, Cmdlet cmdlet) { _cmdletInfo = cmdletInfo; _cmdlet = cmdlet; _defaultValues = new Dictionary<MemberInfo, object>(); _boundParameters = new Collection<MemberInfo>(); _candidateParameterSets = _cmdletInfo.ParameterSets.ToList(); _commandLineValuesBackup = new Dictionary<MemberInfo, object>(); _activeSet = null; _defaultSet = null; _hasDefaultSet = true; _bindDestinationLookup = new Dictionary<MemberInfo, object>(); _engineIntrinsics = new EngineIntrinsics(_cmdlet.ExecutionContext); // make sure common parameters are set in the CommonParameter member object, not the cmdlet itself AddBindDestionations(CommonCmdletParameters.ParameterDiscovery, _cmdlet.CommonParameters); }
private void HandleMissingMandatoryParameters(CommandParameterSetInfo parameterSet, bool considerPipeline, bool askUser) { // select mandatory parametes var unsetMandatories = GetMandatoryUnboundParameters(parameterSet, considerPipeline).ToList(); // check if we got something to do, otherwise we're fine if (unsetMandatories.Count == 0) { return; } Dictionary <CommandParameterInfo, PSObject> values = null; if (askUser) { // try to get this value from UI values = GatherParameterValues(unsetMandatories); } if (values == null) { var parameterNames = from cmdInfo in unsetMandatories select "'" + cmdInfo.Name + "'"; var missingNames = String.Join(", ", parameterNames); var msg = String.Format("Missing value for mandatory parameters {0}.", missingNames); throw new ParameterBindingException(msg, "MissingMandatoryParameters"); } foreach (var pair in values) { if (pair.Value == null) { // WORKAROUND: PS throws a MethodInvocationException when binding pipeline parameters // that is when a user shouldn't be asked anymore... let's do the same if (askUser) { var msg = String.Format("Missing value for mandatory parameter '{0}'.", pair.Key.Name); throw new ParameterBindingException(msg, "MissingMandatoryParameter"); } else { var msg = "The input object cannot be bound as it doesn't provide some mandatory information: " + pair.Key.Name; throw new MethodInvocationException(msg); } } BindParameter(pair.Key, pair.Value, true); } }
private void CheckForActiveParameterSet() { // if we only have one parameter set, this is always the active one (e.g. AllParametersSets) var setCount = _cmdletInfo.ParameterSets.Count; if (setCount == 1) { if (_activeSet == null) { _activeSet = _cmdletInfo.ParameterSets[0]; } return; } // if we have two sets and one is AllParametersSets, then the other one is naturally the default else if (setCount == 2) { var firstSet = _cmdletInfo.ParameterSets[0]; var secondSet = _cmdletInfo.ParameterSets[1]; if (firstSet.Name.Equals(ParameterAttribute.AllParameterSets)) { _activeSet = secondSet; return; } else if (secondSet.Name.Equals(ParameterAttribute.AllParameterSets)) { _activeSet = firstSet; return; } } // otherwise we have more than one parameter set with name // even if an activeSet was already chosen, make sure there ist at most one active set foreach (var param in _boundParameters) { string activeSetName; if (_cmdletInfo.UniqueSetParameters.TryGetValue(param.Name, out activeSetName)) { if (_activeSet != null && !_activeSet.Name.Equals(activeSetName)) { throw new ParameterBindingException("The parameter set selection is ambiguous!", "AmbiguousParameterSet"); } _activeSet = _cmdletInfo.GetParameterSetByName(activeSetName); } } }
private void BindPositionalParameters(CommandParameterCollection parameters, CommandParameterSetInfo parameterSet) { var parametersWithoutName = from param in parameters where String.IsNullOrEmpty(param.Name) select param; if (parameterSet == null) { if (parametersWithoutName.Any()) { ThrowAmbiguousParameterSetException(); } return; } var positionals = (from param in parameterSet.Parameters where param.Position >= 0 orderby param.Position ascending select param).ToList(); int i = 0; foreach (var curParam in parametersWithoutName) { bool bound = false; while (!bound) { if (i < positionals.Count) { var affectedParam = positionals[i]; if (!_boundParameters.Contains(affectedParam.MemberInfo)) { BindParameter(affectedParam, curParam.Value, true); bound = true; } i++; } else { var msg = String.Format("Positional parameter not found for provided argument '{0}'", curParam.Value); throw new ParameterBindingException(msg, "PositionalParameterNotFound"); } } } }
private void CheckForAllSetsParameters(CommandParameterSetInfo set) { CommandParameterInfo inputObjectParam = set.GetParameterByName("InputObject"); Assert.IsNotNull(inputObjectParam); Assert.AreEqual("InputObject", inputObjectParam.Name); Assert.AreEqual(-1, inputObjectParam.Position); Assert.AreEqual(false, inputObjectParam.IsMandatory); CommandParameterInfo nameParam = set.GetParameterByName("Name"); Assert.IsNotNull(nameParam); Assert.AreEqual("Name", nameParam.Name); Assert.AreEqual(1, nameParam.Position); Assert.AreEqual(false, nameParam.IsMandatory); CommandParameterInfo recurseParam = set.GetParameterByName("Recurse"); Assert.IsNotNull(recurseParam); Assert.AreEqual("Recurse", recurseParam.Name); Assert.AreEqual(-1, recurseParam.Position); Assert.AreEqual(false, recurseParam.IsMandatory); }
public override string ToString() { StringBuilder result = new StringBuilder(); List <CommandParameterInfo> commandParameterInfoList1 = new List <CommandParameterInfo>(); List <CommandParameterInfo> commandParameterInfoList2 = new List <CommandParameterInfo>(); foreach (CommandParameterInfo parameter in this.parameters) { if (parameter.Position == int.MinValue) { commandParameterInfoList2.Add(parameter); } else { if (parameter.Position >= commandParameterInfoList1.Count) { for (int count = commandParameterInfoList1.Count; count <= parameter.Position; ++count) { commandParameterInfoList1.Add((CommandParameterInfo)null); } } commandParameterInfoList1[parameter.Position] = parameter; } } foreach (CommandParameterInfo parameter in commandParameterInfoList1) { if (parameter != null) { CommandParameterSetInfo.AppendFormatCommandParameterInfo(parameter, ref result); } } foreach (CommandParameterInfo parameter in commandParameterInfoList2) { if (parameter != null) { CommandParameterSetInfo.AppendFormatCommandParameterInfo(parameter, ref result); } } CommandParameterSetInfo.tracer.WriteLine("ToString = {0}", (object)result.ToString()); return(result.ToString()); }
private void BindPositionalParameters(CommandParameterCollection parameters, CommandParameterSetInfo parameterSet) { var parametersWithoutName = from param in parameters where String.IsNullOrEmpty(param.Name) select param; if (parameterSet == null) { if (parametersWithoutName.Any()) { throw new ParameterBindingException("The parameter set to be used cannot be resolved.", "AmbiguousParameterSet"); } return; } var positionals = (from param in parameterSet.Parameters where param.Position >= 0 orderby param.Position ascending select param).ToList(); int i = 0; foreach (var curParam in parametersWithoutName) { if (i < positionals.Count) { var affectedParam = positionals[i]; BindParameter(affectedParam, curParam.Value, true); i++; } else { var msg = String.Format("Positional parameter not found for provided argument '{0}'", curParam.Value); throw new ParameterBindingException(msg, "PositionalParameterNotFound"); } } }
private void CheckForActiveParameterSet() { // if we only have one parameter set, this is always the active one (e.g. AllParametersSets) var setCount = _cmdletInfo.ParameterSets.Count; if (setCount == 1) { if (_activeSet == null) { _activeSet = _cmdletInfo.ParameterSets[0]; } return; } // if we have two sets and one is AllParametersSets, then the other one is naturally the default else if (setCount == 2) { var firstSet = _cmdletInfo.ParameterSets[0]; var secondSet = _cmdletInfo.ParameterSets[1]; if (firstSet.Name.Equals(ParameterAttribute.AllParameterSets)) { _activeSet = secondSet; return; } else if (secondSet.Name.Equals(ParameterAttribute.AllParameterSets)) { _activeSet = firstSet; return; } } // otherwise we have more than one parameter set with name // even if an activeSet was already chosen, make sure there ist at most one active set foreach (var param in _boundParameters) { string activeSetName; if (_cmdletInfo.UniqueSetParameters.TryGetValue(param.Name, out activeSetName)) { if (_activeSet != null && !_activeSet.Name.Equals(activeSetName)) { throw new ParameterBindingException("The parameter set selection is ambiguous!", "AmbiguousParameterSet"); } _activeSet = _cmdletInfo.GetParameterSetByName(activeSetName); } } }
private void ChooseParameterSet(CommandParameterSetInfo chosenSet) { if (chosenSet != null) { _cmdlet.ParameterSetName = chosenSet.Name; } }
private void BindPositionalParameters(CommandParameterCollection parameters, CommandParameterSetInfo parameterSet) { var parametersWithoutName = from param in parameters where String.IsNullOrEmpty(param.Name) select param; if (parameterSet == null) { if (parametersWithoutName.Any()) { throw new ParameterBindingException("The parameter set to be used cannot be resolved.", "AmbiguousParameterSet"); } return; } var positionals = (from param in parameterSet.Parameters where param.Position >= 0 orderby param.Position ascending select param).ToList(); int i = 0; foreach (var curParam in parametersWithoutName) { if (i < positionals.Count) { var affectedParam = positionals[i]; BindParameter(affectedParam, curParam.Value, true); i++; } else { var msg = String.Format("Positional parameter not found for provided argument '{0}'", curParam.Value); throw new ParameterBindingException(msg, "PositionalParameterNotFound"); } } }
private void HandleMissingMandatoryParameters(CommandParameterSetInfo parameterSet, bool considerPipeline, bool askUser) { // select mandatory parametes var unsetMandatories = GetMandatoryUnboundParameters(parameterSet, considerPipeline); foreach (var curParam in unsetMandatories) { object value = null; // check if we should try to gather it if (askUser) { // try to get this value from UI GatherParameterValue(curParam); } // check if we had success, fail otherwise if (value == null) { // WORKAROUND: PS throws a MethodInvocationException when binding pipeline parameters // that is when a user shouldn't be asked anymore... let's do the same if (askUser) { var msg = String.Format("Missing value for mandatory parameter '{0}'.", curParam.Name); throw new ParameterBindingException(msg, "MissingMandatoryParameter"); } else { var msg = "The input object cannot be bound as it doesn't provide some mandatory information: " + curParam.Name; throw new MethodInvocationException(msg); } } BindParameter(curParam, value, true); } }
private void SetCmdletParameterSetName(CommandParameterSetInfo chosenSet) { if (_cmdlet is PSCmdlet) { ((PSCmdlet)_cmdlet).ParameterSetName = chosenSet != null ? chosenSet.Name : ParameterAttribute.AllParameterSets; } }
private CommandParameterCollection BindDynamicParameters(CommandParameterCollection parameters) { var dynamicParamsCmdlet = _cmdlet as IDynamicParameters; if (dynamicParamsCmdlet == null) // no support for dynamic parameters { return parameters; } // get the object with dynamic parameters var parameterObject = dynamicParamsCmdlet.GetDynamicParameters(); if (parameterObject == null) { return parameters; } var discovery = new CommandParameterDiscovery(parameterObject.GetType()); // add the parameters to the cmdletInfo _cmdletInfo.AddParametersToAllSets(discovery); // as we updated parameter sets, we need to rebuild some cached values _activeSet = _activeSet == null ? null : GetParameterSet(_activeSet.Name); _defaultSet = _defaultSet == null ? null : GetParameterSet(_defaultSet.Name); _candidateParameterSets = (from p in _candidateParameterSets select GetParameterSet(p.Name)).ToList(); AddBindDestionations(discovery, parameterObject); // now try to rebind the parameters parameters = BindNamedParameters(parameters); return BindPositionalParameters(parameters, ActiveOrDefaultParameterSet); }
private CommandParameterCollection BindPositionalParameters(CommandParameterCollection parameters, CommandParameterSetInfo parameterSet) { var parametersWithoutName = from param in parameters where String.IsNullOrEmpty(param.Name) select param; if (parameterSet == null) { if (parametersWithoutName.Any()) { ThrowAmbiguousParameterSetException(); } return parameters; } var positionals = (from param in parameterSet.Parameters where param.Position >= 0 && !_boundParameters.Contains(param.MemberInfo) orderby param.Position ascending select param).ToList(); int i = 0; var parametersLeft = new CommandParameterCollection(parameters); foreach (var curParam in parametersWithoutName) { if (i >= positionals.Count) { break; // can't bind it } BindParameter(positionals[i], curParam.Value, true); parametersLeft.Remove(curParam); i++; } return parametersLeft; }
private void ChooseParameterSet(CommandParameterSetInfo chosenSet) { _activeSet = chosenSet; _candidateParameterSets.Clear(); _candidateParameterSets.Add(chosenSet); SetCmdletParameterSetName(chosenSet); }
// 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]; } }
/// <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 + "'")); } } } } }
private CommandParameterCollection BindPositionalParameters(CommandParameterCollection parameters, CommandParameterSetInfo parameterSet) { var parametersWithoutName = from param in parameters where String.IsNullOrEmpty(param.Name) select param; if (parameterSet == null) { if (parametersWithoutName.Any()) { ThrowAmbiguousParameterSetException(); } return(parameters); } var positionals = (from param in parameterSet.Parameters where param.Position >= 0 && !_boundParameters.Contains(param.MemberInfo) orderby param.Position ascending select param).ToList(); int i = 0; var parametersLeft = new CommandParameterCollection(parameters); foreach (var curParam in parametersWithoutName) { if (i >= positionals.Count) { break; // can't bind it } BindParameter(positionals[i], curParam.Value, true); parametersLeft.Remove(curParam); i++; } return(parametersLeft); }
private IEnumerable<CommandParameterInfo> GetMandatoryUnboundParameters(CommandParameterSetInfo parameterSet, bool considerPipeline) { if (parameterSet == null) { return Enumerable.Empty<CommandParameterInfo>(); } return from param in parameterSet.Parameters where param.IsMandatory && !_boundParameters.Contains(param.MemberInfo) && (considerPipeline || !(param.ValueFromPipeline || param.ValueFromPipelineByPropertyName) ) select param; }
private void ThrowMissingParametersExcpetion(CommandParameterSetInfo paramSet) { var missing = GetMandatoryUnboundParameters(paramSet, true); var msg = "Missing value for mandatory parameter(s): " + String.Join(", ", missing); throw new ParameterBindingException(msg, "MissingMandatoryParameter"); }
private void HandleMissingMandatoryParameters(CommandParameterSetInfo parameterSet, bool considerPipeline, bool askUser) { // select mandatory parametes var unsetMandatories = GetMandatoryUnboundParameters(parameterSet, considerPipeline).ToList(); // check if we got something to do, otherwise we're fine if (unsetMandatories.Count == 0) { return; } Dictionary<CommandParameterInfo, PSObject> values = null; if (askUser) { // try to get this value from UI values = GatherParameterValues(unsetMandatories); } if (values == null) { var parameterNames = from cmdInfo in unsetMandatories select "'" + cmdInfo.Name + "'"; var missingNames = String.Join(", ", parameterNames); var msg = String.Format("Missing value for mandatory parameters {0}.", missingNames); throw new ParameterBindingException(msg, "MissingMandatoryParameters"); } foreach (var pair in values) { if (pair.Value == null) { // WORKAROUND: PS throws a MethodInvocationException when binding pipeline parameters // that is when a user shouldn't be asked anymore... let's do the same if (askUser) { var msg = String.Format("Missing value for mandatory parameter '{0}'.", pair.Key.Name); throw new ParameterBindingException(msg, "MissingMandatoryParameter"); } else { var msg = "The input object cannot be bound as it doesn't provide some mandatory information: " + pair.Key.Name; throw new MethodInvocationException(msg); } } BindParameter(pair.Key, pair.Value, true); } }
private void BindPositionalParameters(CommandParameterCollection parameters, CommandParameterSetInfo parameterSet) { var parametersWithoutName = from param in parameters where String.IsNullOrEmpty(param.Name) select param; if (parameterSet == null) { if (parametersWithoutName.Any()) { ThrowAmbiguousParameterSetException(); } return; } var positionals = (from param in parameterSet.Parameters where param.Position >= 0 orderby param.Position ascending select param).ToList(); int i = 0; foreach (var curParam in parametersWithoutName) { bool bound = false; while (!bound) { if (i < positionals.Count) { var affectedParam = positionals[i]; if (!_boundParameters.Contains(affectedParam.MemberInfo)) { BindParameter(affectedParam, curParam.Value, true); bound = true; } i++; } else { var msg = String.Format("Positional parameter not found for provided argument '{0}'", curParam.Value); throw new ParameterBindingException(msg, "PositionalParameterNotFound"); } } } }
/// <summary> /// Constructs an instance of a ParameterSetSignature /// </summary> /// <param name="commandParamInfoSet">Collection of parameter info</param> public ParameterSetSignature(CommandParameterSetInfo commandParamInfoSet) { List<ParameterInfo> parameterInfo = new List<ParameterInfo>(); foreach (CommandParameterInfo commandParameterInfo in commandParamInfoSet.Parameters) { if (!commonParameterNames.Contains(commandParameterInfo.Name)) { parameterInfo.Add(new ParameterInfo(commandParameterInfo)); } } SignatureText = commandParamInfoSet.ToString(); Parameters = parameterInfo.ToArray(); }
/// <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); } } } } }