-
Couldn't load subscription status.
- Fork 5.2k
Description
Background and motivation
See #116917 for motivating example.
The Marshal.ThrowExceptionForHR() API respects IErrorInfo, but doesn't respect ISupportErrorInfo, which means implementing correct COM semantics isn't possible. The motivation here is for source generated COM. Built-in COM support respects ISupportErrorInfo as expected, but source generated COM can't since no public API exists that has the correct semantics.
API Proposal
A QI for ISupportErrorInfo will be performed on the pUnk. If ISupportErrorInfo is supported, the targetIID will then be passed to ISupportErrorInfo::InterfaceSupportsErrorInfo(). This will effectively allow users to then call GetExceptionForHR(int errorCode, IntPtr errorInfo) with the correct errorInfo value. If the interface doesn't support ISupportErrorInfo or the targetIID isn't supported, the errorInfo is thrown away. Throwing away the errorInfo isn't the expected COM behavior, but is the behavior observed by .NET Framework and built-in COM, therefore it will be followed here and documented. See #117438 (comment) for a proposed implementation. The PR for implementing this API should also replace the existing private API called by built-in COM interop.
namespace System.Runtime.InteropServices;
public static partial class Marshal
{
+ public static void ThrowExceptionForHR(int errorCode, Guid targetIID, IntPtr pUnk);
+ public static Exception? GetExceptionForHR(int errorCode, Guid targetIID, IntPtr pUnk);
}API Usage
From within a source generated COM proxy:
Guid tgtIID = ...
Marshal.ThrowExceptionForHR(errorCode, tgtIID, pUnk);Alternative Designs
No response
Risks
No response
Metadata
Metadata
Assignees
Labels
Type
Projects
Status