tags:

views:

137

answers:

2

I'm currently automating an application at work using COM, and have an issue where anyone using my application has a problem if the original application is already open when my application runs. I know how to locate the process if it's open, but instead of having to worry about closing it, or working around it, etc., I want to try to use the existing application instead of opening a new one.

This is how I normally start the application in my automation program:

Designer.Application desApp = new Designer.Application();

Now I'm attempting to try and use the handle from an existing application:

Designer.Application desApp = (Designer.Application)((System.Diagnostics.Process.GetProcessesByName("Designer.exe")[0]).Handle)

(I know this doesn't work, since .Handle returns an IntPtr, but I'm using it as an example.)

Is there any way to accomplish this? How do I return a usable object if I know the handle/process?

+1  A: 

You cannot make this work in the client code, it has to be dealt with in the server. The server must call CoRegisterClassObject(), passing REGCLS_MULTIPLEUSE so that multiple clients are allowed to use the single server instance. There is no other mechanism to allow a client to obtain an interface pointer to the Application object.

This is very much by design, the server has to be designed and written to support such usage. It cannot be bolted on later.

Hans Passant
+2  A: 

The COM way of attaching to an existing automation object retrieve the object for the Running Object Table (ROT) http://msdn.microsoft.com/en-us/library/ms695276(VS.85).aspx.

You can use the IRunningObjectTable interface to register your COM objects in the ROT. http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.comtypes.irunningobjecttable.aspx

And use to query the ROT for an existing instance of your object. System.Runtime.InteropServices.Marshal.GetActiveObject for example.

Chris Taylor