public override Dictionary <string, PSObject> Prompt(string caption, string message, System.Collections.ObjectModel.Collection <FieldDescription> descriptions) { this.Write(caption + "\n" + message + " "); Dictionary <string, PSObject> results = new Dictionary <string, PSObject>(); foreach (FieldDescription fd in descriptions) { string[] label = GetHotkeyAndLabel(fd.Label); this.WriteLine(label[1]); string data = this.ReadLine(); if (data == null) { return(null); } results[fd.Name] = PSObject.AsPSObject(data); } return(results); }
/// <summary> /// Override - Modify Parameters element in maml1 using the Parameters element from maml2. /// This will copy parameters from maml2 that are not present in maml1. /// </summary> internal static void OverrideParameters(PSObject maml1, PSObject maml2) { string[] parametersPath = new string[] { "Parameters", "Parameter" }; // Final collection of PSObjects. List <object> maml2items = new List <object>(); // Add maml2 first since we are prepending. // For maml2: Add as collection or single item. No-op if PSPropertyInfo propertyInfo2 = GetPropertyInfo(maml2, parametersPath); var array = propertyInfo2.Value as Array; if (array != null) { maml2items.AddRange(array as IEnumerable <object>); } else { maml2items.Add(PSObject.AsPSObject(propertyInfo2.Value)); } // Extend maml1 to make sure the property-path exists - since we'll be modifying it soon. EnsurePropertyInfoPathExists(maml1, parametersPath); // For maml1: Add as collection or single item. Do nothing if null or some other type. PSPropertyInfo propertyInfo1 = GetPropertyInfo(maml1, parametersPath); List <object> maml1items = new List <object>(); array = propertyInfo1.Value as Array; if (array != null) { maml1items.AddRange(array as IEnumerable <object>); } else { maml1items.Add(PSObject.AsPSObject(propertyInfo1.Value)); } // copy parameters from maml2 that are not present in maml1 for (int index = 0; index < maml2items.Count; index++) { PSObject m2paramObj = PSObject.AsPSObject(maml2items[index]); string param2Name = string.Empty; PSPropertyInfo m2propertyInfo = m2paramObj.Properties["Name"]; if (m2propertyInfo != null) { if (!LanguagePrimitives.TryConvertTo <string>(m2propertyInfo.Value, out param2Name)) { continue; } } bool isParamFoundInMaml1 = false; foreach (PSObject m1ParamObj in maml1items) { string param1Name = string.Empty; PSPropertyInfo m1PropertyInfo = m1ParamObj.Properties["Name"]; if (m1PropertyInfo != null) { if (!LanguagePrimitives.TryConvertTo <string>(m1PropertyInfo.Value, out param1Name)) { continue; } } if (param1Name.Equals(param2Name, StringComparison.OrdinalIgnoreCase)) { isParamFoundInMaml1 = true; } } if (!isParamFoundInMaml1) { maml1items.Add(maml2items[index]); } } // Now replace in maml1. If items.Count == 0 do nothing since Value is already null. if (maml1items.Count == 1) { propertyInfo1.Value = maml1items[0]; } else if (maml1items.Count >= 2) { propertyInfo1.Value = maml1items.ToArray(); } }
internal static Uri GetUriFromCommandPSObject(PSObject commandFullHelp) { // this object knows Maml format... // So retrieve Uri information as per the format.. if ((commandFullHelp == null) || (commandFullHelp.Properties["relatedLinks"] == null) || (commandFullHelp.Properties["relatedLinks"].Value == null)) { // return the default.. return(null); } PSObject relatedLinks = PSObject.AsPSObject(commandFullHelp.Properties["relatedLinks"].Value); if (relatedLinks.Properties["navigationLink"] == null) { return(null); } object[] navigationLinks = (object[])LanguagePrimitives.ConvertTo( relatedLinks.Properties["navigationLink"].Value, typeof(object[]), CultureInfo.InvariantCulture); foreach (object navigationLinkAsObject in navigationLinks) { if (navigationLinkAsObject == null) { continue; } PSObject navigationLink = PSObject.AsPSObject(navigationLinkAsObject); PSNoteProperty uriNP = navigationLink.Properties["uri"] as PSNoteProperty; if (uriNP != null) { string uriString = string.Empty; LanguagePrimitives.TryConvertTo <string>(uriNP.Value, CultureInfo.InvariantCulture, out uriString); if (!string.IsNullOrEmpty(uriString)) { if (!System.Uri.IsWellFormedUriString(uriString, UriKind.RelativeOrAbsolute)) { // WinBlue: 545315 Online help links are broken with localized help // Example: https://go.microsoft.com/fwlink/?LinkID=113324 (moglicherwei se auf Englisch) // Split the string based on <s> (space). We decided to go with this approach as // UX localization authors use spaces. Correctly extracting only the wellformed URI // is out-of-scope for this fix. string[] tempUriSplitArray = uriString.Split(Utils.Separators.Space); uriString = tempUriSplitArray[0]; } try { return(new System.Uri(uriString)); // return only the first Uri (ignore other uris) } catch (UriFormatException) { throw PSTraceSource.NewInvalidOperationException(HelpErrors.InvalidURI, uriString); } } } } return(null); }
/// <summary> /// Convert between types. /// </summary> /// <param name="valueToConvert">The value to convert.</param> /// <param name="resultType">The type you want to convert to.</param> /// <param name="formatProvider">The format provider to use for type conversions.</param> /// <returns>The converted type.</returns> public static object ConvertTo(object valueToConvert, Type resultType, IFormatProvider formatProvider) { // TODO: Make it use formatProvider // TODO: read more about the Extended Type System (ETS) of Powershell and enhance this functionality // TODO: check "3.7.5 Better conversion" of Windows Powershell Language Specification 3.0 if (resultType == null) { throw new ArgumentException("Result type can not be null."); } // result is no PSObject, so unpack the value if we deal with one if (valueToConvert is PSObject && resultType != typeof(PSObject) && resultType != typeof(PSObject[])) { valueToConvert = ((PSObject)valueToConvert).BaseObject; } // check if the result is an array and we have something that needs to be casted if (resultType.IsArray && valueToConvert != null && resultType != valueToConvert.GetType()) { var elementType = resultType.GetElementType(); var enumerableValue = valueToConvert as IEnumerable; // check for simple packaging if (enumerableValue == null || enumerableValue is string) // nothing "real" enumerable { var array = Array.CreateInstance(elementType, 1); array.SetValue(ConvertTo(valueToConvert, elementType, formatProvider), 0); return(array); } // otherwise we have some IEnumerable thing. recursively create a list and copy to array // a list first, because we don't know the number of arguments var list = (IList)Activator.CreateInstance(typeof(List <>).MakeGenericType(elementType)); foreach (var curValue in enumerableValue) { list.Add(ConvertTo(curValue, elementType, formatProvider)); } var targetArray = Array.CreateInstance(elementType, list.Count); for (int i = 0; i < list.Count; i++) { targetArray.SetValue(list[i], i); } return(targetArray); } // resultType is no array // TODO: use PSTypeConverters for the following! if (resultType == typeof(PSObject)) { return(PSObject.AsPSObject(valueToConvert)); } if (valueToConvert != null && resultType.IsAssignableFrom(valueToConvert.GetType())) { return(valueToConvert); } if (valueToConvert != null && resultType == typeof(String)) { return(valueToConvert.ToString()); } if (valueToConvert != null && resultType.IsEnum) // enums have to be parsed { return(Enum.Parse(resultType, valueToConvert.ToString(), true)); } if (resultType == typeof(SwitchParameter)) // switch parameters can simply be present { return(new SwitchParameter(true)); } object result = null; if (valueToConvert != null && TryConvertUsingTypeConverter(valueToConvert, resultType, out result)) { return(result); } return(DefaultConvertOrCast(valueToConvert, resultType)); }
private bool HandleKnownContainerTypes(object source, string property, int depth) { Dbg.Assert(source != null, "caller should validate the parameter"); ContainerType ct = ContainerType.None; PSObject mshSource = source as PSObject; IEnumerable enumerable = null; IDictionary dictionary = null; // If passed in object is PSObject with no baseobject, return false. if (mshSource != null && mshSource.ImmediateBaseObjectIsEmpty) { return(false); } // Check if source (or baseobject in mshSource) is known container type GetKnownContainerTypeInfo(mshSource != null ? mshSource.ImmediateBaseObject : source, out ct, out dictionary, out enumerable); if (ct == ContainerType.None) { return(false); } WriteStartOfPSObject(mshSource ?? PSObject.AsPSObject(source), property, true); switch (ct) { case ContainerType.Dictionary: { WriteDictionary(dictionary, depth); } break; case ContainerType.Stack: case ContainerType.Queue: case ContainerType.List: case ContainerType.Enumerable: { WriteEnumerable(enumerable, depth); } break; default: { Dbg.Assert(false, "All containers should be handled in the switch"); } break; } // An object which is original enumerable becomes an PSObject // with arraylist on deserialization. So on roundtrip it will show up // as List. // We serialize properties of enumerable and on deserialization mark the object // as Deserialized. So if object is marked deserialized, we should write properties. // Note: we do not serialize the properties of IEnumerable if depth is zero. if (depth != 0 && (ct == ContainerType.Enumerable || (mshSource != null && mshSource.IsDeserialized))) { // Note:Depth is the depth for serialization of baseObject. // Depth for serialization of each property is one less. WritePSObjectProperties(PSObject.AsPSObject(source), depth); } // If source is PSObject, serialize notes if (mshSource != null) { // Serialize instanceMembers PSMemberInfoCollection <PSMemberInfo> instanceMembers = mshSource.InstanceMembers; if (instanceMembers != null) { WriteMemberInfoCollection(instanceMembers, depth, true); } } _writer.WriteEndElement(); return(true); }
internal static ApartmentState GetApartmentState(object data) { using (RemotingDecoder._trace.TraceMethod()) return(RemotingDecoder.GetPropertyValue <ApartmentState>(PSObject.AsPSObject(data), "ApartmentState")); }
internal static RemoteStreamOptions GetRemoteStreamOptions(object data) { using (RemotingDecoder._trace.TraceMethod()) return(RemotingDecoder.GetPropertyValue <RemoteStreamOptions>(PSObject.AsPSObject(data), "RemoteStreamOptions")); }
internal static Exception GetExceptionFromSerializedErrorRecord( object serializedErrorRecord) { using (RemotingDecoder._trace.TraceMethod()) return((ErrorRecord.FromPSObjectForRemoting(PSObject.AsPSObject(serializedErrorRecord)) ?? throw new PSRemotingDataStructureException(PSRemotingErrorId.DecodingErrorForErrorRecord, new object[0])).Exception); }
internal static PowerShell GetPowerShell(object data) { using (RemotingDecoder._trace.TraceMethod()) return(PowerShell.FromPSObjectForRemoting(RemotingDecoder.GetPropertyValue <PSObject>(PSObject.AsPSObject(data) ?? throw new PSRemotingDataStructureException(PSRemotingErrorId.CantCastRemotingDataToPSObject, new object[1] { (object)data.GetType().FullName }), "PowerShell"))); }
internal static PSEventArgs GetPSEventArgs(PSObject dataAsPSObject) { using (RemotingDecoder._trace.TraceMethod()) { int eventIdentifier = dataAsPSObject != null?RemotingDecoder.GetPropertyValue <int>(dataAsPSObject, "PSEventArgs.EventIdentifier") : throw RemotingDecoder._trace.NewArgumentNullException(nameof(dataAsPSObject)); string propertyValue1 = RemotingDecoder.GetPropertyValue <string>(dataAsPSObject, "PSEventArgs.SourceIdentifier"); object propertyValue2 = RemotingDecoder.GetPropertyValue <object>(dataAsPSObject, "PSEventArgs.Sender"); object propertyValue3 = RemotingDecoder.GetPropertyValue <object>(dataAsPSObject, "PSEventArgs.MessageData"); string propertyValue4 = RemotingDecoder.GetPropertyValue <string>(dataAsPSObject, "PSEventArgs.ComputerName"); Guid propertyValue5 = RemotingDecoder.GetPropertyValue <Guid>(dataAsPSObject, "PSEventArgs.RunspaceId"); ArrayList arrayList = new ArrayList(); foreach (object obj in RemotingDecoder.EnumerateListProperty <object>(dataAsPSObject, "PSEventArgs.SourceArgs")) { arrayList.Add(obj); } return(new PSEventArgs(propertyValue4, propertyValue5, eventIdentifier, propertyValue1, propertyValue2, arrayList.ToArray(), propertyValue3 == null ? (PSObject)null : PSObject.AsPSObject(propertyValue3)) { TimeGenerated = RemotingDecoder.GetPropertyValue <DateTime>(dataAsPSObject, "PSEventArgs.TimeGenerated") }); } }
private static T ConvertPropertyValueTo <T>(string propertyName, object propertyValue) { using (RemotingDecoder._trace.TraceMethod()) { if (propertyName == null) { throw RemotingDecoder._trace.NewArgumentNullException(nameof(propertyName)); } if (typeof(T).IsEnum) { if (propertyValue is string) { try { return((T)Enum.Parse(typeof(T), (string)propertyValue, true)); } catch (ArgumentException ex) { throw new PSRemotingDataStructureException(PSRemotingErrorId.CantCastPropertyToExpectedType, new object[3] { (object)propertyName, (object)typeof(T).FullName, (object)propertyValue.GetType().FullName }); } } else { try { Type underlyingType = Enum.GetUnderlyingType(typeof(T)); return((T)LanguagePrimitives.ConvertTo(propertyValue, underlyingType, (IFormatProvider)CultureInfo.InvariantCulture)); } catch (InvalidCastException ex) { throw new PSRemotingDataStructureException(PSRemotingErrorId.CantCastPropertyToExpectedType, new object[3] { (object)propertyName, (object)typeof(T).FullName, (object)propertyValue.GetType().FullName }); } } } else { if (typeof(T).Equals(typeof(PSObject))) { return(propertyValue == null ? default(T) : (T)PSObject.AsPSObject(propertyValue)); } switch (propertyValue) { case null: if (!typeof(T).IsValueType) { return(default(T)); } if (typeof(T).IsGenericType && typeof(T).GetGenericTypeDefinition().Equals(typeof(Nullable <>))) { return(default(T)); } throw new PSRemotingDataStructureException(PSRemotingErrorId.CantCastPropertyToExpectedType, new object[3] { (object)propertyName, (object)typeof(T).FullName, propertyValue != null ? (object)propertyValue.GetType().FullName : (object)"null" }); case T obj: return(obj); case PSObject _: PSObject psObject = (PSObject)propertyValue; return(RemotingDecoder.ConvertPropertyValueTo <T>(propertyName, psObject.BaseObject)); case Hashtable _: if (typeof(T).Equals(typeof(PSPrimitiveDictionary))) { try { return((T) new PSPrimitiveDictionary((Hashtable)propertyValue)); } catch (ArgumentException ex) { throw new PSRemotingDataStructureException(PSRemotingErrorId.CantCastPropertyToExpectedType, new object[3] { (object)propertyName, (object)typeof(T).FullName, propertyValue != null ? (object)propertyValue.GetType().FullName : (object)"null" }); } } else { break; } } throw new PSRemotingDataStructureException(PSRemotingErrorId.CantCastPropertyToExpectedType, new object[3] { (object)propertyName, (object)typeof(T).FullName, (object)propertyValue.GetType().FullName }); } } }
/// <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); } } } } }
/// <summary> /// Handles process record event. /// </summary> /// <param name="sender"></param> /// <param name="args"></param> private void HandleProcessRecord(object sender, PSEventArgs args) { ServerSteppablePipelineDriverEventArg driverArg = (object)args.SourceEventArgs as ServerSteppablePipelineDriverEventArg; ServerSteppablePipelineDriver driver = driverArg.SteppableDriver; lock (driver.SyncObject) { // Make sure start event handler was called if (driver.SteppablePipeline == null) { return; } // make sure only one thread does the processing if (driver.ProcessingInput) { return; } driver.ProcessingInput = true; driver.Pulsed = false; } bool shouldDoComplete = false; Exception exceptionOccurred = null; try { using (ExecutionContextForStepping ctxt = ExecutionContextForStepping.PrepareExecutionContext( driver.LocalPowerShell.GetContextFromTLS(), driver.LocalPowerShell.InformationalBuffers, driver.RemoteHost)) { bool isProcessCalled = false; while (true) { if (driver.PipelineState != PSInvocationState.Running) { driver.SetState(driver.PipelineState, null); return; } if (!driver.InputEnumerator.MoveNext()) { shouldDoComplete = true; if (!driver.NoInput || isProcessCalled) { // if there is noInput then we // need to call process atleast once break; } } isProcessCalled = true; Array output; if (driver.NoInput) { output = driver.SteppablePipeline.Process(); } else { output = driver.SteppablePipeline.Process(driver.InputEnumerator.Current); } foreach (object o in output) { if (driver.PipelineState != PSInvocationState.Running) { driver.SetState(driver.PipelineState, null); return; } // send the output data to the client driver.DataStructureHandler.SendOutputDataToClient(PSObject.AsPSObject(o)); } lock (driver.SyncObject) { driver.TotalObjectsProcessed++; if (driver.TotalObjectsProcessed >= driver.Input.Count) { break; } } } } } catch (Exception e) { exceptionOccurred = e; } finally { lock (driver.SyncObject) { driver.ProcessingInput = false; driver.CheckAndPulseForProcessing(false); } // Check if should perform stop if (driver.PipelineState == PSInvocationState.Stopping) { driver.PerformStop(); } } if (shouldDoComplete) { try { using (ExecutionContextForStepping ctxt = ExecutionContextForStepping.PrepareExecutionContext( driver.LocalPowerShell.GetContextFromTLS(), driver.LocalPowerShell.InformationalBuffers, driver.RemoteHost)) { Array output = driver.SteppablePipeline.End(); foreach (object o in output) { if (driver.PipelineState != PSInvocationState.Running) { driver.SetState(driver.PipelineState, null); return; } // send the output data to the client driver.DataStructureHandler.SendOutputDataToClient(PSObject.AsPSObject(o)); } driver.SetState(PSInvocationState.Completed, null); return; } } catch (Exception e) { exceptionOccurred = e; } finally { // Check if should perform stop if (driver.PipelineState == PSInvocationState.Stopping) { driver.PerformStop(); } } } if (exceptionOccurred != null) { driver.SetState(PSInvocationState.Failed, exceptionOccurred); } }
/// <summary> /// Ensures the 'UserName' and 'HandleCount' Properties exist the Process object. /// </summary> /// <param name="process"></param> /// <param name="includeUserName"></param> /// <returns></returns> internal static PSObject AddProcessProperties(bool includeUserName, Process process) { PSObject processAsPsobj = includeUserName ? AddUserNameToProcess(process) : PSObject.AsPSObject(process); #if CORECLR // In CoreCLR, the System.Diagnostics.Process.HandleCount property does not exist. // I am adding a note property HandleCount and temporarily setting it to zero. // This issue will be fix for RTM and it is tracked by 5024994: Get-process does not populate the Handles field. PSMemberInfo hasHandleCount = processAsPsobj.Properties["HandleCount"]; if (hasHandleCount == null) { PSNoteProperty noteProperty = new PSNoteProperty("HandleCount", 0); processAsPsobj.Properties.Add(noteProperty, true); processAsPsobj.TypeNames.Insert(0, "System.Diagnostics.Process#HandleCount"); } #endif return(processAsPsobj); }