How to get type of COM object
Solution 1
Add reference to Microsoft.VisualBasic.dll
and then:
Microsoft.VisualBasic.Information.TypeName(someCOMObject)
MSDN reference here.
Solution 2
The accepted answer by Darin requires a dependency to Microsoft.VisualBasic.dll
. If you don't want to have that you can use this simple helper class:
public static class TypeInformation
{
public static string GetTypeName(object comObject)
{
var dispatch = comObject as IDispatch;
if (dispatch == null)
{
return null;
}
var pTypeInfo = dispatch.GetTypeInfo(0, 1033);
string pBstrName;
string pBstrDocString;
int pdwHelpContext;
string pBstrHelpFile;
pTypeInfo.GetDocumentation(
-1,
out pBstrName,
out pBstrDocString,
out pdwHelpContext,
out pBstrHelpFile);
string str = pBstrName;
if (str[0] == 95)
{
// remove leading '_'
str = str.Substring(1);
}
return str;
}
[ComImport]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
[Guid("00020400-0000-0000-C000-000000000046")]
private interface IDispatch
{
int GetTypeInfoCount();
[return: MarshalAs(UnmanagedType.Interface)]
ITypeInfo GetTypeInfo(
[In, MarshalAs(UnmanagedType.U4)] int iTInfo,
[In, MarshalAs(UnmanagedType.U4)] int lcid);
void GetIDsOfNames(
[In] ref Guid riid,
[In, MarshalAs(UnmanagedType.LPArray)] string[] rgszNames,
[In, MarshalAs(UnmanagedType.U4)] int cNames,
[In, MarshalAs(UnmanagedType.U4)] int lcid,
[Out, MarshalAs(UnmanagedType.LPArray)] int[] rgDispId);
}
}
Solution 3
You've basically figured it out. GetType() on a COM object is going to give you System.__ComObject, and you have to try to cast it to something else to see what the object really is.
Admin
Updated on June 03, 2022Comments
-
Admin about 2 years
I am referencing a COM library in Visual Studio, so it has automatically created the corresponding Interop assembly for me. I would like to do a
GetType()
on these com objects, but they always returnSystem.__ComObject
. Querying them for an interface works though:bool isOfType = someComeObject is ISomeComObject; //this works
But what I really want is this to return the actual type of the com object:
Type type = someComeObject.GetType(); //returns System.__ComObject :-(
Does anyone know how to do what I want to do?
-
Admin over 14 yearsHm..is there really no other way? Because I can't test for every possible COM object in existing, I just want the type. The reason is that I am using the type of an object as a key in a dictionary...
-
Admin over 14 yearsI just tried this and it works! It does not return the full name though, just the class name, but that's ok for my purposes. I looked at this method in reflector which internally calls 'LegacyTypeNameOfCOMObject' but I can't figure out what it actually does.
-
Admin over 14 yearsI wish there was something that could give me the full name of that com object to avoid clashes.
-
AxA over 14 yearsThanks. Any idea if this is possible in C#?
-
Darin Dimitrov over 14 years
Microsoft.VisualBasic.dll
is a .NET assembly which can be referenced and used in every application. -
AxA over 14 yearsWatch out if you have COM component written in C++/ATL. You might get a different result than you expect.
-
Żubrówka almost 12 yearsExactly what I was looking for. Thanks!
-
catfood almost 12 yearsDarin Dimitrov's solution is great.
-
nawfal over 10 years
someCOMObject as type
? Not sure if that would work. -
Mike over 9 years
-
Robert Synoradzki over 7 yearsBecause it doesn't.
-
ErrCode over 6 yearsThis seems to work too - just need to ensure there is a reference to
System.Runtime.InteropServices.ComTypes
forITypeInfo
(Visual Studio IDE auto-suggestedMicrosoft.VisualStudio.OLE.Interop.ITypeInfo
, but this is not the one you want!) -
pwhty about 6 years@nawfal: why not? It's trying to cast "someCOMObject" to the type "type". If it fails (and only then), the result is null. If it doesn't, then it found the correct type. (I know, it took me a few days to come up with that answer :-P)
-
nawfal about 6 years@pwhty
type
is not a type/class in your code, it is an instance of a type.as
keyword works on a type -
Zev Spitz over 3 yearsIs there any way to use this to get the library of the COM object? I have an object from the Word object model for which
TypeName
returnsShape
, but I cannot cast it toWord.Shape
source in VBA. -
brinkdinges over 2 yearsAs @rpattabi mentions, this doesn't always work. In my case, it just returns "_ComObject".