The HRESULT
is generally an error code only datum. It is rarely used to convey success; S_FALSE
being the only well defined exception to this. In the case of S_FALSE
, it is often only used when the result type is the COM boolean (VARIANT_BOOL
) and the HRESULT
is mapped to S_FALSE
when the return (out) is VARIANT_FALSE
(and S_OK
when VARIANT_TRUE
).
Wikipedia also talks about the HRESULT
for the case of the error for COM and the .Net/COM boundary (from here);
In the .NET Framework, HRESULT/IErrorInfo error codes are translated into CLR exceptions when transitioning from native to managed code; and CLR exceptions are translated to HRESULT/IErrorInfo error codes when transitioning from managed to native COM code.
Although not conclusive, it certainly does re-enforce the fact that the HRESULT
is generally seen as an error code. Accessing the IErrorInfo
may provide some more data, but I'm not sure it will be as you expect or desire it to be.
This MSDN article does provide more information on how to map COM errors and exceptions, again supporting the error code;
COM methods report errors by returning HRESULTs; .NET methods report them by throwing exceptions. The runtime handles the transition between the two. Each exception class in the .NET Framework maps to an HRESULT.
To support the "success code" you could use an additional [out]
parameter. If the code is outside your control, you could write a thin COM object to map that for you and then use that in the .Net object.
Alternatively, you could use the PreserveSigAttribute
, but as far as I know, it won't translate the errors to exceptions so you will need to do that yourself (a test to verify this is advised). Annotating the method with [PreserveSig]
should do the trick.