Skip to content

Apartment threaded IDispatch server throws InvalidOperationException or fails to marshal #94749

Description

@mgaffigan

Description

When implementing an IDispatch apartment threaded object on net7.0, an exception is thrown when calling Marshal.GetIDispatchForObject. Non-.Net callers get E_NOINTERFACE. The same code works on .Net Framework.

This seems to be related to removing [ComVisible(true)] from many types - which is understandable in general, but StandardOleMarshalObject is exclusively used with COM. I would propose that [ComVisible(true)] be re-added to StandardOleMarshalObject, the requirement for [ComVisible(true)] to be reduced, or the need to re-implement StandardOleMarshalObject be documented. In testing, adding the attribute is sufficient to avoid the exception.

Reproduction Steps

Create a new net7.0-windows console program. Add the following to Program.cs:

Marshal.GetIDispatchForObject(new Example());

[ComVisible(true)]
public class Example : StandardOleMarshalObject
{
}

Expected behavior

The example program should not throw an exception (the type will be available to IDispatch callers).

Actual behavior

The following exception is thrown:

System.InvalidOperationException: Type 'DispTarget' has a ComVisible(false) parent
'System.Runtime.InteropServices.StandardOleMarshalObject' in its hierarchy, therefore QueryInterface calls for IDispatch or class interfaces are disallowed.
    at System.Runtime.InteropServices.Marshal.GetIDispatchForObjectNative(Object o)
    at Program.<Main>$(String[] args) in C:\dev\source\repos\ComDispatchDemo\DemoDispatchServer\Program.cs:line 8

If the type is passed to a COM server or registered with CoRegisterClassObject instead of GetIDispatchForObject, no exception is thrown in the server and E_NOINTERFACE is returned the caller.

Regression?

Yes. The same code on net48 runs without issue.

Known Workarounds

Copy/paste the implementation of StandardOleMarshalComObject.cs into the project, and add the [ComVisible(true)] attribute.

Alternately, if the object does not require apartment threading, remove StandardOleMarshalComObject as a base class.

Configuration

dotnet 7.0.401
Windows 11 22H2 (22621.2428)
Reproducible with Platform x86 or x64
Presumed to be applicable to .Net 5..8 and all platforms

Other information

Loosely related: #80422

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    • Status
      No status

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions