Team Ai
Datasetpublic

MegaBites-AI/Windows-powershell

sourceHugging Facemitupdated 6mo agoView on Hugging Face
0likes308downloads
MshObject.cs2644 linesDownload Raw Back to engine
1// Copyright (c) Microsoft Corporation.2// Licensed under the MIT License.3 4using System;5using System.Collections;6using System.Collections.Concurrent;7using System.Collections.Generic;8using System.Collections.ObjectModel;9using System.ComponentModel;10using System.Data;11using System.Diagnostics.CodeAnalysis;12using System.Dynamic;13using System.Globalization;14using System.Linq;15using System.Linq.Expressions;16using System.Management.Automation;17using System.Management.Automation.Internal;18using System.Management.Automation.Language;19using System.Management.Automation.Runspaces;20using System.Reflection;21using System.Runtime.CompilerServices;22using System.Runtime.Serialization;23using System.Text;24using System.Xml;25 26using Microsoft.Management.Infrastructure;27#if !UNIX28using System.DirectoryServices;29using System.Management;30#endif31 32#pragma warning disable 1634, 1691 // Stops compiler from warning about unknown warnings33#pragma warning disable 5650034 35namespace System.Management.Automation36{37    /// <summary>38    /// Wraps an object providing alternate views of the available members39    /// and ways to extend them. Members can be methods, properties,40    /// parameterized properties, etc.41    /// </summary>42    /// <remarks>43    /// It is permitted to subclass <see cref="PSObject"/>44    /// but there is no established scenario for doing this, nor has it been tested.45    /// </remarks>46    [TypeDescriptionProvider(typeof(PSObjectTypeDescriptionProvider))]47    public class PSObject : IFormattable, IComparable, ISerializable, IDynamicMetaObjectProvider48    {49        #region constructors50 51        #region private to the constructors52 53        internal TypeTable GetTypeTable()54        {55            if (_typeTable != null && _typeTable.TryGetTarget(out TypeTable typeTable))56            {57                return typeTable;58            }59 60            ExecutionContext context = LocalPipeline.GetExecutionContextFromTLS();61            return context?.TypeTable;62        }63 64        internal static T TypeTableGetMemberDelegate<T>(PSObject msjObj, string name) where T : PSMemberInfo65        {66            TypeTable table = msjObj.GetTypeTable();67            return TypeTableGetMemberDelegate<T>(msjObj, table, name);68        }69 70        private static T TypeTableGetMemberDelegate<T>(PSObject msjObj, TypeTable typeTableToUse, string name) where T : PSMemberInfo71        {72            if (typeTableToUse == null)73            {74                return null;75            }76 77            PSMemberInfoInternalCollection<PSMemberInfo> allMembers = typeTableToUse.GetMembers<PSMemberInfo>(msjObj.InternalTypeNames);78            PSMemberInfo member = allMembers[name];79            if (member == null)80            {81                PSObject.MemberResolution.WriteLine("\"{0}\" NOT present in type table.", name);82                return null;83            }84 85            if (member is T memberAsT)86            {87                PSObject.MemberResolution.WriteLine("\"{0}\" present in type table.", name);88                return memberAsT;89            }90 91            PSObject.MemberResolution.WriteLine("\"{0}\" from types table ignored because it has type {1} instead of {2}.",92                name, member.GetType(), typeof(T));93            return null;94        }95 96        internal static PSMemberInfoInternalCollection<T> TypeTableGetMembersDelegate<T>(PSObject msjObj) where T : PSMemberInfo97        {98            TypeTable table = msjObj.GetTypeTable();99            return TypeTableGetMembersDelegate<T>(msjObj, table);100        }101 102        internal static PSMemberInfoInternalCollection<T> TypeTableGetMembersDelegate<T>(PSObject msjObj, TypeTable typeTableToUse) where T : PSMemberInfo103        {104            if (typeTableToUse == null)105            {106                return new PSMemberInfoInternalCollection<T>();107            }108 109            PSMemberInfoInternalCollection<T> members = typeTableToUse.GetMembers<T>(msjObj.InternalTypeNames);110            PSObject.MemberResolution.WriteLine("Type table members: {0}.", members.Count);111            return members;112        }113 114        internal static T TypeTableGetFirstMemberOrDefaultDelegate<T>(PSObject msjObj, MemberNamePredicate predicate) where T : PSMemberInfo115        {116            TypeTable table = msjObj.GetTypeTable();117            return TypeTableGetFirstOrDefaultMemberDelegate<T>(msjObj, table, predicate);118        }119 120        internal static T TypeTableGetFirstOrDefaultMemberDelegate<T>(PSObject msjObj, TypeTable typeTableToUse, MemberNamePredicate predicate) where T : PSMemberInfo121        {122            return typeTableToUse?.GetFirstMemberOrDefault<T>(msjObj.InternalTypeNames, predicate);123        }124 125        private static T AdapterGetMemberDelegate<T>(PSObject msjObj, string name) where T : PSMemberInfo126        {127            if (msjObj.IsDeserialized)128            {129                if (msjObj.AdaptedMembers == null)130                {131                    return null;132                }133 134                T adaptedMember = msjObj.AdaptedMembers[name] as T;135                PSObject.MemberResolution.WriteLine("Serialized adapted member: {0}.", adaptedMember == null ? "not found" : adaptedMember.Name);136                return adaptedMember;137            }138 139            T retValue = msjObj.InternalAdapter.BaseGetMember<T>(msjObj.ImmediateBaseObject, name);140            PSObject.MemberResolution.WriteLine("Adapted member: {0}.", retValue == null ? "not found" : retValue.Name);141            return retValue;142        }143 144        private static T AdapterGetFirstMemberOrDefaultDelegate<T>(PSObject msjObj, MemberNamePredicate predicate) where T : PSMemberInfo145        {146            if (msjObj.IsDeserialized && typeof(T).IsAssignableFrom(typeof(PSPropertyInfo)))147            {148                if (msjObj.AdaptedMembers == null)149                {150                    return null;151                }152 153                foreach (var adaptedMember in msjObj.AdaptedMembers)154                {155                    if (predicate(adaptedMember.Name))156                    {157                        return adaptedMember as T;158                    }159                }160            }161 162            T retValue = msjObj.InternalAdapter.BaseGetFirstMemberOrDefault<T>(msjObj._immediateBaseObject, predicate);163            return retValue;164        }165 166        internal static PSMemberInfoInternalCollection<TResult> TransformMemberInfoCollection<TSource, TResult>(PSMemberInfoCollection<TSource> source)167            where TSource : PSMemberInfo where TResult : PSMemberInfo168        {169            if (typeof(TSource) == typeof(TResult))170            {171                // If the types are the same, don't make a copy, return the cached collection.172                return source as PSMemberInfoInternalCollection<TResult>;173            }174 175            PSMemberInfoInternalCollection<TResult> returnValue = new PSMemberInfoInternalCollection<TResult>();176            foreach (TSource member in source)177            {178                if (member is TResult result)179                {180                    returnValue.Add(result);181                }182            }183 184            return returnValue;185        }186 187        private static PSMemberInfoInternalCollection<T> AdapterGetMembersDelegate<T>(PSObject msjObj) where T : PSMemberInfo188        {189            if (msjObj.IsDeserialized)190            {191                if (msjObj.AdaptedMembers == null)192                {193                    return new PSMemberInfoInternalCollection<T>();194                }195 196                PSObject.MemberResolution.WriteLine("Serialized adapted members: {0}.", msjObj.AdaptedMembers.Count);197                return TransformMemberInfoCollection<PSPropertyInfo, T>(msjObj.AdaptedMembers);198            }199 200            PSMemberInfoInternalCollection<T> retValue = msjObj.InternalAdapter.BaseGetMembers<T>(msjObj._immediateBaseObject);201            PSObject.MemberResolution.WriteLine("Adapted members: {0}.", retValue.VisibleCount);202            return retValue;203        }204 205        private static PSMemberInfoInternalCollection<T> DotNetGetMembersDelegate<T>(PSObject msjObj) where T : PSMemberInfo206        {207            // Don't lookup dotnet members if the object doesn't insist.208            if (msjObj.InternalBaseDotNetAdapter != null)209            {210                PSMemberInfoInternalCollection<T> retValue = msjObj.InternalBaseDotNetAdapter.BaseGetMembers<T>(msjObj._immediateBaseObject);211                PSObject.MemberResolution.WriteLine("DotNet members: {0}.", retValue.VisibleCount);212                return retValue;213            }214 215            return new PSMemberInfoInternalCollection<T>();216        }217 218        private static T DotNetGetMemberDelegate<T>(PSObject msjObj, string name) where T : PSMemberInfo219        {220            // Don't lookup dotnet member if the object doesn't insist.221            if (msjObj.InternalBaseDotNetAdapter != null)222            {223                T retValue = msjObj.InternalBaseDotNetAdapter.BaseGetMember<T>(msjObj._immediateBaseObject, name);224                PSObject.MemberResolution.WriteLine("DotNet member: {0}.", retValue == null ? "not found" : retValue.Name);225                return retValue;226            }227 228            return null;229        }230 231        private static T DotNetGetFirstMemberOrDefaultDelegate<T>(PSObject msjObj, MemberNamePredicate predicate) where T : PSMemberInfo232        {233            // Don't lookup dotnet member if the object doesn't insist.234            return msjObj.InternalBaseDotNetAdapter?.BaseGetFirstMemberOrDefault<T>(msjObj._immediateBaseObject, predicate);235        }236 237        /// <summary>238        /// A collection of delegates to get Extended/Adapted/Dotnet members based on the239        /// <paramref name="viewType"/>240        /// </summary>241        /// <param name="viewType">242        /// A filter to select Extended/Adapted/Dotnet view of the object243        /// </param>244        /// <returns></returns>245        internal static Collection<CollectionEntry<PSMemberInfo>> GetMemberCollection(PSMemberViewTypes viewType)246        {247            return GetMemberCollection(viewType, null);248        }249 250        /// <summary>251        /// A collection of delegates to get Extended/Adapted/Dotnet members based on the252        /// <paramref name="viewType"/>253        /// </summary>254        /// <param name="viewType">255        /// A filter to select Extended/Adapted/Dotnet view of the object256        /// </param>257        /// <param name="backupTypeTable">258        /// Backup type table to use if there is no execution context associated with the current thread259        /// </param>260        /// <returns></returns>261        internal static Collection<CollectionEntry<PSMemberInfo>> GetMemberCollection(262            PSMemberViewTypes viewType,263            TypeTable backupTypeTable)264        {265            Collection<CollectionEntry<PSMemberInfo>> returnValue = new Collection<CollectionEntry<PSMemberInfo>>();266            if ((viewType & PSMemberViewTypes.Extended) == PSMemberViewTypes.Extended)267            {268                if (backupTypeTable == null)269                {270                    returnValue.Add(new CollectionEntry<PSMemberInfo>(271                        PSObject.TypeTableGetMembersDelegate<PSMemberInfo>,272                        PSObject.TypeTableGetMemberDelegate<PSMemberInfo>,273                        PSObject.TypeTableGetFirstMemberOrDefaultDelegate<PSMemberInfo>,274                        true, true, "type table members"));275                }276                else277                {278                    returnValue.Add(new CollectionEntry<PSMemberInfo>(279                        msjObj => TypeTableGetMembersDelegate<PSMemberInfo>(msjObj, backupTypeTable),280                        (msjObj, name) => TypeTableGetMemberDelegate<PSMemberInfo>(msjObj, backupTypeTable, name),281                        (msjObj, predicate) => TypeTableGetFirstOrDefaultMemberDelegate<PSMemberInfo>(msjObj, backupTypeTable, predicate),282                        true, true, "type table members"));283                }284            }285 286            if ((viewType & PSMemberViewTypes.Adapted) == PSMemberViewTypes.Adapted)287            {288                returnValue.Add(new CollectionEntry<PSMemberInfo>(289                    PSObject.AdapterGetMembersDelegate<PSMemberInfo>,290                    PSObject.AdapterGetMemberDelegate<PSMemberInfo>,291                    PSObject.AdapterGetFirstMemberOrDefaultDelegate<PSMemberInfo>,292                    shouldReplicateWhenReturning: false,293                    shouldCloneWhenReturning: false,294                    collectionNameForTracing: "adapted members"));295            }296 297            if ((viewType & PSMemberViewTypes.Base) == PSMemberViewTypes.Base)298            {299                returnValue.Add(new CollectionEntry<PSMemberInfo>(300                    PSObject.DotNetGetMembersDelegate<PSMemberInfo>,301                    PSObject.DotNetGetMemberDelegate<PSMemberInfo>,302                    PSObject.DotNetGetFirstMemberOrDefaultDelegate<PSMemberInfo>,303                    shouldReplicateWhenReturning: false,304                    shouldCloneWhenReturning: false,305                    collectionNameForTracing: "clr members"));306            }307 308            return returnValue;309        }310 311        private static Collection<CollectionEntry<PSMethodInfo>> GetMethodCollection()312        {313            Collection<CollectionEntry<PSMethodInfo>> returnValue = new Collection<CollectionEntry<PSMethodInfo>>314            {315                new CollectionEntry<PSMethodInfo>(316                    PSObject.TypeTableGetMembersDelegate<PSMethodInfo>,317                    PSObject.TypeTableGetMemberDelegate<PSMethodInfo>,318                    PSObject.TypeTableGetFirstMemberOrDefaultDelegate<PSMethodInfo>,319                    shouldReplicateWhenReturning: true,320                    shouldCloneWhenReturning: true,321                    collectionNameForTracing: "type table members"),322                new CollectionEntry<PSMethodInfo>(323                    PSObject.AdapterGetMembersDelegate<PSMethodInfo>,324                    PSObject.AdapterGetMemberDelegate<PSMethodInfo>,325                    PSObject.AdapterGetFirstMemberOrDefaultDelegate<PSMethodInfo>,326                    shouldReplicateWhenReturning: false,327                    shouldCloneWhenReturning: false,328                    collectionNameForTracing: "adapted members"),329                new CollectionEntry<PSMethodInfo>(330                    PSObject.DotNetGetMembersDelegate<PSMethodInfo>,331                    PSObject.DotNetGetMemberDelegate<PSMethodInfo>,332                    PSObject.DotNetGetFirstMemberOrDefaultDelegate<PSMethodInfo>,333                    shouldReplicateWhenReturning: false,334                    shouldCloneWhenReturning: false,335                    collectionNameForTracing: "clr members")336            };337            return returnValue;338        }339 340        /// <summary>341        /// A collection of delegates to get Extended/Adapted/Dotnet properties based on the342        /// <paramref name="viewType"/>343        /// </summary>344        /// <param name="viewType">345        /// A filter to select Extended/Adapted/Dotnet view of the object346        /// </param>347        /// <returns></returns>348        internal static Collection<CollectionEntry<PSPropertyInfo>> GetPropertyCollection(349            PSMemberViewTypes viewType)350        {351            return GetPropertyCollection(viewType, null);352        }353 354        /// <summary>355        /// A collection of delegates to get Extended/Adapted/Dotnet properties based on the356        /// <paramref name="viewType"/>357        /// </summary>358        /// <param name="viewType">359        /// A filter to select Extended/Adapted/Dotnet view of the object360        /// </param>361        /// <param name="backupTypeTable">362        /// Backup type table to use if there is no execution context associated with the current thread363        /// </param>364        /// <returns></returns>365        internal static Collection<CollectionEntry<PSPropertyInfo>> GetPropertyCollection(366            PSMemberViewTypes viewType,367            TypeTable backupTypeTable)368        {369            Collection<CollectionEntry<PSPropertyInfo>> returnValue = new Collection<CollectionEntry<PSPropertyInfo>>();370            if ((viewType & PSMemberViewTypes.Extended) == PSMemberViewTypes.Extended)371            {372                if (backupTypeTable == null)373                {374                    returnValue.Add(new CollectionEntry<PSPropertyInfo>(375                        PSObject.TypeTableGetMembersDelegate<PSPropertyInfo>,376                        PSObject.TypeTableGetMemberDelegate<PSPropertyInfo>,377                        PSObject.TypeTableGetFirstMemberOrDefaultDelegate<PSPropertyInfo>,378                        true, true, "type table members"));379                }380                else381                {382                    returnValue.Add(new CollectionEntry<PSPropertyInfo>(383                        msjObj => TypeTableGetMembersDelegate<PSPropertyInfo>(msjObj, backupTypeTable),384                        (msjObj, name) => TypeTableGetMemberDelegate<PSPropertyInfo>(msjObj, backupTypeTable, name),385                        PSObject.TypeTableGetFirstMemberOrDefaultDelegate<PSPropertyInfo>,386                        true, true, "type table members"));387                }388            }389 390            if ((viewType & PSMemberViewTypes.Adapted) == PSMemberViewTypes.Adapted)391            {392                returnValue.Add(new CollectionEntry<PSPropertyInfo>(393                    PSObject.AdapterGetMembersDelegate<PSPropertyInfo>,394                    PSObject.AdapterGetMemberDelegate<PSPropertyInfo>,395                    PSObject.AdapterGetFirstMemberOrDefaultDelegate<PSPropertyInfo>,396                    false, false, "adapted members"));397            }398 399            if ((viewType & PSMemberViewTypes.Base) == PSMemberViewTypes.Base)400            {401                returnValue.Add(new CollectionEntry<PSPropertyInfo>(402                    PSObject.DotNetGetMembersDelegate<PSPropertyInfo>,403                    PSObject.DotNetGetMemberDelegate<PSPropertyInfo>,404                    PSObject.DotNetGetFirstMemberOrDefaultDelegate<PSPropertyInfo>,405                    false, false, "clr members"));406            }407 408            return returnValue;409        }410 411        private void CommonInitialization(object obj)412        {413            Diagnostics.Assert(obj != null, "checked by callers");414            if (obj is PSCustomObject)415            {416                this.ImmediateBaseObjectIsEmpty = true;417            }418 419            _immediateBaseObject = obj;420            var context = LocalPipeline.GetExecutionContextFromTLS();421            _typeTable = context?.TypeTableWeakReference;422        }423 424        #region Adapter Mappings425 426        private static readonly ConcurrentDictionary<Type, AdapterSet> s_adapterMapping = new ConcurrentDictionary<Type, AdapterSet>();427 428        private static readonly List<Func<object, AdapterSet>> s_adapterSetMappers = new List<Func<object, AdapterSet>>429                                                                                    {430                                                                                        MappedInternalAdapterSet431                                                                                    };432 433        private static AdapterSet MappedInternalAdapterSet(object obj)434        {435            if (obj is PSMemberSet) { return PSObject.s_mshMemberSetAdapter; }436 437            if (obj is PSObject) { return PSObject.s_mshObjectAdapter; }438 439            if (obj is CimInstance) { return PSObject.s_cimInstanceAdapter; }440#if !UNIX441            if (obj is ManagementClass) { return PSObject.s_managementClassAdapter; }442 443            if (obj is ManagementBaseObject) { return PSObject.s_managementObjectAdapter; }444 445            if (obj is DirectoryEntry) { return PSObject.s_directoryEntryAdapter; }446#endif447            if (obj is DataRowView) { return PSObject.s_dataRowViewAdapter; }448 449            if (obj is DataRow) { return PSObject.s_dataRowAdapter; }450 451            if (obj is XmlNode) { return PSObject.s_xmlNodeAdapter; }452 453            return null;454        }455 456        /// <summary>457        /// Returns the adapter corresponding to obj.GetType()458        /// </summary>459        /// <returns>The adapter set corresponding to obj.GetType().</returns>460        internal static AdapterSet GetMappedAdapter(object obj, TypeTable typeTable)461        {462            Type objectType = obj.GetType();463 464            PSObject.AdapterSet adapter = typeTable?.GetTypeAdapter(objectType);465 466            if (adapter != null)467            {468                // We don't cache results found via the type table because type tables may differ b/w runspaces,469                // our cache is app domain wide, and the key is simply the type.470                return adapter;471            }472 473            if (s_adapterMapping.TryGetValue(objectType, out AdapterSet result))474            {475                return result;476            }477 478            lock (s_adapterSetMappers)479            {480                foreach (var mapper in s_adapterSetMappers)481                {482                    result = mapper(obj);483                    if (result != null)484                    {485                        break;486                    }487                }488            }489 490            if (result == null)491            {492#if !UNIX493                if (objectType.IsCOMObject)494                {495                    // All WinRT types are COM types.496                    // All WinRT types would contain the TypeAttributes flag being set to WindowsRunTime.497                    if (WinRTHelper.IsWinRTType(objectType))498                    {499                        result = PSObject.s_dotNetInstanceAdapterSet;500                    }501 502                    // We are not using IsAssignableFrom because we want to avoid503                    // using the COM adapters for Primary Interop Assembly types504                    // and they derive from System.__ComObject.505                    // We are not using Type.Equals because System.__ComObject is506                    // not public.507                    else if (objectType.FullName.Equals("System.__ComObject"))508                    {509                        // We don't cache the adapter set for COM objects because the adapter varies depending on the COM object, but often510                        // (typically), the runtime type is always the same.  That's why this if statement is here and returns.511 512                        ComTypeInfo info = ComTypeInfo.GetDispatchTypeInfo(obj);513                        return info != null514                                   ? new AdapterSet(new ComAdapter(info), DotNetInstanceAdapter)515                                   : PSObject.s_dotNetInstanceAdapterSet;516                    }517                    else518                    {519                        ComTypeInfo info = ComTypeInfo.GetDispatchTypeInfo(obj);520                        result = info != null521                                   ? new AdapterSet(new DotNetAdapterWithComTypeName(info), null)522                                   : PSObject.s_dotNetInstanceAdapterSet;523                    }524                }525                else526                {527                    result = PSObject.s_dotNetInstanceAdapterSet;528                }529#else530                result = PSObject.s_dotNetInstanceAdapterSet;531#endif532            }533 534            var existingOrNew = s_adapterMapping.GetOrAdd(objectType, result);535            Diagnostics.Assert(existingOrNew == result, "There is a logic error in caching adapter sets.");536 537            return result;538        }539 540        #endregion541 542        internal static AdapterSet CreateThirdPartyAdapterSet(Type adaptedType, PSPropertyAdapter adapter)543        {544            return new AdapterSet(new ThirdPartyAdapter(adaptedType, adapter), s_baseAdapterForAdaptedObjects);545        }546 547        #endregion private to the constructors548 549        /// <summary>550        /// Initializes a new instance of PSObject with an PSCustomObject BaseObject.551        /// </summary>552        public PSObject()553        {554            CommonInitialization(PSCustomObject.SelfInstance);555        }556 557        /// <summary>558        /// Initializes a new instance of PSObject with an PSCustomObject BaseObject559        /// with an initial capacity for members.560        /// </summary>561        /// <param name="instanceMemberCapacity">The initial capacity for the instance member collection.</param>562        public PSObject(int instanceMemberCapacity) : this()563        {564            _instanceMembers = new PSMemberInfoInternalCollection<PSMemberInfo>(instanceMemberCapacity);565        }566 567        /// <summary>568        /// Initializes a new instance of PSObject wrapping obj (accessible through BaseObject).569        /// </summary>570        /// <param name="obj">Object we are wrapping.</param>571        /// <exception cref="ArgumentNullException">If <paramref name="obj"/> is null.</exception>572        [SuppressMessage("Microsoft.Naming", "CA1720:IdentifiersShouldNotContainTypeNames", MessageId = "obj", Justification = "This is shipped as part of V1. Retaining this for backward compatibility.")]573        public PSObject(object obj)574        {575            if (obj == null)576            {577                throw PSTraceSource.NewArgumentNullException(nameof(obj));578            }579 580            CommonInitialization(obj);581        }582 583        /// <summary>584        /// Creates a PSObject from an ISerializable context.585        /// </summary>586        /// <param name="info">Serialization information for this instance.</param>587        /// <param name="context">The streaming context for this instance.</param>588        protected PSObject(SerializationInfo info, StreamingContext context)589        {590            if (info == null)591            {592                throw PSTraceSource.NewArgumentNullException(nameof(info));593            }594 595            if (info.GetValue("CliXml", typeof(string)) is not string serializedData)596            {597                throw PSTraceSource.NewArgumentNullException(nameof(info));598            }599 600            PSObject result = PSObject.AsPSObject(PSSerializer.Deserialize(serializedData));601            CommonInitialization(result.ImmediateBaseObject);602 603            CopyDeserializerFields(source: result, target: this);604        }605 606        internal static PSObject ConstructPSObjectFromSerializationInfo(SerializationInfo info, StreamingContext context)607        {608            return new PSObject(info, context);609        }610 611        #endregion constructors612 613        #region fields614 615        #region instance fields616 617        private readonly object _lockObject = new object();618 619        private ConsolidatedString _typeNames;620 621        /// <summary>622        /// This is the main field in the class representing623        /// the System.Object we are encapsulating.624        /// </summary>625        private object _immediateBaseObject;626 627        private WeakReference<TypeTable> _typeTable;628        private AdapterSet _adapterSet;629        private PSMemberInfoInternalCollection<PSMemberInfo> _instanceMembers;630        private PSMemberInfoIntegratingCollection<PSMemberInfo> _members;631        private PSMemberInfoIntegratingCollection<PSPropertyInfo> _properties;632        private PSMemberInfoIntegratingCollection<PSMethodInfo> _methods;633 634        private PSObjectFlags _flags;635 636        #endregion instance fields637 638        private static readonly PSTraceSource s_memberResolution = PSTraceSource.GetTracer("MemberResolution", "Traces the resolution from member name to the member. A member can be a property, method, etc.", false);639 640        private static readonly ConditionalWeakTable<object, ConsolidatedString> s_typeNamesResurrectionTable = new ConditionalWeakTable<object, ConsolidatedString>();641 642        private static readonly Collection<CollectionEntry<PSMemberInfo>> s_memberCollection = GetMemberCollection(PSMemberViewTypes.All);643        private static readonly Collection<CollectionEntry<PSMethodInfo>> s_methodCollection = GetMethodCollection();644        private static readonly Collection<CollectionEntry<PSPropertyInfo>> s_propertyCollection = GetPropertyCollection(PSMemberViewTypes.All);645 646        private static readonly DotNetAdapter s_dotNetInstanceAdapter = new DotNetAdapter();647        private static readonly DotNetAdapter s_baseAdapterForAdaptedObjects = new BaseDotNetAdapterForAdaptedObjects();648        private static readonly DotNetAdapter s_dotNetStaticAdapter = new DotNetAdapter(true);649 650        private static readonly AdapterSet s_dotNetInstanceAdapterSet = new AdapterSet(DotNetInstanceAdapter, null);651        private static readonly AdapterSet s_mshMemberSetAdapter = new AdapterSet(new PSMemberSetAdapter(), null);652        private static readonly AdapterSet s_mshObjectAdapter = new AdapterSet(new PSObjectAdapter(), null);653 654        private static readonly PSObject.AdapterSet s_cimInstanceAdapter =655            new PSObject.AdapterSet(new ThirdPartyAdapter(typeof(Microsoft.Management.Infrastructure.CimInstance),656                                                          new Microsoft.PowerShell.Cim.CimInstanceAdapter()),657                                    PSObject.DotNetInstanceAdapter);658 659#if !UNIX660        private static readonly AdapterSet s_managementObjectAdapter = new AdapterSet(new ManagementObjectAdapter(), DotNetInstanceAdapter);661        private static readonly AdapterSet s_managementClassAdapter = new AdapterSet(new ManagementClassApdapter(), DotNetInstanceAdapter);662        private static readonly AdapterSet s_directoryEntryAdapter = new AdapterSet(new DirectoryEntryAdapter(), DotNetInstanceAdapter);663#endif664        private static readonly AdapterSet s_dataRowViewAdapter = new AdapterSet(new DataRowViewAdapter(), s_baseAdapterForAdaptedObjects);665        private static readonly AdapterSet s_dataRowAdapter = new AdapterSet(new DataRowAdapter(), s_baseAdapterForAdaptedObjects);666        private static readonly AdapterSet s_xmlNodeAdapter = new AdapterSet(new XmlNodeAdapter(), s_baseAdapterForAdaptedObjects);667 668        #endregion fields669 670        #region properties671 672        internal PSMemberInfoInternalCollection<PSMemberInfo> InstanceMembers673        {674            get675            {676                if (_instanceMembers == null)677                {678                    lock (_lockObject)679                    {680                        _instanceMembers ??=681                            s_instanceMembersResurrectionTable.GetValue(682                                GetKeyForResurrectionTables(this),683                                _ => new PSMemberInfoInternalCollection<PSMemberInfo>());684                    }685                }686 687                return _instanceMembers;688            }689 690            set => _instanceMembers = value;691        }692 693        /// <summary>694        /// This is the adapter that will depend on the type of baseObject.695        /// </summary>696        internal Adapter InternalAdapter => InternalAdapterSet.OriginalAdapter;697 698        /// <summary>699        /// This is the adapter that is used to resolve the base dotnet members for an700        /// adapted object. If an object is not adapted, this will be null.701        /// </summary>702        /// <remarks>703        /// If an object is not adapted, InternalAdapter will use the dotnet adapter.704        /// So there is no point falling back to the same dotnet adapter.705        ///706        /// If an object is adapted, this adapter will be used to resolve the dotnet707        /// members.708        /// </remarks>709        internal Adapter InternalBaseDotNetAdapter => InternalAdapterSet.DotNetAdapter;710 711        /// <summary>712        /// This is the adapter set that will contain the adapter of the baseObject713        /// and the ultimate .net member lookup adapter.714        /// See <see cref="PSObject.AdapterSet"/> for explanation.715        /// </summary>716        private AdapterSet InternalAdapterSet717        {718            get719            {720                if (_adapterSet == null)721                {722                    lock (_lockObject)723                    {724                        _adapterSet ??= GetMappedAdapter(_immediateBaseObject, GetTypeTable());725                    }726                }727 728                return _adapterSet;729            }730        }731 732        /// <summary>733        /// Gets the member collection.734        /// </summary>735        public PSMemberInfoCollection<PSMemberInfo> Members736        {737            get738            {739                if (_members == null)740                {741                    lock (_lockObject)742                    {743                        _members ??= new PSMemberInfoIntegratingCollection<PSMemberInfo>(this, s_memberCollection);744                    }745                }746 747                return _members;748            }749        }750 751        /// <summary>752        /// Gets the Property collection, or the members that are actually properties.753        /// </summary>754        public PSMemberInfoCollection<PSPropertyInfo> Properties755        {756            get757            {758                if (_properties == null)759                {760                    lock (_lockObject)761                    {762                        _properties ??= new PSMemberInfoIntegratingCollection<PSPropertyInfo>(this, s_propertyCollection);763                    }764                }765 766                return _properties;767            }768        }769 770        /// <summary>771        /// Gets the Method collection, or the members that are actually methods.772        /// </summary>773        public PSMemberInfoCollection<PSMethodInfo> Methods774        {775            get776            {777                if (_methods == null)778                {779                    lock (_lockObject)780                    {781                        _methods ??= new PSMemberInfoIntegratingCollection<PSMethodInfo>(this, s_methodCollection);782                    }783                }784 785                return _methods;786            }787        }788 789        /// <summary>790        /// Gets the object we are directly wrapping.791        /// </summary>792        /// <remarks>If the ImmediateBaseObject is another PSObject,793        /// that PSObject will be returned.</remarks>794        public object ImmediateBaseObject => _immediateBaseObject;795 796        /// <summary>797        /// Gets the object we are wrapping.798        /// </summary>799        /// <remarks>If the ImmediateBaseObject is another PSObject, this property800        /// will return its BaseObject.</remarks>801        public object BaseObject802        {803            get804            {805                object returnValue;806                PSObject mshObj = this;807                do808                {809                    returnValue = mshObj._immediateBaseObject;810                    mshObj = returnValue as PSObject;811                } while (mshObj != null);812 813                return returnValue;814            }815        }816 817        /// <summary>818        /// Gets the type names collection initially containing the object type hierarchy.819        /// </summary>820        public Collection<string> TypeNames821        {822            get823            {824                var result = InternalTypeNames;825                if (result.IsReadOnly)826                {827                    lock (_lockObject)828                    {829                        // Check again after acquiring the lock to ensure some other thread didn't make the copy.830                        if (result.IsReadOnly)831                        {832                            _typeNames = s_typeNamesResurrectionTable.GetValue(833                                            GetKeyForResurrectionTables(this),834                                            _ => new ConsolidatedString(_typeNames));835 836                            object baseObj = BaseObject;837                            // In most cases, the TypeNames will be modified after it's returned838                            if (baseObj != null) { PSVariableAssignmentBinder.NoteTypeHasInstanceMemberOrTypeName(baseObj.GetType()); }839 840                            return _typeNames;841                        }842                    }843                }844 845                return result;846            }847        }848 849        internal ConsolidatedString InternalTypeNames850        {851            get852            {853                if (_typeNames == null)854                {855                    lock (_lockObject)856                    {857                        if (_typeNames == null)858                        {859                            if (!s_typeNamesResurrectionTable.TryGetValue(GetKeyForResurrectionTables(this), out _typeNames))860                            {861                                // We don't cache this typename in the resurrection table because it's cached in the psobject,862                                // and the assumption is we'll usually get the value directly from the PSObject, so it's not863                                // needed in the resurrection table.864                                //865                                // If we hand out the typename to a client that could change it (through the public property866                                // TypeNames), then we'll need to store the copy in the resurrection table.867                                _typeNames = InternalAdapter.BaseGetTypeNameHierarchy(_immediateBaseObject);868                            }869                        }870                    }871                }872 873                return _typeNames;874            }875 876            set => _typeNames = value;877        }878 879        internal static ConsolidatedString GetTypeNames(object obj)880        {881            if (obj is PSObject psobj)882            {883                return psobj.InternalTypeNames;884            }885 886            if (HasInstanceTypeName(obj, out ConsolidatedString result))887            {888                return result;889            }890 891            return PSObject.GetMappedAdapter(obj, null).OriginalAdapter.BaseGetTypeNameHierarchy(obj);892        }893 894        internal static bool HasInstanceTypeName(object obj, out ConsolidatedString result)895        {896            return s_typeNamesResurrectionTable.TryGetValue(GetKeyForResurrectionTables(obj), out result);897        }898 899        #endregion properties900 901        #region static methods902        internal static bool HasInstanceMembers(object obj, out PSMemberInfoInternalCollection<PSMemberInfo> instanceMembers)903        {904            if (obj is PSObject psobj)905            {906                lock (psobj)907                {908                    if (psobj._instanceMembers == null)909                    {910                        s_instanceMembersResurrectionTable.TryGetValue(GetKeyForResurrectionTables(psobj), out psobj._instanceMembers);911                    }912                }913 914                instanceMembers = psobj._instanceMembers;915            }916            else if (obj != null)917            {918                s_instanceMembersResurrectionTable.TryGetValue(GetKeyForResurrectionTables(obj), out instanceMembers);919            }920            else921            {922                instanceMembers = null;923            }924 925            return instanceMembers != null && instanceMembers.Count > 0;926        }927 928        private static readonly ConditionalWeakTable<object, PSMemberInfoInternalCollection<PSMemberInfo>> s_instanceMembersResurrectionTable =929            new ConditionalWeakTable<object, PSMemberInfoInternalCollection<PSMemberInfo>>();930 931        /// <summary>932        /// </summary>933        /// <param name="valueToConvert"></param>934        /// <returns></returns>935        public static implicit operator PSObject(int valueToConvert)936        {937            return PSObject.AsPSObject(valueToConvert);938        }939 940        /// <summary>941        /// </summary>942        /// <param name="valueToConvert"></param>943        /// <returns></returns>944        public static implicit operator PSObject(string valueToConvert)945        {946            return PSObject.AsPSObject(valueToConvert);947        }948 949        /// <summary>950        /// </summary>951        /// <param name="valueToConvert"></param>952        /// <returns></returns>953        public static implicit operator PSObject(Hashtable valueToConvert)954        {955            return PSObject.AsPSObject(valueToConvert);956        }957 958        /// <summary>959        /// </summary>960        /// <param name="valueToConvert"></param>961        /// <returns></returns>962        public static implicit operator PSObject(double valueToConvert)963        {964            return PSObject.AsPSObject(valueToConvert);965        }966 967        /// <summary>968        /// </summary>969        /// <param name="valueToConvert"></param>970        /// <returns></returns>971        public static implicit operator PSObject(bool valueToConvert)972        {973            return PSObject.AsPSObject(valueToConvert);974        }975 976        /// <summary>977        /// If obj is not an PSObject, it is returned. Otherwise, retrieves978        /// the first non PSObject or PSObject with CustomBaseObject979        /// in the PSObject - BaseObject chain.980        /// </summary>981        internal static object Base(object obj)982        {983            if (obj is not PSObject mshObj)984            {985                return obj;986            }987 988            if (mshObj == AutomationNull.Value)989                return null;990            if (mshObj.ImmediateBaseObjectIsEmpty)991            {992                return obj;993            }994 995            object returnValue;996            do997            {998                returnValue = mshObj._immediateBaseObject;999                mshObj = returnValue as PSObject;1000            } while ((mshObj != null) && (!mshObj.ImmediateBaseObjectIsEmpty));1001 1002            return returnValue;1003        }1004 1005        internal static PSMemberInfo GetStaticCLRMember(object obj, string methodName)1006        {1007            obj = PSObject.Base(obj);1008            if (obj == null || methodName == null || methodName.Length == 0)1009            {1010                return null;1011            }1012 1013            var objType = obj as Type ?? obj.GetType();1014            return DotNetStaticAdapter.BaseGetMember<PSMemberInfo>(objType, methodName);1015        }1016 1017        /// <summary>1018        /// If obj is an PSObject it will be returned as is, otherwise1019        /// a new PSObject will be created based on obj.1020        /// </summary>1021        /// <param name="obj">Object to be wrapped.</param>1022        /// <returns>1023        /// obj or a new PSObject whose BaseObject is obj1024        /// </returns>1025        /// <exception cref="ArgumentNullException">If <paramref name="obj"/> is null.</exception>1026        [SuppressMessage("Microsoft.Naming", "CA1720:IdentifiersShouldNotContainTypeNames", MessageId = "obj", Justification = "This is shipped as part of V1. Retaining this for backward compatibility.")]1027        public static PSObject AsPSObject(object obj)1028        {1029            return AsPSObject(obj, false);1030        }1031 1032        /// <summary>1033        /// If obj is a PSObject, it will be returned as is, otherwise a new1034        /// PSObject will be created on obj. Its InstanceMembers and TypeNames1035        /// will be initialized if we are not going to use the ResurrectionTables1036        /// for this PSObject instance.1037        /// </summary>1038        /// <param name="obj"></param>1039        /// <param name="storeTypeNameAndInstanceMembersLocally"></param>1040        /// <returns></returns>1041        [SuppressMessage("Microsoft.Naming", "CA1720:IdentifiersShouldNotContainTypeNames", MessageId = "obj", Justification = "AsPSObject is shipped as part of V1. This is a new overload method.")]1042        internal static PSObject AsPSObject(object obj, bool storeTypeNameAndInstanceMembersLocally)1043        {1044            if (obj == null)1045            {1046                throw PSTraceSource.NewArgumentNullException(nameof(obj));1047            }1048 1049            if (obj is PSObject so)1050            {1051                return so;1052            }1053 1054            return new PSObject(obj) { StoreTypeNameAndInstanceMembersLocally = storeTypeNameAndInstanceMembersLocally };1055        }1056 1057        /// <summary>1058        /// Returns an object that should be used as a key for getting 1) instance members and 2) type names1059        /// - If base object is a PSCustomObject or a string or a type1060        ///   then the most nested wrapping PSObject is returned (the PSObject where immediateBaseObject=PSCustomObject/string/type)1061        /// - Otherwise the base object is returned1062        /// This is a temporary fix for Win8 : 254345 - Job Failed By Throwing ExtendedTypeSystemException.1063        /// </summary>1064        /// <returns></returns>1065        internal static object GetKeyForResurrectionTables(object obj)1066        {1067            if (obj is not PSObject pso)1068            {1069                return obj;1070            }1071 1072            PSObject psObjectAboveBase = pso;1073            while (psObjectAboveBase.ImmediateBaseObject is PSObject)1074            {1075                psObjectAboveBase = (PSObject)psObjectAboveBase.ImmediateBaseObject;1076            }1077 1078            if (psObjectAboveBase.ImmediateBaseObject is PSCustomObject1079                || psObjectAboveBase.ImmediateBaseObject is string1080                || pso.StoreTypeNameAndInstanceMembersLocally)1081            {1082                return psObjectAboveBase;1083            }1084 1085            return psObjectAboveBase.ImmediateBaseObject;1086        }1087 1088        #endregion static methods1089 1090        #region instance methods1091        #region ToString1092 1093        private static string GetSeparator(ExecutionContext context, string separator)1094        {1095            if (separator != null)1096            {1097                return separator;1098            }1099 1100            object obj = context?.GetVariableValue(SpecialVariables.OFSVarPath);1101            if (obj != null)1102            {1103                return obj.ToString();1104            }1105 1106            return " ";1107        }1108 1109        internal static string ToStringEnumerator(ExecutionContext context, IEnumerator enumerator, string separator, string format, IFormatProvider formatProvider)1110        {1111            StringBuilder returnValue = new StringBuilder();1112            string separatorToUse = GetSeparator(context, separator);1113            while (enumerator.MoveNext())1114            {1115                object obj = enumerator.Current;1116                returnValue.Append(PSObject.ToString(context, obj, separator, format, formatProvider, false, false));1117                returnValue.Append(separatorToUse);1118            }1119 1120            if (returnValue.Length == 0)1121            {1122                return string.Empty;1123            }1124 1125            int separatorLength = separatorToUse.Length;1126            returnValue.Remove(returnValue.Length - separatorLength, separatorLength);1127            return returnValue.ToString();1128        }1129 1130        internal static string ToStringEnumerable(ExecutionContext context, IEnumerable enumerable, string separator, string format, IFormatProvider formatProvider)1131        {1132            StringBuilder returnValue = new StringBuilder();1133            string separatorToUse = GetSeparator(context, separator);1134            foreach (object obj in enumerable)1135            {1136                if (obj != null)1137                {1138                    PSObject mshObj = PSObject.AsPSObject(obj);1139                    returnValue.Append(PSObject.ToString(context, mshObj, separator, format, formatProvider, false, false));1140                }1141 1142                returnValue.Append(separatorToUse);1143            }1144 1145            if (returnValue.Length == 0)1146            {1147                return string.Empty;1148            }1149 1150            int separatorLength = separatorToUse.Length;1151            returnValue.Remove(returnValue.Length - separatorLength, separatorLength);1152            return returnValue.ToString();1153        }1154 1155        private static string ToStringEmptyBaseObject(ExecutionContext context, PSObject mshObj, string separator, string format, IFormatProvider formatProvider)1156        {1157            StringBuilder returnValue = new StringBuilder("@{");1158            bool isFirst = true;1159            foreach (PSPropertyInfo property in mshObj.Properties)1160            {1161                if (!isFirst)1162                {1163                    returnValue.Append("; ");1164                }1165 1166                isFirst = false;1167                returnValue.Append(property.Name);1168                returnValue.Append('=');1169 1170                // Don't evaluate script properties during a ToString() operation.1171                var propertyValue = property is PSScriptProperty ? property.GetType().FullName : property.Value;1172 1173                returnValue.Append(PSObject.ToString(context, propertyValue, separator, format, formatProvider, false, false));1174            }1175 1176            if (isFirst)1177            {1178                return string.Empty;1179            }1180 1181            returnValue.Append('}');1182            return returnValue.ToString();1183        }1184 1185        /// <summary>1186        /// Returns the string representation of obj.1187        /// </summary>1188        /// <param name="context">ExecutionContext used to fetch the separator.</param>1189        /// <param name="obj">1190        /// object we are trying to call ToString on. If this is not an PSObject we try1191        /// enumerating and if that fails we call obj.ToString.1192        /// If this is an PSObject, we look for a brokered ToString.1193        /// If it is not present, and the BaseObject is null we try listing the properties.1194        /// If the BaseObject is not null we try enumerating. If that fails we try the BaseObject's ToString.1195        /// </param>1196        /// <returns>A string representation of the object.</returns>1197        /// <exception cref="ExtendedTypeSystemException">1198        /// When there is a brokered ToString but it failed, or when the ToString on obj throws an exception.1199        /// </exception>1200        internal static string ToStringParser(ExecutionContext context, object obj)

Showing the first 1,200 of 2644 lines. Download the file for the rest.