I have a base library created in VB6 that exposes a standard COM interface that is used in a number of applications.
This also exposed a number of error code constants, used with Err.Raise to indicate certain conditions.
Public Enum IOErrors
IOErrorBase = 45000
IOErrorConnectionFailed
IOErrorAuthFailed
IOErrorNotConnected
IOErrorInvalidPortDirection
IOErrorGettingValue
IOErrorNoValueYet
End Enum
Come on 10 years and we're creating C# objects implementing the same set of interfaces and want to throw exceptions in a way that the calling application will recognise them.
I can only find two relevant classes, Win32Exception and COMException.
Throwing Win32Exception((int)IOErrors.IOErrorConnectionFailed, "Connect failed") passes the message back correctly but the error code is ignored and Err.Number is &H80004005.
Throwing COMException("Connect failed", IOErrors.IOErrorConnectionFailed) results in no error being picked up in the calling application, presumably because the error code is not an HRESULT and is positive, meaning success.
TL;DR How can I throw an exception from C# such that COM interop will translate it into one of the recognised (positive) error codes above?
The "positive" VB style error numbers are translated to HRESULTs with a "FAILURE" severity and a facility of FACILITY_CONTROL/0xA, i.e. 0x800AAFC9.
You can get a suitable HRESULT using:
int HResult = (int)(0x800A0000 | (int)errorCode);
This can then be raised back to the calling process using a plain COMException, or by throwing your own subclass of 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);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With