我有一个在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,“连接失败”)可以正确传递消息,但错误代码将被忽略,Err.Number为& H80004005.
抛出COMException(“ Connect failed”,IOErrors.IOErrorConnectionFailed)不会导致在调用应用程序中拾取任何错误,大概是因为错误代码不是HRESULT且为正,表示成功.
TL; DR
如何从C#引发异常,以使COM互操作将其转换为上面公认的(正)错误代码之一?
解决方法:
VB样式错误的“正数”将转换为严重性为“ FAILURE”且功能为FACILITY_CONTROL / 0xA(即0x800AAFC9)的HRESULT.
您可以使用以下方法获得合适的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);
}
}