通过 C# 的 COM 互操作引发正 VB 样式错误代码

Raise positive VB style error codes via COM interop from C#

我有一个在 VB6 中创建的基础库,它公开了在许多应用程序中使用的标准 COM 接口。 这也暴露了一些错误代码常量,与 Err.Raise 一起用于指示某些条件。

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

10 年过去了,我们正在创建实现同一组接口的 C# 对象,并希望以调用应用程序能够识别它们的方式抛出异常。

我只能找到两个相关的 类、Win32ExceptionCOMException

抛出 Win32Exception((int)IOErrors.IOErrorConnectionFailed, "Connect failed") 正确传回消息但错误代码被忽略并且 Err.Number&H80004005.

抛出 COMException("Connect failed", IOErrors.IOErrorConnectionFailed) 导致在调用应用程序中没有发现错误,大概是因为错误代码不是 HRESULT 并且是正数,表示成功。

长话短说;博士 我怎样才能从 C# 中抛出异常,以便 COM 互操作将其转换为上面识别的(正)错误代码之一?

"positive" 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);
    }
}