Esempio n. 1
0
        private bool PrepareCommandElements(ExecutionContext context)
        {
            int commandIndex = 0;
            bool dotSource = _commandAst.InvocationOperator == TokenKind.Dot;

            CommandProcessorBase processor = null;
            string commandName = null;
            bool psuedoWorkflowCommand = false;
            try
            {
                processor = PrepareFromAst(context, out commandName) ?? context.CreateCommand(commandName, dotSource);
            }
            catch (RuntimeException rte)
            {
                // Failed to create the CommandProcessor;
                CommandProcessorBase.CheckForSevereException(rte);

                if (_commandAst.IsInWorkflow() &&
                    commandName != null &&
                    CompletionCompleters.PseudoWorkflowCommands.Contains(commandName, StringComparer.OrdinalIgnoreCase))
                {
                    psuedoWorkflowCommand = true;
                }
                else
                {
                    return false;
                }
            }

            var commandProcessor = processor as CommandProcessor;
            var scriptProcessor = processor as ScriptCommandProcessorBase;
            bool implementsDynamicParameters = commandProcessor != null &&
                                               commandProcessor.CommandInfo.ImplementsDynamicParameters;

            var argumentsToGetDynamicParameters = implementsDynamicParameters
                                                      ? new List<object>(_commandElements.Count)
                                                      : null;
            if (commandProcessor != null || scriptProcessor != null || psuedoWorkflowCommand)
            {
                // Pre-processing the arguments -- command arguments
                for (commandIndex++; commandIndex < _commandElements.Count; commandIndex++)
                {
                    var parameter = _commandElements[commandIndex] as CommandParameterAst;
                    if (parameter != null)
                    {
                        if (argumentsToGetDynamicParameters != null)
                        {
                            argumentsToGetDynamicParameters.Add(parameter.Extent.Text);
                        }

                        AstPair parameterArg = parameter.Argument != null
                            ? new AstPair(parameter)
                            : new AstPair(parameter, (ExpressionAst)null);

                        _arguments.Add(parameterArg);
                    }
                    else
                    {
                        var dash = _commandElements[commandIndex] as StringConstantExpressionAst;
                        if (dash != null && dash.Value.Trim().Equals("-", StringComparison.OrdinalIgnoreCase))
                        {
                            // "-" is represented by StringConstantExpressionAst. Most likely the user type a tab here,
                            // and we don't want it be treated as an argument
                            continue;
                        }

                        var expressionArgument = _commandElements[commandIndex] as ExpressionAst;
                        if (expressionArgument != null)
                        {
                            if (argumentsToGetDynamicParameters != null)
                            {
                                argumentsToGetDynamicParameters.Add(expressionArgument.Extent.Text);
                            }

                            _arguments.Add(new AstPair(null, expressionArgument));
                        }
                    }
                }
            }

            if (commandProcessor != null)
            {
                _function = false;
                if (implementsDynamicParameters)
                {
                    ParameterBinderController.AddArgumentsToCommandProcessor(commandProcessor, argumentsToGetDynamicParameters.ToArray());
                    bool retryWithNoArgs = false, alreadyRetried = false;

                    do
                    {
                        CommandProcessorBase oldCurrentCommandProcessor = context.CurrentCommandProcessor;
                        try
                        {
                            context.CurrentCommandProcessor = commandProcessor;
                            commandProcessor.SetCurrentScopeToExecutionScope();
                            // Run method "BindCommandLineParametersNoValidation" to get all available parameters, including the dynamic
                            // parameters (some of them, not necessarilly all. Since we don't do the actual binding, some dynamic parameters
                            // might not be retrieved). 
                            if (!retryWithNoArgs)
                            {
                                // Win8 345299: First try with all unbounded arguments
                                commandProcessor.CmdletParameterBinderController.BindCommandLineParametersNoValidation(commandProcessor.arguments);
                            }
                            else
                            {
                                // Win8 345299: If the first try ended with ParameterBindingException, try again with no arguments
                                alreadyRetried = true;
                                commandProcessor.CmdletParameterBinderController.ClearUnboundArguments();
                                commandProcessor.CmdletParameterBinderController.BindCommandLineParametersNoValidation(new Collection<CommandParameterInternal>());
                            }
                        }
                        catch (ParameterBindingException e)
                        {
                            // Catch the parameter binding exception thrown when Reparsing the argument.
                            //   "MissingArgument" - a single parameter is matched, but no argument is present
                            //   "AmbiguousParameter" - multiple parameters are matched
                            // When such exceptions are caught, retry again without arguments, so as to get dynamic parameters
                            // based on the current provider
                            if (e.ErrorId == "MissingArgument" || e.ErrorId == "AmbiguousParameter")
                                retryWithNoArgs = true;
                        }
                        catch (Exception e)
                        {
                            CommandProcessorBase.CheckForSevereException(e);
                        }
                        finally
                        {
                            context.CurrentCommandProcessor = oldCurrentCommandProcessor;
                            commandProcessor.RestorePreviousScope();
                        }
                    } while (retryWithNoArgs && !alreadyRetried);
                }
                // Get all bindable parameters and initialize the _unboundParameters
                _commandInfo = commandProcessor.CommandInfo;
                _commandName = commandProcessor.CommandInfo.Name;
                _bindableParameters = commandProcessor.CmdletParameterBinderController.BindableParameters;
                _defaultParameterSetFlag = commandProcessor.CommandInfo.CommandMetadata.DefaultParameterSetFlag;
            }
            else if (scriptProcessor != null)
            {
                _function = true;
                _commandInfo = scriptProcessor.CommandInfo;
                _commandName = scriptProcessor.CommandInfo.Name;
                _bindableParameters = scriptProcessor.ScriptParameterBinderController.BindableParameters;
                _defaultParameterSetFlag = 0;
            }
            else if (!psuedoWorkflowCommand)
            {
                // The command is not a function, cmdlet and script cmdlet
                return false;
            }

            if (_commandAst.IsInWorkflow())
            {
                var converterType = Type.GetType(Utils.WorkflowType);
                if (converterType != null)
                {
                    var activityParameters = (Dictionary<string, Type>)converterType.GetMethod("GetActivityParameters").Invoke(null, new object[] { _commandAst });
                    if (activityParameters != null)
                    {
                        bool needToRemoveReplacedProperty = activityParameters.ContainsKey("PSComputerName") &&
                                                            !activityParameters.ContainsKey("ComputerName");

                        var parametersToAdd = new List<MergedCompiledCommandParameter>();
                        var attrCollection = new Collection<Attribute> { new ParameterAttribute() };
                        foreach (var pair in activityParameters)
                        {
                            if (psuedoWorkflowCommand || !_bindableParameters.BindableParameters.ContainsKey(pair.Key))
                            {
                                Type parameterType = GetActualActivityParameterType(pair.Value);
                                var runtimeDefinedParameter = new RuntimeDefinedParameter(pair.Key, parameterType, attrCollection);
                                var compiledCommandParameter = new CompiledCommandParameter(runtimeDefinedParameter, false) { IsInAllSets = true };
                                var mergedCompiledCommandParameter = new MergedCompiledCommandParameter(compiledCommandParameter, ParameterBinderAssociation.DeclaredFormalParameters);
                                parametersToAdd.Add(mergedCompiledCommandParameter);
                            }
                        }
                        if (parametersToAdd.Any())
                        {
                            var mergedBindableParameters = new MergedCommandParameterMetadata();
                            if (!psuedoWorkflowCommand)
                            {
                                mergedBindableParameters.ReplaceMetadata(_bindableParameters);
                            }
                            foreach (var p in parametersToAdd)
                            {
                                mergedBindableParameters.BindableParameters.Add(p.Parameter.Name, p);
                            }
                            _bindableParameters = mergedBindableParameters;
                        }

                        // Remove common parameters that are supported by all commands, but not
                        // by workflows
                        bool fixedReadOnly = false;
                        foreach (var ignored in _ignoredWorkflowParameters)
                        {
                            if (_bindableParameters.BindableParameters.ContainsKey(ignored))
                            {
                                // However, some ignored parameters are explicitly implemented by
                                // activities, so keep them.
                                if (!activityParameters.ContainsKey(ignored))
                                {
                                    if (!fixedReadOnly)
                                    {
                                        _bindableParameters.ResetReadOnly();
                                        fixedReadOnly = true;
                                    }

                                    _bindableParameters.BindableParameters.Remove(ignored);
                                }
                            }
                        }

                        if (_bindableParameters.BindableParameters.ContainsKey("ComputerName") && needToRemoveReplacedProperty)
                        {
                            if (!fixedReadOnly)
                            {
                                _bindableParameters.ResetReadOnly();
                                fixedReadOnly = true;
                            }

                            _bindableParameters.BindableParameters.Remove("ComputerName");
                            string aliasOfComputerName = (from aliasPair in _bindableParameters.AliasedParameters
                                                          where String.Equals("ComputerName", aliasPair.Value.Parameter.Name)
                                                          select aliasPair.Key).FirstOrDefault();
                            if (aliasOfComputerName != null)
                            {
                                _bindableParameters.AliasedParameters.Remove(aliasOfComputerName);
                            }
                        }
                    }
                }
            }
            _unboundParameters.AddRange(_bindableParameters.BindableParameters.Values);

            // Pre-processing the arguments -- pipeline input
            // Check if there is pipeline input
            CommandBaseAst preCmdBaseAst = null;
            var pipe = _commandAst.Parent as PipelineAst;
            Diagnostics.Assert(pipe != null, "CommandAst should has a PipelineAst parent");
            if (pipe.PipelineElements.Count > 1)
            {
                foreach (CommandBaseAst cmdBase in pipe.PipelineElements)
                {
                    if (cmdBase.GetHashCode() == _commandAst.GetHashCode())
                    {
                        _isPipelineInputExpected = preCmdBaseAst != null;
                        if (_isPipelineInputExpected)
                            _pipelineInputType = typeof(object);
                        break;
                    }
                    preCmdBaseAst = cmdBase;
                }
            }

            return true;
        }
Esempio n. 2
0
        /// <summary>
        /// Initialize collection/dictionary members when it's necessary
        /// </summary>
        private void InitializeMembers()
        {
            List<string> supportedCommonParameters = new List<string>() { "Verbose", "Debug", "ErrorAction", "WarningAction", "InformationAction" };
            _ignoredWorkflowParameters = new List<string>(Cmdlet.CommonParameters.Concat<string>(Cmdlet.OptionalCommonParameters));
            _ignoredWorkflowParameters.RemoveAll(item => supportedCommonParameters.Contains(item, StringComparer.OrdinalIgnoreCase));

            // Initializing binding realted members
            _function = false;
            _commandName = null;
            _currentParameterSetFlag = uint.MaxValue;
            _defaultParameterSetFlag = 0;
            _bindableParameters = null;

            // reuse the collections/dictionaries
            _arguments = _arguments ?? new Collection<AstParameterArgumentPair>();
            _boundParameters = _boundParameters ?? new Dictionary<string, MergedCompiledCommandParameter>(StringComparer.OrdinalIgnoreCase);
            _boundArguments = _boundArguments ?? new Dictionary<string, AstParameterArgumentPair>(StringComparer.OrdinalIgnoreCase);
            _unboundParameters = _unboundParameters ?? new List<MergedCompiledCommandParameter>();
            _boundPositionalParameter = _boundPositionalParameter ?? new Collection<string>();
            _bindingExceptions = _bindingExceptions ?? new Dictionary<CommandParameterAst, ParameterBindingException>();

            _arguments.Clear();
            _boundParameters.Clear();
            _unboundParameters.Clear();
            _boundArguments.Clear();
            _boundPositionalParameter.Clear();
            _bindingExceptions.Clear();

            // Initializing tab expansion related members
            _pipelineInputType = null;
            _bindingEffective = true;
            _isPipelineInputExpected = false;

            // reuse the collections
            _parametersNotFound = _parametersNotFound ?? new Collection<CommandParameterAst>();
            _ambiguousParameters = _ambiguousParameters ?? new Collection<CommandParameterAst>();
            _duplicateParameters = _duplicateParameters ?? new Collection<AstParameterArgumentPair>();

            _parametersNotFound.Clear();
            _ambiguousParameters.Clear();
            _duplicateParameters.Clear();
        }