通过C#的COM互操作提高正VB样式错误代码
我有一个在VB6中创建的基础库,它公开了一个在许多应用程序中使用的标准COM接口。 这也暴露了许多错误代码常量,与Err.Raise
用于指示某些条件。
Public Enum IOErrors IOErrorBase = 45000 IOErrorConnectionFailed IOErrorAuthFailed IOErrorNotConnected IOErrorInvalidPortDirection IOErrorGettingValue IOErrorNoValueYet End Enum
经过10年,我们正在创建实现相同接口集的C#对象,并希望以调用应用程序识别它们的方式抛出exception。
我只能找到两个相关的类, Win32Exception
和COMException
。
抛出Win32Exception((int)IOErrors.IOErrorConnectionFailed, "Connect failed")
正确传递消息,但忽略错误代码, Err.Number
为&H80004005
。
抛出COMException("Connect failed", IOErrors.IOErrorConnectionFailed)
导致调用应用程序中没有错误被COMException("Connect failed", IOErrors.IOErrorConnectionFailed)
,大概是因为错误代码不是HRESULT
而且是肯定的,这意味着成功。
TL; DR如何从C#中抛出exception,以便COM互操作将其转换为上面的一个已识别(正)错误代码?
“正”VB样式错误号被转换为HRESULT
,具有“FAILURE”严重性和FACILITY_CONTROL
/ 0xA
,即0x800AAFC9
。
您可以使用以下方法获得合适的HRESULT
:
int HResult = (int)(0x800A0000 | (int)errorCode);
然后可以使用普通的COMException
或通过抛出自己的COMException
子类将其提升回调用进程:
/// /// Exception that returns an ICIO error wrapped in an exception. /// internal class ICIOErrorException : COMException { internal ICIOErrorException(ICIO.IOErrors errorCode, string message) : base(message) { this.HResult = (int)(0x800A0000 | (int)errorCode); } }