Search code examples
c#vbacominterop

GetActiveObject() vs. GetObject() -- MK_E_UNAVAILABLE Error


All:

I am having some problems translating some VBA code to C#.

We have a 3rd party app which acts as a local COM server.

In the VBA code we use GetObject() to get a reference to the existing object

e.g.

Set appHandle = GetObject("", ProgId)

this works fine.

I added a reference to the 3rd party app in our c# code, and used Marshal.GetActiveObject() to try and get a reference to a running instance.

e.g.

var appModel = (IAppCoModel)Marshal.GetActiveObject(ProgId);

but I keep getting a MK_E_UNAVAILABLE error.

Creating a new object works fine in the C# code

e.g.

var appModel = new AppCoModel()

this launches the 3rd party app and allows me to communicate with it. It is only grabbing a reference to a running instance that fails.

What I've tried

Different security contexts
VS is running in admin mode, the 3rd party app isn't. I tried running our c# app from the command line (non-admin). Still failing.

Check the ROT contents
(suggested by Marshal.GetActiveObject() throws MK_E_UNAVAILABLE exception in C#)
The 3rd party app doesn't appear in it. Don't know enough COM to be sure that it needs to.

Checked all the Registry entries
Look good (as far as I can see) and they are good enough to create and instance of the 3rd party app and for the VBA to find it. Anything specific that I should check here?

Any suggestions that people can make would be appreciated.


Solution

  • All:

    Not too sure what the etiquette for closing one's own question is but since I found the answer I would like to some way mark it as 'not needing an answer'.

    The reason that GetActiveObject() returns MK_E_UNAVAILABLE is that the 3rd party app is not registered as an automation server. It is not possible to get a reference to the running instance.

    This didn't show in the VBA code because:

    1. GetObject("",ProgID) creates a new instance each time ( http://msdn.microsoft.com/en-us/library/gg251785.aspx )

    2. The COM exposed functionality in the 3rd party app launches the app if it is not running. So in the VBA we are creating multiple objects all pointing at the same running app rather than attaching to the running app.