Exemplo n.º 1
0
 public IntPtr GetFuncDesc(ITypeInfo typeInfo, int index)
 {
     if (typeInfo == null) throw new ArgumentNullException(nameof(typeInfo));
     IntPtr ret;
     typeInfo.GetFuncDesc(index, out ret);
     return ret;
 }
Exemplo n.º 2
0
        private static IntPtr GetFuncDesc_Proxy(ITypeInfo typeInfo, int index)
        {
            IntPtr funcDesc;

            typeInfo.GetFuncDesc(index, out funcDesc);
            return(funcDesc);
        }
Exemplo n.º 3
0
        public IntPtr GetFuncDesc(ITypeInfo typeInfo, int index)
        {
            IntPtr ret;

            typeInfo.GetFuncDesc(index, out ret);
            return(ret);
        }
Exemplo n.º 4
0
        internal static System.Runtime.InteropServices.ComTypes.FUNCDESC GetFuncDesc(ITypeInfo typeinfo, int index)
        {
            IntPtr ptr;

            typeinfo.GetFuncDesc(index, out ptr);
            System.Runtime.InteropServices.ComTypes.FUNCDESC funcdesc = (System.Runtime.InteropServices.ComTypes.FUNCDESC)Marshal.PtrToStructure(ptr, typeof(System.Runtime.InteropServices.ComTypes.FUNCDESC));
            typeinfo.ReleaseFuncDesc(ptr);
            return(funcdesc);
        }
 internal static void GetFuncDescForDescIndex(ITypeInfo typeInfo, int funcIndex, out System.Runtime.InteropServices.ComTypes.FUNCDESC funcDesc, out IntPtr funcDescHandle)
 {
     IntPtr zero = IntPtr.Zero;
     typeInfo.GetFuncDesc(funcIndex, out zero);
     if (zero == IntPtr.Zero)
     {
         throw new COMException(Microsoft.Build.Shared.ResourceUtilities.FormatResourceString("ResolveComReference.CannotRetrieveTypeInformation", new object[0]));
     }
     funcDesc = (System.Runtime.InteropServices.ComTypes.FUNCDESC) Marshal.PtrToStructure(zero, typeof(System.Runtime.InteropServices.ComTypes.FUNCDESC));
     funcDescHandle = zero;
 }
Exemplo n.º 6
0
        public unsafe static ICollection <string?> GetFunctionNames(this ITypeInfo typeInfo, uint functionIndex)
        {
            typeInfo.GetFuncDesc(functionIndex, out FUNCDESC * description)
            .ThrowIfFailed($"Failed to get description for function index: {functionIndex}");

            uint     count = (uint)description->cParams + 1;
            MemberId id    = description->memid;

            typeInfo.ReleaseFuncDesc(description);
            return(GetMemberNames(typeInfo, id, count));
        }
Exemplo n.º 7
0
        private void LoadFuncs(ITypeInfo typeInfo, TYPEATTR typeAttr)
        {
            var skippingFlags = FUNCFLAGS.FUNCFLAG_FRESTRICTED | FUNCFLAGS.FUNCFLAG_FHIDDEN;

            for (var i = 0; i < typeAttr.cFuncs; i++)
            {
                typeInfo.GetFuncDesc(i, out var ptFuncDesc);
                var funcDesc = Marshal.PtrToStructure <FUNCDESC>(ptFuncDesc);

                var currentFlags = (FUNCFLAGS)funcDesc.wFuncFlags;

                if ((currentFlags & skippingFlags) != 0)
                {
                    Marshal.Release(ptFuncDesc);
                    continue;
                }

                var arrOfNames = new string[1];
                var cNames     = arrOfNames.Length;
                var dispId     = funcDesc.memid;

                typeInfo.GetNames(dispId, arrOfNames, cNames, out var names);

                if (names == 0)
                {
                    Marshal.Release(ptFuncDesc);
                    continue;
                }

                var memberName = arrOfNames[0];

                if (funcDesc.invkind == INVOKEKIND.INVOKE_FUNC)
                {
                    var isFunc = funcDesc.elemdescFunc.tdesc.vt != VT_VOID;
                    AddMethod(memberName, dispId, isFunc);
                }
                else
                {
                    var prop = GetOrAddProperty(memberName, dispId);

                    if (funcDesc.invkind == INVOKEKIND.INVOKE_PROPERTYGET)
                    {
                        prop.IsReadable = true;
                    }
                    else
                    {
                        prop.IsWritable = true;
                    }
                }

                Marshal.Release(ptFuncDesc);
            }
        }
        internal static void GetFuncDescForDescIndex(ITypeInfo typeInfo, int funcIndex, out System.Runtime.InteropServices.ComTypes.FUNCDESC funcDesc, out IntPtr funcDescHandle)
        {
            IntPtr zero = IntPtr.Zero;

            typeInfo.GetFuncDesc(funcIndex, out zero);
            if (zero == IntPtr.Zero)
            {
                throw new COMException(Microsoft.Build.Shared.ResourceUtilities.FormatResourceString("ResolveComReference.CannotRetrieveTypeInformation", new object[0]));
            }
            funcDesc       = (System.Runtime.InteropServices.ComTypes.FUNCDESC)Marshal.PtrToStructure(zero, typeof(System.Runtime.InteropServices.ComTypes.FUNCDESC));
            funcDescHandle = zero;
        }
Exemplo n.º 9
0
        /// <summary>
        /// Helper method for retrieving the function description structure for the given function index.
        /// This method needs to also return the native pointer to be released when we're done with our FUNCDESC.
        /// It's not really possible to copy everything to a managed struct and then release the ptr immediately
        /// here, since FUNCDESCs contain other native pointers we may need to access.
        /// </summary>
        internal static void GetFuncDescForDescIndex(ITypeInfo typeInfo, int funcIndex, out FUNCDESC funcDesc, out IntPtr funcDescHandle)
        {
            typeInfo.GetFuncDesc(funcIndex, out IntPtr pFuncDesc);

            // GetFuncDesc should never return null, this is just to be safe
            if (pFuncDesc == IntPtr.Zero)
            {
                throw new COMException(
                          ResourceUtilities.GetResourceString("ResolveComReference.CannotRetrieveTypeInformation"));
            }

            funcDesc       = (FUNCDESC)Marshal.PtrToStructure(pFuncDesc, typeof(FUNCDESC));
            funcDescHandle = pFuncDesc;
        }
Exemplo n.º 10
0
 internal static ComMethodInformation[] GetMethodInformationArray(ITypeInfo typeInfo, Collection<int> methods, bool skipLastParameters)
 {
     int count = methods.Count;
     int num2 = 0;
     ComMethodInformation[] informationArray = new ComMethodInformation[count];
     foreach (int num3 in methods)
     {
         IntPtr ptr;
         typeInfo.GetFuncDesc(num3, out ptr);
         System.Runtime.InteropServices.ComTypes.FUNCDESC funcdesc = (System.Runtime.InteropServices.ComTypes.FUNCDESC) Marshal.PtrToStructure(ptr, typeof(System.Runtime.InteropServices.ComTypes.FUNCDESC));
         informationArray[num2++] = GetMethodInformation(funcdesc, skipLastParameters);
         typeInfo.ReleaseFuncDesc(ptr);
     }
     return informationArray;
 }
Exemplo n.º 11
0
 private void GetComMembers(ITypeInfo info, TYPEATTR attrib)
 {
     for (var index = 0; index < attrib.cFuncs; index++)
     {
         IntPtr memberPtr;
         info.GetFuncDesc(index, out memberPtr);
         var member = (FUNCDESC)Marshal.PtrToStructure(memberPtr, typeof(FUNCDESC));
         if (member.callconv != CALLCONV.CC_STDCALL)
         {
             continue;
         }
         _members.Add(new ComMember(info, member));
         info.ReleaseFuncDesc(memberPtr);
     }
 }
Exemplo n.º 12
0
        public unsafe void GetFunctionDescriptionsForIUnknown()
        {
            TypeLibTests.LoadStdOle2(out ITypeLib typeLib);
            ITypeInfo typeInfo = typeLib.GetTypeInfoByName("IUnknown");

            // From OleView:
            //
            // [restricted]
            // HRESULT _stdcall QueryInterface(
            //                [in] GUID* riid,
            //                [out] void** ppvObj);

            HResult result = typeInfo.GetFuncDesc(0, out FUNCDESC * description);

            result.Should().Be(HResult.S_OK);

            description->cParams.Should().Be(2);
            description->cParamsOpt.Should().Be(0);
            description->cScodes.Should().Be(0);
            description->callconv.Should().Be(CallConvention.StdCall);
            description->funckind.Should().Be(FunctionKind.PureVirtual);
            description->invkind.Should().Be(InvokeKind.Function);
            description->wFuncFlags.Should().Be(FunctionFlags.Restricted);

            // Return type
            description->elemdescFunc.tdesc.vt.Should().Be(VariantType.HResult);

            // First arg GUID*
            ELEMDESC *element = description->lprgelemdescParam;

            element->tdesc.vt.Should().Be(VariantType.Pointer);
            element->Union.paramdesc.wParamFlags.Should().Be(ParameterFlags.In);
            element->tdesc.Union.lptdesc->vt.Should().Be(VariantType.UserDefined);
            RefTypeHandle handle = element->tdesc.Union.lptdesc->Union.hreftype;

            result = typeInfo.GetRefTypeInfo(handle, out ITypeInfo userDefined);
            result.Should().Be(HResult.S_OK);
            userDefined.GetMemberName(MemberId.Nil).Should().Be("GUID");

            // Second arg void**
            element++;
            element->tdesc.vt.Should().Be(VariantType.Pointer);
            element->Union.paramdesc.wParamFlags.Should().Be(ParameterFlags.Out);
            element->tdesc.Union.lptdesc->vt.Should().Be(VariantType.Pointer);
            element->tdesc.Union.lptdesc->Union.lptdesc->vt.Should().Be(VariantType.Void);

            typeInfo.ReleaseFuncDesc(description);
        }
Exemplo n.º 13
0
 private void GetComMembers(ITypeInfo info, TYPEATTR attrib)
 {
     for (var index = 0; index < attrib.cFuncs; index++)
     {
         info.GetFuncDesc(index, out IntPtr memberPtr);
         using (DisposalActionContainer.Create(memberPtr, info.ReleaseFuncDesc))
         {
             var member = Marshal.PtrToStructure <FUNCDESC>(memberPtr);
             if (member.callconv != CALLCONV.CC_STDCALL)
             {
                 continue;
             }
             _members.Add(new ComMember(this, info, member));
         }
     }
 }
Exemplo n.º 14
0
        internal static ComMethodInformation[] GetMethodInformationArray(ITypeInfo typeInfo, Collection <int> methods, bool skipLastParameters)
        {
            int count = methods.Count;
            int num2  = 0;

            ComMethodInformation[] informationArray = new ComMethodInformation[count];
            foreach (int num3 in methods)
            {
                IntPtr ptr;
                typeInfo.GetFuncDesc(num3, out ptr);
                System.Runtime.InteropServices.ComTypes.FUNCDESC funcdesc = (System.Runtime.InteropServices.ComTypes.FUNCDESC)Marshal.PtrToStructure(ptr, typeof(System.Runtime.InteropServices.ComTypes.FUNCDESC));
                informationArray[num2++] = GetMethodInformation(funcdesc, skipLastParameters);
                typeInfo.ReleaseFuncDesc(ptr);
            }
            return(informationArray);
        }
Exemplo n.º 15
0
        private void LoadMembers()
        {
            _members = new List <ComMemberInfo>();

            for (short i = 0; i < _typeAttr.cFuncs; i++)
            {
                IntPtr pFuncDesc = IntPtr.Zero;

                _typeInfo.GetFuncDesc(i, out pFuncDesc);
                ComFunctionInfo comFunctionInfo = new ComFunctionInfo(this, pFuncDesc);

                _members.Add(comFunctionInfo);
            }

            /* Note that these are not always enum constants.  Some properties show up as VARDESC's. */
            for (short i = 0; i < _typeAttr.cVars; i++)
            {
                System.Runtime.InteropServices.ComTypes.VARDESC varDesc;
                IntPtr p = IntPtr.Zero;

                _typeInfo.GetVarDesc(i, out p);
                object constantValue = null;

                try
                {
                    varDesc = p.ToStructure <System.Runtime.InteropServices.ComTypes.VARDESC>();

                    if (varDesc.varkind == VARKIND.VAR_CONST)
                    {
                        constantValue = Marshal.GetObjectForNativeVariant(varDesc.desc.lpvarValue);
                    }
                }
                finally
                {
                    _typeInfo.ReleaseVarDesc(p);
                }

                ComVariableInfo comVariableInfo = new ComVariableInfo(this, varDesc, constantValue);
                _members.Add(comVariableInfo);
            }

            _members.Sort(delegate(ComMemberInfo a, ComMemberInfo b)
            {
                return(a.Name.CompareTo(b.Name));
            });
        }
Exemplo n.º 16
0
        internal static ComMethodInformation[] GetMethodInformationArray(
            ITypeInfo typeInfo,
            Collection <int> methods,
            bool skipLastParameters)
        {
            int count = methods.Count;
            int num   = 0;

            ComMethodInformation[] methodInformationArray = new ComMethodInformation[count];
            foreach (int method in methods)
            {
                IntPtr ppFuncDesc;
                typeInfo.GetFuncDesc(method, out ppFuncDesc);
                System.Runtime.InteropServices.ComTypes.FUNCDESC structure = (System.Runtime.InteropServices.ComTypes.FUNCDESC)Marshal.PtrToStructure(ppFuncDesc, typeof(System.Runtime.InteropServices.ComTypes.FUNCDESC));
                methodInformationArray[num++] = ComUtil.GetMethodInformation(structure, skipLastParameters);
                typeInfo.ReleaseFuncDesc(ppFuncDesc);
            }
            return(methodInformationArray);
        }
Exemplo n.º 17
0
        public static IEnumerable <DispatchMember> GetDispatchMembers(this ITypeInfo typeInfo)
        {
            var funcCount    = typeInfo.GetTypeAttr().cFuncs;
            var isEnumerable = false;

            var names = new string[1];

            for (var index = 0; index < funcCount; index++)
            {
                IntPtr pDesc;
                typeInfo.GetFuncDesc(index, out pDesc);
                try
                {
                    var desc = (FUNCDESC)Marshal.PtrToStructure(pDesc, typeof(FUNCDESC));
                    if (desc.memid == SpecialDispIDs.NewEnum)
                    {
                        isEnumerable = true;
                    }

                    if ((desc.wFuncFlags & (short)FUNCFLAGS.FUNCFLAG_FRESTRICTED) != 0)
                    {
                        continue;
                    }

                    int nameCount;
                    typeInfo.GetNames(desc.memid, names, 1, out nameCount);
                    if (nameCount > 0)
                    {
                        yield return(new DispatchMember(names[0], desc.memid, desc.invkind));
                    }
                }
                finally
                {
                    typeInfo.ReleaseFuncDesc(pDesc);
                }

                if (isEnumerable)
                {
                    yield return(new DispatchMember("GetEnumerator", SpecialDispIDs.GetEnumerator, INVOKEKIND.INVOKE_FUNC));
                }
            }
        }
Exemplo n.º 18
0
 internal static System.Runtime.InteropServices.ComTypes.FUNCDESC GetFuncDesc(ITypeInfo typeinfo, int index)
 {
     IntPtr ptr;
     typeinfo.GetFuncDesc(index, out ptr);
     System.Runtime.InteropServices.ComTypes.FUNCDESC funcdesc = (System.Runtime.InteropServices.ComTypes.FUNCDESC) Marshal.PtrToStructure(ptr, typeof(System.Runtime.InteropServices.ComTypes.FUNCDESC));
     typeinfo.ReleaseFuncDesc(ptr);
     return funcdesc;
 }
Exemplo n.º 19
0
 private static IntPtr GetFuncDesc_Proxy(ITypeInfo typeInfo, int index)
 {
     IntPtr funcDesc;
     typeInfo.GetFuncDesc(index, out funcDesc);
     return funcDesc;
 }
Exemplo n.º 20
0
        public static Dictionary <string, string> GetHelpStrings(Assembly assembly)
        {
            Dictionary <string, string> dictionary = new Dictionary <string, string>();

            var a = assembly.CustomAttributes.FirstOrDefault(x => x.AttributeType.Equals(typeof(ImportedFromTypeLibAttribute)));
            var b = assembly.CustomAttributes.FirstOrDefault(x => x.AttributeType.Equals(typeof(GuidAttribute)));
            var c = assembly.CustomAttributes.FirstOrDefault(x => x.AttributeType.Equals(typeof(TypeLibVersionAttribute)));

            if (a != null)
            {
                Guid guid      = Guid.Parse(String.Format("{0}", b.ConstructorArguments[0].Value));
                int  wVerMajor = (int)c.ConstructorArguments[0].Value;
                int  wVerMinor = (int)c.ConstructorArguments[1].Value;

                ITypeLib typeLib = null;
                typeLib = LoadRegTypeLib(ref guid, wVerMajor, wVerMinor, 0);

                string strLibName       = null;
                string strLibDocString  = null;
                int    dwLibHelpContext = 0;
                string strLibHelpFile   = null;

                typeLib.GetDocumentation(-1, out strLibName, out strLibDocString, out dwLibHelpContext, out strLibHelpFile);

                int count = typeLib.GetTypeInfoCount();

                // Loop through types.
                for (int i = 0; i < count; i++)
                {
                    ITypeInfo typeInfo = null;
                    typeLib.GetTypeInfo(i, out typeInfo);

                    IntPtr pTypeAttr = IntPtr.Zero;

                    typeInfo.GetTypeAttr(out pTypeAttr);
                    System.Runtime.InteropServices.ComTypes.TYPEATTR typeAttr = (System.Runtime.InteropServices.ComTypes.TYPEATTR)Marshal.PtrToStructure(pTypeAttr, typeof(System.Runtime.InteropServices.ComTypes.TYPEATTR));

                    // Skip type if it is hidden.
                    if (typeAttr.wTypeFlags.HasFlag(System.Runtime.InteropServices.ComTypes.TYPEFLAGS.TYPEFLAG_FHIDDEN) == true)
                    {
                        continue;
                    }

                    string strTypeName       = null;
                    string strTypeDocString  = null;
                    int    dwTypeHelpContext = 0;
                    string strTypeHelpFile   = null;

                    typeInfo.GetDocumentation(-1, out strTypeName, out strTypeDocString, out dwTypeHelpContext, out strTypeHelpFile);

                    string typeKey = String.Format("{0}.{1}", strLibName, strTypeName);
                    dictionary.Add(typeKey, strTypeDocString);

                    for (int j = 0; j < typeAttr.cFuncs; j++)
                    {
                        IntPtr pFuncDesc = IntPtr.Zero;
                        typeInfo.GetFuncDesc(j, out pFuncDesc);

                        System.Runtime.InteropServices.ComTypes.FUNCDESC funcDesc = (System.Runtime.InteropServices.ComTypes.FUNCDESC)Marshal.PtrToStructure(pFuncDesc, typeof(System.Runtime.InteropServices.ComTypes.FUNCDESC));

                        string strMemberName       = null;
                        string strMemberDocString  = null;
                        int    dwMemberHelpContext = 0;
                        string strMemberHelpFile   = null;

                        typeInfo.GetDocumentation(funcDesc.memid, out strMemberName, out strMemberDocString, out dwMemberHelpContext, out strMemberHelpFile);

                        string memberKey = String.Format("{0}.{1}", typeKey, strMemberName);

                        if (!dictionary.ContainsKey(memberKey))
                        {
                            dictionary.Add(memberKey, strMemberDocString);
                        }

                        typeInfo.ReleaseFuncDesc(pFuncDesc);
                    }

                    typeInfo.ReleaseTypeAttr(pTypeAttr);
                }
            }

            return(dictionary);
        }
Exemplo n.º 21
0
        private Declaration CreateMemberDeclaration(out FUNCDESC memberDescriptor, TYPEKIND typeKind, ITypeInfo info, int memberIndex,
                                                    QualifiedModuleName typeQualifiedModuleName, Declaration moduleDeclaration, out string[] memberNames)
        {
            IntPtr memberDescriptorPointer;

            info.GetFuncDesc(memberIndex, out memberDescriptorPointer);
            memberDescriptor = (FUNCDESC)Marshal.PtrToStructure(memberDescriptorPointer, typeof(FUNCDESC));

            if (memberDescriptor.callconv != CALLCONV.CC_STDCALL)
            {
                memberDescriptor = new FUNCDESC();
                memberNames      = new string[] {};
                return(null);
            }

            memberNames = new string[255];
            int namesArrayLength;

            info.GetNames(memberDescriptor.memid, memberNames, 255, out namesArrayLength);

            var memberName            = memberNames[0];
            var funcValueType         = (VarEnum)memberDescriptor.elemdescFunc.tdesc.vt;
            var memberDeclarationType = GetDeclarationType(memberDescriptor, funcValueType, typeKind);

            var asTypeName = string.Empty;

            if (memberDeclarationType != DeclarationType.Procedure && !TypeNames.TryGetValue(funcValueType, out asTypeName))
            {
                if (funcValueType == VarEnum.VT_PTR)
                {
                    try
                    {
                        var asTypeDesc = (TYPEDESC)Marshal.PtrToStructure(memberDescriptor.elemdescFunc.tdesc.lpValue, typeof(TYPEDESC));
                        asTypeName = GetTypeName(asTypeDesc, info);
                    }
                    catch
                    {
                        asTypeName = funcValueType.ToString(); //TypeNames[VarEnum.VT_VARIANT];
                    }
                }
                else
                {
                    asTypeName = funcValueType.ToString(); //TypeNames[VarEnum.VT_VARIANT];
                }
            }

            var attributes = new Attributes();

            if (memberName == "_NewEnum" && ((FUNCFLAGS)memberDescriptor.wFuncFlags).HasFlag(FUNCFLAGS.FUNCFLAG_FNONBROWSABLE))
            {
                attributes.AddEnumeratorMemberAttribute(memberName);
            }
            else if (memberDescriptor.memid == 0)
            {
                attributes.AddDefaultMemberAttribute(memberName);
                //Debug.WriteLine("Default member found: {0}.{1} ({2} / {3})", moduleDeclaration.IdentifierName, memberName, memberDeclarationType, (VarEnum)memberDescriptor.elemdescFunc.tdesc.vt);
            }
            else if (((FUNCFLAGS)memberDescriptor.wFuncFlags).HasFlag(FUNCFLAGS.FUNCFLAG_FHIDDEN))
            {
                attributes.AddHiddenMemberAttribute(memberName);
            }

            return(new Declaration(new QualifiedMemberName(typeQualifiedModuleName, memberName),
                                   moduleDeclaration, moduleDeclaration, asTypeName, false, false, Accessibility.Global, memberDeclarationType,
                                   null, Selection.Home, true, null, attributes));
        }
Exemplo n.º 22
0
 public FuncDesc(int index, ITypeInfo typeinfo)
 {
     m_typeinfo = typeinfo;
     typeinfo.GetFuncDesc(index, out m_ipFuncDesc);
     m_funcdesc = (FUNCDESC)Marshal.PtrToStructure(m_ipFuncDesc, typeof(FUNCDESC));
 }
Exemplo n.º 23
0
        /// <summary>
        /// Helper method for retrieving the function description structure for the given function index.
        /// This method needs to also return the native pointer to be released when we're done with our FUNCDESC.
        /// It's not really possible to copy everything to a managed struct and then release the ptr immediately
        /// here, since FUNCDESCs contain other native pointers we may need to access.
        /// </summary>
        /// <param name="typeInfo"></param>
        /// <param name="funcIndex"></param>
        /// <param name="funcDesc"></param>
        /// <param name="funcDescHandle"></param>
        /// <returns></returns>
        internal static void GetFuncDescForDescIndex(ITypeInfo typeInfo, int funcIndex, out FUNCDESC funcDesc, out IntPtr funcDescHandle)
        {
            IntPtr pFuncDesc = IntPtr.Zero;
            typeInfo.GetFuncDesc(funcIndex, out pFuncDesc);

            // GetFuncDesc should never return null, this is just to be safe
            if (pFuncDesc == IntPtr.Zero)
            {
                throw new COMException(
                    ResourceUtilities.FormatResourceString("ResolveComReference.CannotRetrieveTypeInformation"));
            }

            funcDesc = (FUNCDESC)Marshal.PtrToStructure(pFuncDesc, typeof(FUNCDESC));
            funcDescHandle = pFuncDesc;
        }
Exemplo n.º 24
0
 public static IScope <FUNCDESC> CreateFuncDescScope(this ITypeInfo typeInfo, int index)
 {
     return(StructHelpers.CreateScope <FUNCDESC>((out IntPtr pFuncDesc) => typeInfo.GetFuncDesc(index, out pFuncDesc), typeInfo.ReleaseFuncDesc));
 }
Exemplo n.º 25
0
        public override void asCommandLine(Dictionary <string, string> args)
        {
            _typeLibrary = (string)args["TypeLibrary"];
            //_typeLibrary = @"C:\Peach3\ComTest\Release\ComTest.dll";

            if (!File.Exists(_typeLibrary))
            {
                throw new PeachException("Error, the TypeLibrary was not found.");
            }

            ITypeLib typeLib = null;
            int      ret     = LoadTypeLib(_typeLibrary, out typeLib);

            if (ret != 0)
            {
                throw new PeachException("Error loading TypeLibrary.  LoadTypeLib returned " + ret);
            }

            if (typeLib == null)
            {
                throw new PeachException("Error, LoadTypeLib returned a null ITypeLib interface.");
            }

            string name;
            string doc;
            int    helpid;
            string helpfile;

            string [] arrClassification = new string [] { "Enum", "Struct", "Module", "Interface",
                                                          "Dispinterface", "Coclass", "Typedef", "Union" };


            typeLib.GetDocumentation(-1, out name, out doc, out helpid, out helpfile);
            Console.WriteLine(name);

            ITypeInfo typeInfo = null;

            for (int cnt = 0; cnt < typeLib.GetTypeInfoCount(); cnt++)
            {
                // http://www.codeguru.com/cpp/com-tech/activex/misc/article.php/c2569

                Console.WriteLine(" ------------- ");

                typeInfo = null;
                typeLib.GetTypeInfo(cnt, out typeInfo);
                if (typeInfo == null)
                {
                    Console.WriteLine("typeInfo was null, continue!");
                    continue;
                }

                typeLib.GetDocumentation(cnt, out name, out doc, out helpid, out helpfile);
                Console.WriteLine("  " + name);

                System.Runtime.InteropServices.ComTypes.TYPEKIND typeKind;
                typeLib.GetTypeInfoType(cnt, out typeKind);

                Console.WriteLine("  " + arrClassification[(int)typeKind]);

                IntPtr ppTypeAttributes;
                typeInfo.GetTypeAttr(out ppTypeAttributes);
                var typeAttributes = (System.Runtime.InteropServices.ComTypes.TYPEATTR)Marshal.PtrToStructure(ppTypeAttributes, typeof(System.Runtime.InteropServices.ComTypes.TYPEATTR));

                for (int cntFuncs = 0; cntFuncs < typeAttributes.cFuncs; cntFuncs++)
                {
                    IntPtr ppFuncDesc;
                    typeInfo.GetFuncDesc(cntFuncs, out ppFuncDesc);
                    var funcDesc = (System.Runtime.InteropServices.ComTypes.FUNCDESC)Marshal.PtrToStructure(ppFuncDesc, typeof(System.Runtime.InteropServices.ComTypes.FUNCDESC));

                    int memberID = funcDesc.memid;
                    //var elemDesc = funcDesc.elemdescFunc;

                    typeInfo.GetDocumentation(memberID, out name, out doc, out helpid, out helpfile);
                    Console.WriteLine("    " + name);

                    //funcDesc.

                    typeInfo.ReleaseFuncDesc(ppFuncDesc);
                }

                for (int cntVars = 0; cntVars < typeAttributes.cVars; cntVars++)
                {
                    IntPtr ppVarDesc;
                    typeInfo.GetVarDesc(cntVars, out ppVarDesc);
                    var varDesc = (System.Runtime.InteropServices.ComTypes.VARDESC)Marshal.PtrToStructure(ppVarDesc, typeof(System.Runtime.InteropServices.ComTypes.VARDESC));

                    int memberID = varDesc.memid;

                    typeInfo.GetDocumentation(memberID, out name, out doc, out helpid, out helpfile);
                    Console.WriteLine("    " + name);

                    typeInfo.ReleaseVarDesc(ppVarDesc);
                }

                typeInfo.ReleaseTypeAttr(ppTypeAttributes);
            }
        }