Search code examples
c#com-interop

Get value from System.__Object in C#


I have a vendor specific COM interface. Intellisense shows properties while writing; thus I write something like

App.Element.Car.seats

which is somehow known to Visual Studio. In the autocomplete window, these elements are shown as properties of App, which is the COM interface to the external application. Does Visual Studio somehow read the methods and properites that are available in the dll / library?

However, call returns System.__Object, but it should be a number of some type. I do not have any documentation to the COM interface; thus I have to work just with the dll. Is there any way to get the correct type and retrieve the actual value that is contained somehow in seats?

In VB, this notation does work, but I must use C#.


Solution

  • Visual Studio uses metadata to provide IntelliSense for COM objects, and that's how it's able to suggest properties and methods as you type. When a COM component is registered, type information is made available which development environments like Visual Studio can utilize.

    However, when using COM interop from C#, especially with late binding, things can get a bit tricky. If you are accessing a COM object that does not have strongly-typed interop assemblies available (or if you are using late binding for some other reason), the result will often be a generic System.__ComObject, which does not provide much type information in C#.

    I will recommend you use Type Libraries: If the COM component comes with a type library (.tlb file), you can import this into your C# project using the tlbimp.exe tool which comes with Visual Studio. This will generate a .NET interop assembly which provides strongly-typed classes for interacting with the COM component.

    Or

    Use dynamic: Starting from C# 4.0, you can use the dynamic keyword which effectively provides late binding in C#. This allows you to work with COM objects in a more VB-like manner:

    dynamic app = GetComObject(); // Or however you get your COM object
    var seats = app.Element.Car.seats;