0

I already have a native code COM object, and am trying to instantiate it from C#. The Com is registered in DCOM components and in the registry.

This is what I'v try to do:

public static void Main(string[] args)
{
    Type t = Type.GetTypeFromProgID("CaseConsole.Application");

    dynamic app = Activator.CreateInstance(t);
    dynamic c = app.Case;

    c.OpenCase("17-16", 0);
}

If I try to instantiate the com-type then, I get the:

NotImplementedException

The execption is thrown at line:

dynamic c = app.Case;

As I set a breakpoint at this line, I'v looked into "app" and the error was already present

I'v looked in the Type t and it shows: IsCOMObject = true

As VBS it works great:

Dim App
Dim c

Set App = CreateObject ("CaseConsole.Application")
Set c = App.Case

c.OpenCase "17-16", 0

As VB.net it works

Sub Main()
    Dim App
    Dim c

    App = CreateObject("CaseConsole.Application")
    c = App.Case

    c.OpenCase("17-16", 0)
End Sub

but not in C#

For the C# example I looked at the sources from

http://www.codeproject.com/Articles/990/Understanding-Classic-COM-Interoperability-With-NE

https://msdn.microsoft.com/en-us/library/aa645736%28v=vs.71%29.aspx

Equivalent code of CreateObject in C#

My guess is that i must invoke the methods with InvokeMember or a security thing...

Please can you help to get the c# example working?

Update rename case to c but that wasn't the fault.

Community
  • 1
  • 1

2 Answers2

0

Your C# program is subtly different from the VBS and VB.NET programs. The apartment state of the thread that runs this code is different. The exception comes from the proxy, it should be interpreted as "running this code from a worker thread is not supported". Nicely done. Fix:

[STAThread]
public static void Main(string[] args)
{
   // etc..
}

Note the added [STAThread] attribute. It is technically not correct to do this, a console mode app does not provide the correct kind of runtime environment for single-threaded COM objects but if the VB.NET app works then you have little to fear. If you ever notice deadlock then you'll know what to look for. It worked when you used late-binding through InvokeMember because that uses IDispatch and it has a different proxy.

Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536
-1

Great thank you Sami Kuhmonen, the solution was:

object c = t.InvokeMember("Case", BindingFlags.GetProperty, null, app, null);
t.InvokeMember("OpenCase", BindingFlags.InvokeMethod, null, c, new object[] { "17-16", 0 });

so I didn't realized the fact, that "Case" ís a property.

Solved