4

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.

Community
  • 1
  • 1
AlanT
  • 3,627
  • 20
  • 28

1 Answers1

6

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.

Toby Allen
  • 10,997
  • 11
  • 73
  • 124
AlanT
  • 3,627
  • 20
  • 28
  • It is perfectly ok to answer your own question and mark it as the answer and is encouraged. – Toby Allen Jun 13 '12 at 13:51
  • What C# code did you use to replace your GetActiveObject call? (I'm having a similar problem, and want to find the C# equivalent of the VB `GetObject(,Name)`. I need a GetOrCreateCOMObject kind of interface, I think. – Kevin Jan 04 '21 at 23:23
  • @Kevin, truthfully, at this remove, I can't remember all that much about it. I *think* that the problem was that we were expecting the program to act like Excel where, if there is an instance of Excel running, we could attach to it by getting the instance from the ROT and the legacy VBA seemed to do it but the C# was failing. I think that once we found that the VBA was not finding it in the ROT (just not telling us) that we were fine with creating a new instance Sorry that I can't be of more help. – AlanT Jan 05 '21 at 21:07
  • No problem, thank you. I will continue to research the issue. There must be a way in C#! – Kevin Jan 06 '21 at 07:53