Вы должны бросить исключения. Исключения отображаются в HRESULTS платформой, а HRESULT - это стандартный способ возврата ошибок COM-клиентам, так что это путь.
Каждый тип исключения имеет свойство HResult. Когда управляемый код, вызываемый из COM-клиента, генерирует исключение, среда выполнения передает HResult COM-клиенту. Если вам нужны специфичные для приложения коды HRESULT, вы можете создать свои собственные типы исключений и установить свойство Exception.HResult .
Следует отметить, что информация стека вызовов будет потеряна, когда исключение будет выдано COM-клиенту. Поэтому может быть хорошей идеей регистрировать исключения перед распространением на COM-клиент.
Одна техника, которую я иногда использую, заключается в следующем: явная реализация интерфейса ComVisible для COM-клиентов, который регистрирует и перебрасывает исключения. COM-клиенты используют интерфейс ComVisible, который регистрирует исключения перед их распространением. Клиенты .NET используют конкретный класс и, как ожидается, сами примут меры для обработки исключений. Писать немного скучно, но это может пригодиться, когда вы впоследствии решите проблему.
Еще одним преимуществом этого подхода является то, что вы можете иметь API, приспособленный к ограничениям COM для клиентов COM, и более стандартный API для стандартных клиентов .NET. Например, клиенты COM ограничены передачей массивов по ссылке, тогда как передача по ссылке не рекомендуется для клиентов .NET.
Пример:
[
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
}
}
}