È necessario inviare Eccezioni. Le eccezioni sono mappate in HRESULTS dal Framework e HRESULT sono il modo standard per restituire errori ai client COM, quindi questa è la strada da percorrere.
Ogni tipo di eccezione ha una proprietà HResult. Quando il codice gestito richiamato da un client COM genera un'eccezione, il runtime passa HResult al client COM. Se si desidera utilizzare codici HRESULT specifici dell'applicazione, è possibile creare i propri tipi di eccezioni personalizzati e impostare la proprietà Exception.HResult.
Un punto da notare è che le informazioni sullo stack di chiamata andranno perse quando un'eccezione viene lanciata a un client COM. Può quindi essere una buona idea registrare le eccezioni prima di propagare al client COM.
Una tecnica che a volte utilizzo è la seguente: implementare esplicitamente un'interfaccia ComVisible per i client COM che registra e rilancia le eccezioni. I client COM utilizzano l'interfaccia ComVisible che registra le eccezioni prima di propagarle. I client .NET utilizzano la classe concreta e sono tenuti a predisporre i propri arrangiamenti per la gestione delle eccezioni. È un po 'prolisso scrivere ma può essere utile quando successivamente si risolvono i problemi.
Un altro vantaggio di questo approccio è che è possibile avere un'API adattata alle restrizioni di COM per i client COM e un'API più standard per i client .NET standard. Ad esempio, i client COM sono limitati al passaggio di matrici per riferimento, mentre il passaggio per riferimento è scoraggiato per i client .NET.
Esempio:
[
ComVisible(true),
GuidAttribute("..."),
Description("...")
]
public interface IMyComVisibleClass
{
// Text from the Description attribute will be exported to the COM type library.
[Description("...")]
MyResult MyMethod(...);
[Description("...")]
MyOtherResult MyArrayMethod([In] ref int[] ids,...);
}
...
[
ComVisible(true),
GuidAttribute("..."),
ProgId("..."),
ClassInterface(ClassInterfaceType.None),
Description("...")
]
public class MyComVisibleClass : IMyComVisibleClass
{
public MyResult MyMethod(...)
{
... implementation without exception handling ...
}
public MyOtherResult MyArrayMethod(int[] ids,...)
{
... input parameter does not use ref keyword for .NET clients ...
... implementation without exception handling ...
}
MyResult IMyComVisibleClass.MyMethod(...)
{
// intended for COM clients only
try
{
return this.MyMethod(...);
}
catch(Exception ex)
{
... log exception ...
throw; // Optionally wrap in a custom exception type
}
}
MyOtherResult IMyComVisibleClass.MyArrayMethod(ref int[] ids, ...)
{
// intended for COM clients only
try
{
// Array is passed without ref keyword
return this.MyArrayMethod(ids, ...);
}
catch(Exception ex)
{
... log exception ...
throw; // Optionally wrap in a custom exception type
}
}
}
eccezioni sono mappati HRESULTS, quindi questo è l'approccio migliore. Vedi la mia risposta qui sotto. – Joe