views:

373

answers:

3

I am consuming a cpp COM object from c# code. My c# code looks like this:

try
{
   var res = myComServer.GetSomething();
}
catch (Exception e) { }

However the exception never contains any of the details I set in cpp, in particular my error message.

In my cpp side I have followed several examples I have found on the web:

...
ICreateErrorInfo *pcerrinfo;    
IErrorInfo *perrinfo;    
HRESULT hr;    
hr = CreateErrorInfo(&pcerrinfo);    
pcerrinfo->SetDescription(L"C++ Exception");    
hr = pcerrinfo->QueryInterface(IID_IErrorInfo, (LPVOID FAR*) &perrinfo);  
if (SUCCEEDED(hr))    
{  
  SetErrorInfo(0, perrinfo);  
  perrinfo->Release();    
}  

pcerrinfo->Release();    
return E_FAIL;  // E_FAIL or other appropriate failure code  
...

Am I missing anything? Is there anything else that could affect this, like marshaling, the interop creation or attributes of the com server itself?

A: 

Instead of catching the Exception type, catch COMException type like this ...

try
{
  // COM call
} 
catch( COMException cEx )
{
  // Check HRESULT here
}
JP Alioto
As COMException is derived from System.Exception this makes no difference with regards to the exception details. It's just a more specific filter.
0xA3
The child class has more information than the base class. Relevant information to COM exceptions. I don't understand your point at all.
JP Alioto
COMException (or more precise its base ExternalException) has only one additional member which is ErrorCode. This member contains the HRESULT of the error. The HRESULT however will also be included in the Message and HResult properties of System.Exception.
0xA3
You're right. I thought COMException used something other than System.Exception.Message, but it does not. I stand corrected.
JP Alioto
+6  A: 

Does your COM class support ISupportErrorInfo ?

Remus Rusanu
+1 That's an interesting guess. I can see how examples in the web might focus on the details and neglect to mention that you need to mark your class with ISupportErrorInfo.
Euro Micelli
+2  A: 

Assuming that your class does implement ISupportErrorInfo, did you by any chance add the support AFTER you imported the library into your C# project from Visual Studio?

Visual Studio generates the gunk that it needs to talk to a COM library only once, when you import the library. For this purpose, it builds a special translation DLL called "originalDllName.Interop.dll", based on the information available in the TypeLib of the DLL at the time of the import.

You can make implementation changes as often as you want without trouble; but if you changed the library in any way (added new classes, changed the interface definitions, changed the iterfaces implemented by your classes...), you will have to remove the COM DLL from your References, and then re-import it, for the Interop DLL to be refreshed.

Euro Micelli