Team Ai
Datasetpublic

MegaBites-AI/Windows-powershell

sourceHugging Facemitupdated 6mo agoView on Hugging Face
0likes372downloads
ComTypeLibDesc.cs183 linesDownload Raw Back to ComInterop
1// Licensed to the .NET Foundation under one or more agreements.2// The .NET Foundation licenses this file to you under the MIT license.3 4using System;5using System.Collections.Generic;6using System.Dynamic;7using System.Globalization;8using System.Linq.Expressions;9using System.Runtime.InteropServices;10using ComTypes = System.Runtime.InteropServices.ComTypes;11 12namespace System.Management.Automation.ComInterop13{14    /// <summary>15    /// Cached information from a TLB. Only information that is required is saved. CoClasses are used16    /// for event hookup. Enums are stored for accessing symbolic names from scripts.17    /// </summary>18    internal sealed class ComTypeLibDesc : IDynamicMetaObjectProvider19    {20        // typically typelibs contain very small number of coclasses21        // so we will just use the linked list as it performs better22        // on small number of entities23        private readonly LinkedList<ComTypeClassDesc> _classes;24        private readonly Dictionary<string, ComTypeEnumDesc> _enums;25        private ComTypes.TYPELIBATTR _typeLibAttributes;26 27        private static readonly Dictionary<Guid, ComTypeLibDesc> s_cachedTypeLibDesc = new Dictionary<Guid, ComTypeLibDesc>();28 29        private ComTypeLibDesc()30        {31            _enums = new Dictionary<string, ComTypeEnumDesc>();32            _classes = new LinkedList<ComTypeClassDesc>();33        }34 35        public override string ToString() => $"<type library {Name}>";36 37        public string Documentation38        {39            get { return string.Empty; }40        }41 42        #region IDynamicMetaObjectProvider Members43 44        DynamicMetaObject IDynamicMetaObjectProvider.GetMetaObject(Expression parameter)45        {46            return new TypeLibMetaObject(parameter, this);47        }48 49        #endregion50 51        internal static ComTypeLibDesc GetFromTypeLib(ComTypes.ITypeLib typeLib)52        {53            // check whether we have already loaded this type library54            ComTypes.TYPELIBATTR typeLibAttr = ComRuntimeHelpers.GetTypeAttrForTypeLib(typeLib);55            ComTypeLibDesc typeLibDesc;56            lock (s_cachedTypeLibDesc)57            {58                if (s_cachedTypeLibDesc.TryGetValue(typeLibAttr.guid, out typeLibDesc))59                {60                    return typeLibDesc;61                }62            }63 64            typeLibDesc = new ComTypeLibDesc65            {66                Name = ComRuntimeHelpers.GetNameOfLib(typeLib),67                _typeLibAttributes = typeLibAttr68            };69 70            int countTypes = typeLib.GetTypeInfoCount();71            for (int i = 0; i < countTypes; i++)72            {73                typeLib.GetTypeInfoType(i, out ComTypes.TYPEKIND typeKind);74 75                typeLib.GetTypeInfo(i, out ComTypes.ITypeInfo typeInfo);76                if (typeKind == ComTypes.TYPEKIND.TKIND_COCLASS)77                {78                    ComTypeClassDesc classDesc = new ComTypeClassDesc(typeInfo, typeLibDesc);79                    typeLibDesc._classes.AddLast(classDesc);80                }81                else if (typeKind == ComTypes.TYPEKIND.TKIND_ENUM)82                {83                    ComTypeEnumDesc enumDesc = new ComTypeEnumDesc(typeInfo, typeLibDesc);84                    typeLibDesc._enums.Add(enumDesc.TypeName, enumDesc);85                }86                else if (typeKind == ComTypes.TYPEKIND.TKIND_ALIAS)87                {88                    ComTypes.TYPEATTR typeAttr = ComRuntimeHelpers.GetTypeAttrForTypeInfo(typeInfo);89                    if (typeAttr.tdescAlias.vt == (short)VarEnum.VT_USERDEFINED)90                    {91                        ComRuntimeHelpers.GetInfoFromType(typeInfo, out string aliasName, out _);92 93                        typeInfo.GetRefTypeInfo(typeAttr.tdescAlias.lpValue.ToInt32(), out ComTypes.ITypeInfo referencedTypeInfo);94 95                        ComTypes.TYPEATTR referencedTypeAttr = ComRuntimeHelpers.GetTypeAttrForTypeInfo(referencedTypeInfo);96                        ComTypes.TYPEKIND referencedTypeKind = referencedTypeAttr.typekind;97 98                        if (referencedTypeKind == ComTypes.TYPEKIND.TKIND_ENUM)99                        {100                            ComTypeEnumDesc enumDesc = new ComTypeEnumDesc(referencedTypeInfo, typeLibDesc);101                            typeLibDesc._enums.Add(aliasName, enumDesc);102                        }103                    }104                }105            }106 107            // cached the typelib using the guid as the dictionary key108            lock (s_cachedTypeLibDesc)109            {110                s_cachedTypeLibDesc.Add(typeLibAttr.guid, typeLibDesc);111            }112 113            return typeLibDesc;114        }115 116        public object GetTypeLibObjectDesc(string member)117        {118            foreach (ComTypeClassDesc coclass in _classes)119            {120                if (member == coclass.TypeName)121                {122                    return coclass;123                }124            }125 126            if (_enums != null && _enums.TryGetValue(member, out ComTypeEnumDesc enumDesc))127                return enumDesc;128 129            return null;130        }131 132        public string[] GetMemberNames()133        {134            string[] retval = new string[_enums.Count + _classes.Count];135            int i = 0;136            foreach (ComTypeClassDesc coclass in _classes)137            {138                retval[i++] = coclass.TypeName;139            }140 141            foreach (KeyValuePair<string, ComTypeEnumDesc> enumDesc in _enums)142            {143                retval[i++] = enumDesc.Key;144            }145 146            return retval;147        }148 149        internal bool HasMember(string member)150        {151            foreach (ComTypeClassDesc coclass in _classes)152            {153                if (member == coclass.TypeName)154                {155                    return true;156                }157            }158 159            if (_enums.ContainsKey(member))160                return true;161 162            return false;163        }164 165        public Guid Guid => _typeLibAttributes.guid;166 167        public string Name { get; private set; }168 169        internal ComTypeClassDesc GetCoClassForInterface(string itfName)170        {171            foreach (ComTypeClassDesc coclass in _classes)172            {173                if (coclass.Implements(itfName, false))174                {175                    return coclass;176                }177            }178 179            return null;180        }181    }182}183