Повышение положительных кодов ошибок в стиле VB через COM-взаимодействие с C#

У меня есть базовая библиотека, созданная в VB6, которая предоставляет стандартный COM-интерфейс, который используется в ряде приложений. Это также выявило ряд констант кода ошибки, используемых с Err.Raise для обозначения определенных условий.

Public Enum IOErrors
  IOErrorBase = 45000
  IOErrorConnectionFailed
  IOErrorAuthFailed
  IOErrorNotConnected
  IOErrorInvalidPortDirection
  IOErrorGettingValue
  IOErrorNoValueYet
End Enum

Прошло 10 лет, и мы создаем объекты C#, реализующие один и тот же набор интерфейсов, и хотим генерировать исключения таким образом, чтобы вызывающее приложение могло их распознать.

Я могу найти только два соответствующих класса, Win32Exception и COMException.

Выброс Win32Exception((int)IOErrors.IOErrorConnectionFailed, "Connect failed") передает сообщение обратно правильно, но код ошибки игнорируется, а Err.Number равен &H80004005.

Выброс COMException("Connect failed", IOErrors.IOErrorConnectionFailed) приводит к тому, что вызывающее приложение не обнаруживает ошибку, предположительно потому, что код ошибки не является HRESULT и является положительным, что означает успех.

TL; DR Как я могу создать исключение из C #, чтобы COM-взаимодействие преобразовало его в один из распознанных (положительных) кодов ошибок выше?


person Deanna    schedule 30.09.2015    source источник
comment
Связанный вопрос: Как вернуть положительный код ошибки из ATL в VB6?   -  person Deanna    schedule 05.10.2015


Ответы (1)


«Положительные» номера ошибок в стиле VB преобразуются в HRESULTs с серьезностью «FAILURE» и возможностью FACILITY_CONTROL/0xA, т. е. 0x800AAFC9.

Вы можете получить подходящий HRESULT, используя:

int HResult = (int)(0x800A0000 | (int)errorCode);

Затем это можно вернуть вызывающему процессу с помощью простого COMException или путем создания собственного подкласса COMException:

/// <summary>
/// Exception that returns an ICIO error wrapped in an exception.
/// </summary>
internal class ICIOErrorException : COMException {
    internal ICIOErrorException(ICIO.IOErrors errorCode, string message)
        : base(message) {
        this.HResult = (int)(0x800A0000 | (int)errorCode);
    }
}
person Deanna    schedule 30.09.2015