/// <summary> /// Retrieve the pipeline input of a specified cmdlet. /// </summary> /// <param name="commandRuntime">The runtime of the cmdlet whose pipeline should be retrieved.</param> /// <param name="cmdlet">The cmdlet whose pipeline should be retrieved.</param> /// <returns></returns> private static Pipeline GetCmdletPipelineInput(ICommandRuntime commandRuntime, InternalCommand cmdlet) { var inputPipe = commandRuntime.GetInternalProperty("InputPipe"); var enumerator = inputPipe.GetInternalField("_enumeratorToProcess"); var currentPS = (PSObject)cmdlet.GetInternalProperty("CurrentPipelineObject"); var current = PSObjectToString(currentPS) == string.Empty || currentPS == null ? null : currentPS.BaseObject; if (enumerator == null) //Piping from a cmdlet { if (current == null) { return(null); } return(new Pipeline(current, new List <object> { current })); } else //Piping from a variable { var declaringType = enumerator.GetType().DeclaringType; var enumeratorType = enumerator.GetType(); IEnumerable <object> list; if (declaringType == typeof(Array) || enumeratorType.Name == "SZArrayEnumerator") //It's a SZArrayEnumerator (piping straight from a variable). In .NET Core 3.1 SZArrayEnumerator is no longer nested { list = ((object[])enumerator.GetInternalField("_array")); } else if (declaringType == typeof(List <>)) //It's a List<T>.Enumerator (piping from $groups[0].Group) { list = enumerator.PSGetInternalField("_list", "list", null).ToIEnumerable(); } else if (enumeratorType.IsGenericType && enumeratorType.GetGenericTypeDefinition() == typeof(ReadOnlyListEnumerator <>)) { list = enumerator.GetInternalField("list").ToIEnumerable(); } else { throw new NotImplementedException($"Don't know how to extract the pipeline input from a '{enumeratorType}' enumerator from type '{declaringType}'."); } list = list.Select(o => { var pso = o as PSObject; if (pso != null) { return(pso.BaseObject); } return(o); }); return(new Pipeline(current, list.ToList())); } }
/// <summary> /// Retrieve the pipeline input of a specified cmdlet. /// </summary> /// <param name="commandRuntime">The runtime of the cmdlet whose pipeline should be retrieved.</param> /// <param name="cmdlet">The cmdlet whose pipeline should be retrieved.</param> /// <returns></returns> private static Pipeline GetCmdletPipelineInput(ICommandRuntime commandRuntime, InternalCommand cmdlet) { var inputPipe = commandRuntime.GetInternalProperty("InputPipe"); var enumerator = inputPipe.GetInternalField("_enumeratorToProcess"); var currentPS = (PSObject)cmdlet.GetInternalProperty("CurrentPipelineObject"); var current = PSObjectToString(currentPS) == string.Empty || currentPS == null ? null : currentPS.BaseObject; if (enumerator == null) //Piping from a cmdlet { if (current == null) { return(null); } return(new Pipeline(current, new List <object> { current })); } else //Piping from a variable { var array = ((object[])enumerator.GetInternalField("_array")).Select(o => { if (o is PSObject) { return(o); } else { return(new PSObject(o)); } }).Cast <PSObject>(); return(new Pipeline(current, array.Select(e => e.BaseObject).ToList())); } }