通过与c#的COM互操作提高VB风格的正面错误码

本文关键字:VB 风格 误码 错误 COM 互操作 | 更新日期: 2023-09-27 18:15:13

我有一个在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并且是正的,意味着成功。

TL,博士我如何从c#抛出异常,使COM互操作将其转换为上述可识别的(积极的)错误代码之一?

通过与c#的COM互操作提高VB风格的正面错误码

VB风格的"正面"错误编号被转换为具有"FAILURE"严重性和FACILITY_CONTROL/0xA设施的HRESULT s,即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);
    }
}