![]() | |
![]() |
| | Thread Tools | Search this Thread | Display Modes |
#1
| |||
| |||
|
#2
| |||
| |||
|
#3
| |||
| |||
|
|
Hi Michael, If the COM object implements IDispatch, we can use IDispatch.GetTypeInfo to get its type information. Please try following code: 1) Add reference to "CustomMarshalers", you should be able to find it at %windir%\Microsoft.NET\Framework\v2.0.50727\Custom Marshalers.dll. 2) Use following code to test: using System; using System.Text; using System.Runtime.InteropServices; using System.Reflection; using System.Runtime.InteropServices.CustomMarshalers; namespace ConsoleApplication1 { [ ComImport, Guid("00020400-0000-0000-C000-000000000046"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown ) ] public interface IDispatch { void Reserved(); [PreserveSig] int GetTypeInfo(uint nInfo, int lcid, [MarshalAs( UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(TypeToTypeInfoMarshaler))] out System.Type typeInfo); } class Program { static void Main(string[] args) { Type t1 = Type.GetTypeFromProgID("Scripting.FileSystemObject "); Object o1 = Activator.CreateInstance(t1); IDispatch disp2 = o1 as IDispatch; if (disp2 != null) { Type t3; disp2.GetTypeInfo(0, 0, out t3); MemberInfo[] mlist3 = t3.GetMembers(); } } } } References: #.NET Remoting: Create a Custom Marshaling Implementation Using .NET Remoting and COM Interop -- MSDN Magazine, September 2003 http://msdn.microsoft.com/msdnmag/is...tomMarshaling/ Hope this helps. Regards, Walter Wang (wawang (AT) online (DOT) microsoft.com, remove 'online.') Microsoft Online Community Support ================================================== When responding to posts, please "Reply to Group" via your newsreader so that others may learn and benefit from your issue. ================================================== This posting is provided "AS IS" with no warranties, and confers no rights. |
#4
| |||
| |||
|
#5
| |||
| |||
|
|
Hi Michael, If the COM object implements IDispatch, we can use IDispatch.GetTypeInfotogetitstypeinformation. Please try following code: 1) Add reference to "CustomMarshalers", you should be able to find it at %windir%\Microsoft.NET\Framework\v2.0.50727\Custom Marshalers.dll. 2) Use following code to test: class Program { static void Main(string[] args) { Typet1 =Type.GetTypeFromProgID("Scripting.FileSystemObjec t"); Object o1 = Activator.CreateInstance(t1); IDispatch disp2 = o1 as IDispatch; if (disp2 != null) { Typet3; disp2.GetTypeInfo(0, 0, out t3); MemberInfo[] mlist3 = t3.GetMembers(); } } } } References: #.NET Remoting: Create a Custom Marshaling Implementation Using .NET Remoting and COM Interop -- MSDN Magazine, September 2003http://msdn.microsoft.com/msdnmag/issues/03/09/CustomMarshaling/ Hope this helps. Regards, Walter Wang (waw... (AT) online (DOT) microsoft.com, remove 'online.') Microsoft Online Community Support This posting is provided "AS IS" with no warranties, and confers no rights. |
#6
| |||
| |||
|
|
On 15 Okt, 08:20, waw... (AT) online (DOT) microsoft.com ("Walter Wang [MSFT]") wrote: Hi Michael, If the COM object implements IDispatch, we can use IDispatch.GetTypeInfotogetitstypeinformation. Please try following code: 1) Add reference to "CustomMarshalers", you should be able to find it at %windir%\Microsoft.NET\Framework\v2.0.50727\Custom Marshalers.dll. 2) Use following code to test: class Program { static void Main(string[] args) { Typet1 =Type.GetTypeFromProgID("Scripting.FileSystemObjec t"); Object o1 = Activator.CreateInstance(t1); IDispatch disp2 = o1 as IDispatch; if (disp2 != null) { Typet3; disp2.GetTypeInfo(0, 0, out t3); MemberInfo[] mlist3 = t3.GetMembers(); } } } } References: #.NET Remoting: Create a Custom Marshaling Implementation Using .NET Remoting and COM Interop -- MSDN Magazine, September 2003http://msdn.microsoft.com/msdnmag/issues/03/09/CustomMarshaling/ Hope this helps. Regards, Walter Wang (waw... (AT) online (DOT) microsoft.com, remove 'online.') Microsoft Online Community Support This posting is provided "AS IS" with no warranties, and confers no rights. Hi I'm trying to do the exactly same but the method: disp2.GetTypeInfo(0, 0, out t3); takes very long time to get finished, about 4 minutes, which is too mutch of course. What can be the reason for this? I know that my COM- object has very many interfaces, but I cant understand why this shouldn't be handled....... My COM is written in Delphi and I have access to the source, is there anything I can look at in the source to make this faster? Thanks in advance - RightCoder |
#7
| |||
| |||
|
|
The reason that it is taking so long is because it's generating in-memory interop assemblies behind the scenes. It's basically the same thing as adding a reference to a type library in Visual Studio although it seems to be slower than when you manually add the reference. The faster but more difficult way to work with COM in .NET is to work directly with the IDispatch interface. Here is a bit of code that I use in one of my applications. The code listed below are 3 separate .cs files. I also did not list my full source so not all functionality is available in what I'm giving you but it should be enough to give you an idea as to what's involved. Once you have the code in place, you can use it something like: Jason Newell www.jasonnewell.net /* Example Usage */ ComObject comObject = new ComObject(Marshal.GetActiveObject("Word.Applicatio n")); string[] propertyNames = comObject.GetPropertyNames(); foreach (string propertyName in propertyNames) { object property = comObject.WrappedComObject.GetType().InvokeMember( propertyName, System.Reflection.BindingFlags.GetProperty, null, comObject.WrappedComObject, null); } /* IDispatch.cs */ using System; using System.Collections.Generic; using System.Runtime.InteropServices; using System.Text; namespace SolidEdgeSpy.InteropServices { [Guid("00020400-0000-0000-c000-000000000046"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown )] public interface IDispatch { int GetTypeInfoCount(); System.Runtime.InteropServices.ComTypes.ITypeInfo GetTypeInfo([MarshalAs(UnmanagedType.U4)] int iTInfo, [MarshalAs(UnmanagedType.U4)] int lcid); [PreserveSig] int GetIDsOfNames(ref Guid riid, [MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.LPWStr)] string[] rgsNames, int cNames, int lcid, [MarshalAs(UnmanagedType.LPArray)] int[] rgDispId); [PreserveSig] int Invoke(int dispIdMember, ref Guid riid, [MarshalAs(UnmanagedType.U4)] int lcid, [MarshalAs(UnmanagedType.U4)] int dwFlags, ref System.Runtime.InteropServices.ComTypes.DISPPARAMS pDispParams, [Out, MarshalAs(UnmanagedType.LPArray)] object[] pVarResult, ref System.Runtime.InteropServices.ComTypes.EXCEPINFO pExcepInfo, [Out, MarshalAs(UnmanagedType.LPArray)] IntPtr[] pArgErr); } } /* ComObject.cs */ using System; using System.Collections.Generic; using System.Runtime.InteropServices; using System.Runtime.InteropServices.ComTypes; using System.Text; namespace SolidEdgeSpy.InteropServices { public class ComObject : IDisposable { private object _object; private IDispatch _dispatch; private IntPtr _pTypeAttr = IntPtr.Zero; private System.Runtime.InteropServices.ComTypes.ITypeInfo _typeInfo; private string _typeName, _typeDescription, _typeHelpFile; private int _typeHelpContext; private SolidEdgeSpy.InteropServices.ComTypeLibrary _comTypeLibrary; public ComObject(object comObject) { System.Runtime.InteropServices.ComTypes.ITypeLib ppTLB = null; int pIndex = 0; _dispatch = comObject as IDispatch; if (_dispatch != null) { _object = comObject; _typeInfo = _dispatch.GetTypeInfo(0, 0); _typeInfo.GetTypeAttr(out _pTypeAttr); _typeInfo.GetDocumentation(-1, out _typeName, out _typeDescription, out _typeHelpContext, out _typeHelpFile); _typeInfo.GetContainingTypeLib(out ppTLB, out pIndex); _comTypeLibrary = new ComTypeLibrary(ppTLB); } else { throw new InvalidComObjectException(); } } ~ComObject() { Dispose(); } public void Dispose() { try { if (_typeInfo != null) { _typeInfo.ReleaseTypeAttr(_pTypeAttr); } if (_object != null) { Marshal.ReleaseComObject(_object); _object = null; } if (_dispatch != null) { Marshal.ReleaseComObject(_dispatch); _dispatch = null; } } catch { } } public string[] GetPropertyNames() { System.Collections.ArrayList list = new System.Collections.ArrayList(); try { for (int i = 0; i < this.TypeAttr.cFuncs; i++) { IntPtr pFuncDesc = IntPtr.Zero; System.Runtime.InteropServices.ComTypes.FUNCDESC funcDesc; string strName, strDocString, strHelpFile; int dwHelpContext; _typeInfo.GetFuncDesc(i, out pFuncDesc); funcDesc = (System.Runtime.InteropServices.ComTypes.FUNCDESC) Marshal.PtrToStructure(pFuncDesc, typeof(System.Runtime.InteropServices.ComTypes.FUN CDESC)); switch (funcDesc.invkind) { case System.Runtime.InteropServices.ComTypes.INVOKEKIND .INVOKE_PROPERTYGET: _typeInfo.GetDocumentation(funcDesc.memid, out strName, out strDocString, out dwHelpContext, out strHelpFile); list.Add(strName); break; } } } catch (System.Exception ex) { throw ex; } return (string[])list.ToArray(typeof(string)); } public string TypeName { get { return this._typeName; } } public string TypeFullName { get { return this.ComTypeLibrary.Name + "." + this._typeName; } } public string TypeDescription { get { return this._typeDescription; } } public int TypeHelpContext { get { return this._typeHelpContext; } } public string TypeHelpFile { get { return this._typeHelpFile; } } public object WrappedComObject { get { return _dispatch; } } public ComTypeLibrary ComTypeLibrary { get { return _comTypeLibrary; } } public System.Runtime.InteropServices.ComTypes.TYPEATTR TypeAttr { get { return (System.Runtime.InteropServices.ComTypes.TYPEATTR) Marshal.PtrToStructure(_pTypeAttr, typeof(System.Runtime.InteropServices.ComTypes.TYP EATTR)); } } public string TypeVersion { get { string version = String.Empty; try { version = TypeAttr.wMajorVerNum.ToString() + "." + TypeAttr.wMinorVerNum.ToString(); } catch { } return version; } } } } /* ComTypeLibrary.cs */ using System; using System.Collections.Generic; using System.IO; using System.Reflection; using System.Reflection.Emit; using System.Runtime.InteropServices; using System.Runtime.InteropServices.ComTypes; using System.Text; namespace SolidEdgeSpy.InteropServices { public class ComTypeLibrary { private System.Runtime.InteropServices.ComTypes.ITypeLib _typeLib; IntPtr _pTypeLibAttr = IntPtr.Zero; string _Name, _Description, _HelpFile; int _HelpContext; public ComTypeLibrary(System.Runtime.InteropServices.ComT ypes.ITypeLib typeLib) { _typeLib = typeLib; _typeLib.GetLibAttr(out _pTypeLibAttr); _typeLib.GetDocumentation(-1, out _Name, out _Description, out _HelpContext, out _HelpFile); } public string Name { get { return this._Name; } } public string Description { get { return this._Description; } } public int HelpContext { get { return this._HelpContext; } } public string HelpFile { get { return this._HelpFile; } } public System.Runtime.InteropServices.ComTypes.TYPELIBATT R TypeLibAttr { get { return (System.Runtime.InteropServices.ComTypes.TYPELIBAT TR)Marshal.PtrToStructure(_pTypeLibAttr, typeof(System.Runtime.InteropServices.ComTypes.TYP ELIBATTR)); } } public string TypeLibVersion { get { string version = String.Empty; try { version = TypeLibAttr.wMajorVerNum.ToString() + "." + TypeLibAttr.wMinorVerNum.ToString(); } catch { } return version; } } public Version Version { get { return new Version(TypeLibAttr.wMajorVerNum, TypeLibAttr.wMinorVerNum, 0, 0); } } public override int GetHashCode() { return this.TypeLibAttr.guid.GetHashCode() + this.TypeLibAttr.wMajorVerNum.GetHashCode() + this.TypeLibAttr.wMinorVerNum.GetHashCode(); } public override bool Equals(object obj) { ComTypeLibrary comTypeLibrary = obj as ComTypeLibrary; if (comTypeLibrary != null) { if (this.TypeLibAttr.guid.Equals(comTypeLibrary.TypeL ibAttr.guid)) { if (this.TypeLibAttr.wMajorVerNum.Equals(comTypeLibra ry.TypeLibAttr.wMajorVerNum)) { if (this.TypeLibAttr.wMinorVerNum.Equals(comTypeLibra ry.TypeLibAttr.wMinorVerNum)) { return true; } } } return base.Equals(obj); } else { return base.Equals(obj); } } public override string ToString() |
#8
| |||
| |||
|
|
Hi Jason Thank you for your response. I must admit I have not had a closer look at your code because it seems to be a lot of work to be done before I'm there. I have no experience with COM nor working with IDispatch so this looks like a mountain for me. I dont have the time either to sit down and understand all the details. I may be asking for much here, but I'm looking for a complete solution and I was hoping it was a matter of changing an input-parameter or doing another methodcall. Is it really that difficult to introspect COM from .NET? What else could be done to make this work without taking so long time? Could I make the COMs TLB available on the client? There must be an easier way or a workaround that is doable for a mere mortal like me (ASP.NET developer)? ;-) "Jason Newell" wrote: The reason that it is taking so long is because it's generating in-memory interop assemblies behind the scenes. It's basically the same thing as adding a reference to a type library in Visual Studio although it seems to be slower than when you manually add the reference. The faster but more difficult way to work with COM in .NET is to work directly with the IDispatch interface. Here is a bit of code that I use in one of my applications. The code listed below are 3 separate .cs files. I also did not list my full source so not all functionality is available in what I'm giving you but it should be enough to give you an idea as to what's involved. Once you have the code in place, you can use it something like: Jason Newell www.jasonnewell.net /* Example Usage */ ComObject comObject = new ComObject(Marshal.GetActiveObject("Word.Applicatio n")); string[] propertyNames = comObject.GetPropertyNames(); foreach (string propertyName in propertyNames) { object property = comObject.WrappedComObject.GetType().InvokeMember( propertyName, System.Reflection.BindingFlags.GetProperty, null, comObject.WrappedComObject, null); } /* IDispatch.cs */ using System; using System.Collections.Generic; using System.Runtime.InteropServices; using System.Text; namespace SolidEdgeSpy.InteropServices { [Guid("00020400-0000-0000-c000-000000000046"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown )] public interface IDispatch { int GetTypeInfoCount(); System.Runtime.InteropServices.ComTypes.ITypeInfo GetTypeInfo([MarshalAs(UnmanagedType.U4)] int iTInfo, [MarshalAs(UnmanagedType.U4)] int lcid); [PreserveSig] int GetIDsOfNames(ref Guid riid, [MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.LPWStr)] string[] rgsNames, int cNames, int lcid, [MarshalAs(UnmanagedType.LPArray)] int[] rgDispId); [PreserveSig] int Invoke(int dispIdMember, ref Guid riid, [MarshalAs(UnmanagedType.U4)] int lcid, [MarshalAs(UnmanagedType.U4)] int dwFlags, ref System.Runtime.InteropServices.ComTypes.DISPPARAMS pDispParams, [Out, MarshalAs(UnmanagedType.LPArray)] object[] pVarResult, ref System.Runtime.InteropServices.ComTypes.EXCEPINFO pExcepInfo, [Out, MarshalAs(UnmanagedType.LPArray)] IntPtr[] pArgErr); } } /* ComObject.cs */ using System; using System.Collections.Generic; using System.Runtime.InteropServices; using System.Runtime.InteropServices.ComTypes; using System.Text; namespace SolidEdgeSpy.InteropServices { public class ComObject : IDisposable { private object _object; private IDispatch _dispatch; private IntPtr _pTypeAttr = IntPtr.Zero; private System.Runtime.InteropServices.ComTypes.ITypeInfo _typeInfo; private string _typeName, _typeDescription, _typeHelpFile; private int _typeHelpContext; private SolidEdgeSpy.InteropServices.ComTypeLibrary _comTypeLibrary; public ComObject(object comObject) { System.Runtime.InteropServices.ComTypes.ITypeLib ppTLB = null; int pIndex = 0; _dispatch = comObject as IDispatch; if (_dispatch != null) { _object = comObject; _typeInfo = _dispatch.GetTypeInfo(0, 0); _typeInfo.GetTypeAttr(out _pTypeAttr); _typeInfo.GetDocumentation(-1, out _typeName, out _typeDescription, out _typeHelpContext, out _typeHelpFile); _typeInfo.GetContainingTypeLib(out ppTLB, out pIndex); _comTypeLibrary = new ComTypeLibrary(ppTLB); } else { throw new InvalidComObjectException(); } } ~ComObject() { Dispose(); } public void Dispose() { try { if (_typeInfo != null) { _typeInfo.ReleaseTypeAttr(_pTypeAttr); } if (_object != null) { Marshal.ReleaseComObject(_object); _object = null; } if (_dispatch != null) { Marshal.ReleaseComObject(_dispatch); _dispatch = null; } } catch { } } public string[] GetPropertyNames() { System.Collections.ArrayList list = new System.Collections.ArrayList(); try { for (int i = 0; i < this.TypeAttr.cFuncs; i++) { IntPtr pFuncDesc = IntPtr.Zero; System.Runtime.InteropServices.ComTypes.FUNCDESC funcDesc; string strName, strDocString, strHelpFile; int dwHelpContext; _typeInfo.GetFuncDesc(i, out pFuncDesc); funcDesc = (System.Runtime.InteropServices.ComTypes.FUNCDESC) Marshal.PtrToStructure(pFuncDesc, typeof(System.Runtime.InteropServices.ComTypes.FUN CDESC)); switch (funcDesc.invkind) { case System.Runtime.InteropServices.ComTypes.INVOKEKIND .INVOKE_PROPERTYGET: _typeInfo.GetDocumentation(funcDesc.memid, out strName, out strDocString, out dwHelpContext, out strHelpFile); list.Add(strName); break; } } } catch (System.Exception ex) { throw ex; } return (string[])list.ToArray(typeof(string)); } public string TypeName { get { return this._typeName; } } public string TypeFullName { get { return this.ComTypeLibrary.Name + "." + this._typeName; } } public string TypeDescription { get { return this._typeDescription; } } public int TypeHelpContext { get { return this._typeHelpContext; } } public string TypeHelpFile { get { return this._typeHelpFile; } } public object WrappedComObject { get { return _dispatch; } } public ComTypeLibrary ComTypeLibrary { get { return _comTypeLibrary; } } public System.Runtime.InteropServices.ComTypes.TYPEATTR TypeAttr { get { return (System.Runtime.InteropServices.ComTypes.TYPEATTR) Marshal.PtrToStructure(_pTypeAttr, typeof(System.Runtime.InteropServices.ComTypes.TYP EATTR)); } } public string TypeVersion { get { string version = String.Empty; try { version = TypeAttr.wMajorVerNum.ToString() + "." + TypeAttr.wMinorVerNum.ToString(); } catch { } return version; } } } } /* ComTypeLibrary.cs */ using System; using System.Collections.Generic; using System.IO; using System.Reflection; using System.Reflection.Emit; using System.Runtime.InteropServices; using System.Runtime.InteropServices.ComTypes; using System.Text; namespace SolidEdgeSpy.InteropServices { public class ComTypeLibrary { private System.Runtime.InteropServices.ComTypes.ITypeLib _typeLib; IntPtr _pTypeLibAttr = IntPtr.Zero; string _Name, _Description, _HelpFile; int _HelpContext; public ComTypeLibrary(System.Runtime.InteropServices.ComT ypes.ITypeLib typeLib) { _typeLib = typeLib; _typeLib.GetLibAttr(out _pTypeLibAttr); _typeLib.GetDocumentation(-1, out _Name, out _Description, out _HelpContext, out _HelpFile); } public string Name { get { return this._Name; } } public string Description { get { return this._Description; } } public int HelpContext { get { return this._HelpContext; } } public string HelpFile { get { return this._HelpFile; } } public System.Runtime.InteropServices.ComTypes.TYPELIBATT R TypeLibAttr { get { return (System.Runtime.InteropServices.ComTypes.TYPELIBAT TR)Marshal.PtrToStructure(_pTypeLibAttr, typeof(System.Runtime.InteropServices.ComTypes.TYP ELIBATTR)); } } public string TypeLibVersion { get { string version = String.Empty; try { version = TypeLibAttr.wMajorVerNum.ToString() + "." + TypeLibAttr.wMinorVerNum.ToString(); } catch { } return version; } } public Version Version { get { return new Version(TypeLibAttr.wMajorVerNum, TypeLibAttr.wMinorVerNum, 0, 0); } } public override int GetHashCode() { return this.TypeLibAttr.guid.GetHashCode() + this.TypeLibAttr.wMajorVerNum.GetHashCode() + this.TypeLibAttr.wMinorVerNum.GetHashCode(); } public override bool Equals(object obj) { ComTypeLibrary comTypeLibrary = obj as ComTypeLibrary; if (comTypeLibrary != null) { if (this.TypeLibAttr.guid.Equals(comTypeLibrary.TypeL ibAttr.guid)) { if (this.TypeLibAttr.wMajorVerNum.Equals(comTypeLibra ry.TypeLibAttr.wMajorVerNum)) { if (this.TypeLibAttr.wMinorVerNum.Equals(comTypeLibra ry.TypeLibAttr.wMinorVerNum)) { return true; } } } return base.Equals(obj); } else { return base.Equals(obj); } } public override string ToString() |
#9
| |||
| |||
|
|
If there is an easier way to do it with existing .NET API's, then I guess I've wasted a considerable amount of time developing a lot of code. I always look for existing .NET API's before I dive off doing things myself, but in this case, I found no other solution. Fortunately for me, I do have a lot of COM experience so I'm able to write the code. The API that I've written closely resembles the existing System.Reflection namespace. Everything that I've done starts with the name Com. i.e. ComType, ComObject, ComMethodInfo, ComPropertyInfo, ComParameterInfo, etc. The code that I posted is still very much a work in progress. It sounds like it could be useful to others so I'll post a copy of the source onto my website. Maybe even write a Code Project article about it. Jason Newell www.jasonnewell.net RightCoder wrote: Hi Jason Thank you for your response. I must admit I have not had a closer look at your code because it seems to be a lot of work to be done before I'm there. I have no experience with COM nor working with IDispatch so this looks like a mountain for me. I dont have the time either to sit down and understand all the details. I may be asking for much here, but I'm looking for a complete solution and I was hoping it was a matter of changing an input-parameter or doing another methodcall. Is it really that difficult to introspect COM from .NET? What else could be done to make this work without taking so long time? Could I make the COMs TLB available on the client? There must be an easier way or a workaround that is doable for a mere mortal like me (ASP.NET developer)? ;-) "Jason Newell" wrote: The reason that it is taking so long is because it's generating in-memory interop assemblies behind the scenes. It's basically the same thing as adding a reference to a type library in Visual Studio although it seems to be slower than when you manually add the reference. The faster but more difficult way to work with COM in .NET is to work directly with the IDispatch interface. Here is a bit of code that I use in one of my applications. The code listed below are 3 separate .cs files. I also did not list my full source so not all functionality is available in what I'm giving you but it should be enough to give you an idea as to what's involved. Once you have the code in place, you can use it something like: Jason Newell www.jasonnewell.net /* Example Usage */ ComObject comObject = new ComObject(Marshal.GetActiveObject("Word.Applicatio n")); string[] propertyNames = comObject.GetPropertyNames(); foreach (string propertyName in propertyNames) { object property = comObject.WrappedComObject.GetType().InvokeMember( propertyName, System.Reflection.BindingFlags.GetProperty, null, comObject.WrappedComObject, null); } /* IDispatch.cs */ using System; using System.Collections.Generic; using System.Runtime.InteropServices; using System.Text; namespace SolidEdgeSpy.InteropServices { [Guid("00020400-0000-0000-c000-000000000046"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown )] public interface IDispatch { int GetTypeInfoCount(); System.Runtime.InteropServices.ComTypes.ITypeInfo GetTypeInfo([MarshalAs(UnmanagedType.U4)] int iTInfo, [MarshalAs(UnmanagedType.U4)] int lcid); [PreserveSig] int GetIDsOfNames(ref Guid riid, [MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.LPWStr)] string[] rgsNames, int cNames, int lcid, [MarshalAs(UnmanagedType.LPArray)] int[] rgDispId); [PreserveSig] int Invoke(int dispIdMember, ref Guid riid, [MarshalAs(UnmanagedType.U4)] int lcid, [MarshalAs(UnmanagedType.U4)] int dwFlags, ref System.Runtime.InteropServices.ComTypes.DISPPARAMS pDispParams, [Out, MarshalAs(UnmanagedType.LPArray)] object[] pVarResult, ref System.Runtime.InteropServices.ComTypes.EXCEPINFO pExcepInfo, [Out, MarshalAs(UnmanagedType.LPArray)] IntPtr[] pArgErr); } } /* ComObject.cs */ using System; using System.Collections.Generic; using System.Runtime.InteropServices; using System.Runtime.InteropServices.ComTypes; using System.Text; namespace SolidEdgeSpy.InteropServices { public class ComObject : IDisposable { private object _object; private IDispatch _dispatch; private IntPtr _pTypeAttr = IntPtr.Zero; private System.Runtime.InteropServices.ComTypes.ITypeInfo _typeInfo; private string _typeName, _typeDescription, _typeHelpFile; private int _typeHelpContext; private SolidEdgeSpy.InteropServices.ComTypeLibrary _comTypeLibrary; public ComObject(object comObject) { System.Runtime.InteropServices.ComTypes.ITypeLib ppTLB = null; int pIndex = 0; _dispatch = comObject as IDispatch; if (_dispatch != null) { _object = comObject; _typeInfo = _dispatch.GetTypeInfo(0, 0); _typeInfo.GetTypeAttr(out _pTypeAttr); _typeInfo.GetDocumentation(-1, out _typeName, out _typeDescription, out _typeHelpContext, out _typeHelpFile); _typeInfo.GetContainingTypeLib(out ppTLB, out pIndex); _comTypeLibrary = new ComTypeLibrary(ppTLB); } else { throw new InvalidComObjectException(); } } ~ComObject() { Dispose(); } public void Dispose() { try { if (_typeInfo != null) { _typeInfo.ReleaseTypeAttr(_pTypeAttr); } if (_object != null) { Marshal.ReleaseComObject(_object); _object = null; } if (_dispatch != null) { Marshal.ReleaseComObject(_dispatch); _dispatch = null; } } catch { } } public string[] GetPropertyNames() { System.Collections.ArrayList list = new System.Collections.ArrayList(); try { for (int i = 0; i < this.TypeAttr.cFuncs; i++) { IntPtr pFuncDesc = IntPtr.Zero; System.Runtime.InteropServices.ComTypes.FUNCDESC funcDesc; string strName, strDocString, strHelpFile; int dwHelpContext; _typeInfo.GetFuncDesc(i, out pFuncDesc); funcDesc = (System.Runtime.InteropServices.ComTypes.FUNCDESC) Marshal.PtrToStructure(pFuncDesc, typeof(System.Runtime.InteropServices.ComTypes.FUN CDESC)); switch (funcDesc.invkind) { case System.Runtime.InteropServices.ComTypes.INVOKEKIND .INVOKE_PROPERTYGET: _typeInfo.GetDocumentation(funcDesc.memid, out strName, out strDocString, out dwHelpContext, out strHelpFile); list.Add(strName); break; } } } catch (System.Exception ex) { throw ex; } return (string[])list.ToArray(typeof(string)); } public string TypeName { get { return this._typeName; } } public string TypeFullName { get { return this.ComTypeLibrary.Name + "." + this._typeName; } } public string TypeDescription { get { return this._typeDescription; } } public int TypeHelpContext { get { return this._typeHelpContext; } } public string TypeHelpFile { get { return this._typeHelpFile; } } public object WrappedComObject { get { return _dispatch; } } public ComTypeLibrary ComTypeLibrary { get { return _comTypeLibrary; } } public System.Runtime.InteropServices.ComTypes.TYPEATTR TypeAttr { get { return (System.Runtime.InteropServices.ComTypes.TYPEATTR) Marshal.PtrToStructure(_pTypeAttr, typeof(System.Runtime.InteropServices.ComTypes.TYP EATTR)); } } public string TypeVersion { get { string version = String.Empty; try { version = TypeAttr.wMajorVerNum.ToString() + "." + TypeAttr.wMinorVerNum.ToString(); } catch { } return version; } } } } /* ComTypeLibrary.cs */ using System; using System.Collections.Generic; using System.IO; using System.Reflection; using System.Reflection.Emit; using System.Runtime.InteropServices; using System.Runtime.InteropServices.ComTypes; using System.Text; namespace SolidEdgeSpy.InteropServices { public class ComTypeLibrary { private System.Runtime.InteropServices.ComTypes.ITypeLib _typeLib; IntPtr _pTypeLibAttr = IntPtr.Zero; string _Name, _Description, _HelpFile; int _HelpContext; public ComTypeLibrary(System.Runtime.InteropServices.ComT ypes.ITypeLib typeLib) { _typeLib = typeLib; _typeLib.GetLibAttr(out _pTypeLibAttr); _typeLib.GetDocumentation(-1, out _Name, out _Description, out _HelpContext, out _HelpFile); } public string Name { get { return this._Name; } } public string Description { get { return this._Description; } } public int HelpContext { get { return this._HelpContext; } } public string HelpFile { get { return this._HelpFile; } } public System.Runtime.InteropServices.ComTypes.TYPELIBATT R TypeLibAttr { get { return (System.Runtime.InteropServices.ComTypes.TYPELIBAT TR)Marshal.PtrToStructure(_pTypeLibAttr, typeof(System.Runtime.InteropServices.ComTypes.TYP ELIBATTR)); } } public string TypeLibVersion { get { string version = String.Empty; try { version = TypeLibAttr.wMajorVerNum.ToString() + "." + TypeLibAttr.wMinorVerNum.ToString(); } catch { } return version; } } public Version Version { get { return new Version(TypeLibAttr.wMajorVerNum, TypeLibAttr.wMinorVerNum, 0, 0); |
![]() |
| Thread Tools | Search this Thread |
| Display Modes | |
| |