Accessing a COM object through a Windows process handle
I am currently automating an application at work using COM and have a problem where anyone using my application has a problem if the original application is already open when my application is running. I know how to find a process if it opens, but instead of worrying about closing it or bypassing it, etc., I want to try and use an existing application instead of opening a new one.
This is how I usually run the application in my automation program:
Designer.Application desApp = new Designer.Application();
Now I am trying to use a handle from an existing application:
Designer.Application desApp = (Designer.Application)((System.Diagnostics.Process.GetProcessesByName("Designer.exe")[0]).Handle)
(I know this doesn't work as it .Handle
returns IntPtr
, but I'm using it as an example.)
Is there a way to do this? How do I return a usable object if I know the handle / process?
a source to share
The COM method of binding to an existing automation object returns an object for the desktop table (ROT) http://msdn.microsoft.com/en-us/library/ms695276(VS.85).aspx .
You can use the IRunningObjectTable interface to register COM objects with the ROT. http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.comtypes.irunningobjecttable.aspx
And use to request ROT for an existing instance of your object. For example, System.Runtime.InteropServices.Marshal.GetActiveObject.
a source to share
You cannot do this work in client code, it needs to be solved on the server. The server must call CoRegisterClassObject () passing in REGCLS_MULTIPLEUSE to allow multiple clients to use the same server instance. There is no other mechanism for the client to obtain an interface pointer to the Application object.
It is very much by design, the server must be designed and written to support this use. It cannot be pinned later.
a source to share