im working with IPC (ROT) and COM interops. I will try to descripte my issue in few points:
- there are two c# applications called ComServer and ComClient
- ComServer creates an COM interop object and register this to ROT. Just a static Main method marked as STAThread
- ComClient get the COM object from ROT and start working with the object remotely. Also as a simple static Main method marked as STAThread.
Everything working fine till the COM object try to throw a COMException. The problem is instead of a COMException the ComClient thrown an InvalidCastException (Interface not supported (Exception from HRESULT: 0x80004002 (E_NOINTERFACE)). I know there must be something with wrong threading model. Both apps running as STA but why i get this exception?
If i just create the COM instance in my ComClient application i get he right COMException. Only if the COM object is comming from ROT i get this InvalisCastException.
Important point: my COM interop is not registered! i working with side-by-side manifest files and the threading model of the interop is "Apartment".
ComServer:
[STAThread]
static void Main(string[] args)
{
object obj = Activator.CreateInstance(Type.GetTypeFromProgID("MyComApi.MyComClass"));
System.Runtime.InteropServices.ComTypes.IRunningObjectTable pROT = null;
NativeMethods.NativeMethods.GetRunningObjectTable((uint)0, out pROT);
System.Runtime.InteropServices.ComTypes.IMoniker pMoniker = null;
NativeMethods.NativeMethods.CreateFileMoniker("MYCOMCLASS", out pMoniker);
pROT.Register((int)NativeMethods.NativeMethods.ROTFlags.REGISTRATIONKEEPSALIVE, comObject, pMoniker);
new ManualResetEvent(false).WaitOne();
}
ComClient:
[STAThread]
static void Main(string[] args)
{
MyComApi.MyComClass comobj = (MyComApi.MyComClass)Marshal.BindToMoniker("MYCOMCLASS");
comobj.DoIt();
comobj.DoItWrong(); //<-- InvalidCastException instead of COMException
...
}
ComClient (without getting COM object from ROT:
[STAThread]
static void Main(string[] args)
{
MyComApi.MyComClass comobj = (MyComApi.MyComClass)Activator.CreateInstance(Type.GetTypeFromProgID("MyComApi.MyComClass"));
comobj.DoIt();
comobj.DoItWrong(); //<-- COMException, this is ok!
...
}