I have two applications, both of which I have written. AppA was written in C++ using MFC. During startup it registers a CSingleDocTemplate and creates a document. The document provides a COM interface and registers itself in the ROT:
LPUNKNOWN punk = GetInterface(&IID_Welder); // doesn't AddRef ::RegisterActiveObject(punk, CLSID_Interface, ACTIVEOBJECT_WEAK, &m_dwRegister);
AppA revokes the entry in the ROT when it is destroyed:
if (m_dwRegister) ::RevokeActiveObject(m_dwRegister, NULL);
The destructor is only called when AppA terminates.
AppB is written in C# and is a client of the interface provided by AppA:
private void Connect() { welderInterface = (Welder.Interface)Marshal.GetActiveObject("Welder.Interface"); Marshal.GetIUnknownForObject(welderInterface); // AddRef's it ... }(error handling omitted for clarity)private void Disconnect() { if (welderInterface != null) { Marshal.ReleaseComObject(welderInterface); welderInterface = null; } }
That all works perfectly the first time AppB runs after AppA has started; AppB can call Connect
and Disconnect
as often as it wants and use the interface between. However, if AppB terminates and runs again (AppA still running) the interface is no longer available - Marshal.GetActiveObject
throws an exception from MK_E_UNAVAILABLE
. The only way to make the interface available again is to restart AppA - not an acceptable solution!
Please can someone suggest how I might fix this?