Skip to content

Invoke members for dispatch interfaces on that interface's corresponding IDispatch pointer, not on the canonical one - #122200

Merged
jkoritzinsky merged 2 commits into
dotnet:mainfrom
jkoritzinsky:specific-idispatch
Dec 5, 2025
Merged

Invoke members for dispatch interfaces on that interface's corresponding IDispatch pointer, not on the canonical one#122200
jkoritzinsky merged 2 commits into
dotnet:mainfrom
jkoritzinsky:specific-idispatch

Conversation

@jkoritzinsky

@jkoritzinskyjkoritzinsky commented Dec 4, 2025

Copy link
Copy Markdown
Member

We need to invoke the method on the exact IDispatch pointer that's returned to ensure that members on that dispatch interface will be resolved. The default IDispatch pointer will only resolve members for its corresponding interface.

Fixes#122175

Regression introduced in #104406

Test helper code adapted from #122195 (can be consolidated in the future).

…ing IDispatch pointer, not on the canonical one
@dotnet-policy-service

Copy link
Copy Markdown
Contributor

Tagging subscribers to this area: @dotnet/interop-contrib
See info in area-owners.md if you want to be subscribed.

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes a bug where dispatch interface members were being invoked on the canonical IDispatch pointer instead of the interface-specific IDispatch pointer. This caused issues when a .NET object with a custom default interface (via ComDefaultInterfaceAttribute) exposed multiple IDispatch interfaces - only the default interface's members were resolvable.

Key changes:

  • Modified COM interop dispatch invocation to use the interface-specific IDispatch pointer while still validating IDispatch support via QueryInterface
  • Added test infrastructure for in-process COM activation
  • Added test case demonstrating the fix for non-default IDispatch interfaces

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 3 comments.

FileDescription
src/coreclr/vm/interoputil.cppCore fix: extracts and uses interface-specific IDispatch pointer for method invocation instead of canonical pointer
src/tests/Interop/common/ComActivationHelpers.csNew test helper providing COM class registration and activation infrastructure
src/tests/Interop/COM/NETClients/ConsumeNETServer/Program.csAdded test case validating IDispatch invocation on non-default interface, reorganized using directives, renamed TestEntryPoint to ConsumeNETServerTests
src/tests/Interop/COM/NETClients/ConsumeNETServer/ConsumeNETServer.csprojAdded reference to ComActivationHelpers.cs

Comment threadsrc/coreclr/vm/interoputil.cpp Outdated
Comment threadsrc/tests/Interop/common/ComActivationHelpers.cs Outdated
Comment threadsrc/tests/Interop/COM/NETClients/ConsumeNETServer/Program.cs

@AaronRobinsonMSFTAaronRobinsonMSFT left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you! We should also backport this to .NET 10. I don't think it needs to go further back.

Comment threadsrc/tests/Interop/common/ComActivationHelpers.cs Outdated
Comment threadsrc/tests/Interop/common/ComActivationHelpers.cs Outdated
@jkoritzinsky

Copy link
Copy Markdown
MemberAuthor

@AaronRobinsonMSFT any more feedback or is this good to go?

@jkoritzinsky

Copy link
Copy Markdown
MemberAuthor

/backport to release/10.0

@github-actions

Copy link
Copy Markdown
Contributor

Started backporting to release/10.0 (link to workflow run)

@AaronRobinsonMSFTAaronRobinsonMSFT left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you!

@jkoritzinsky
jkoritzinsky merged commit 2c91165 into dotnet:mainDec 5, 2025
101 of 105 checks passed
@jkoritzinsky
jkoritzinsky deleted the specific-idispatch branch December 5, 2025 17:58
steveisok pushed a commit that referenced this pull request Dec 6, 2025
…ce's corresponding IDispatch pointer, not on the canonical one (#122229)
Backport of #122200 to release/10.0
/cc @jkoritzinsky
## Customer Impact
- [X] Customer reported
- [ ] Found internally
[Select one or both of the boxes. Describe how this issue impacts
customers, citing the expected and actual behaviors and scope of the
issue. If customer-reported, provide the issue number.]
Method call on an IDispatch-based ComImport interface fails to call the
target COM method if the target COM object is a .NET object exposed to
COM that uses the ClassDefaultInterfaceAttribute; instead, an exception
is thrown.
## Regression
- [X] Yes
- [ ] No
[If yes, specify when the regression was introduced. Provide the PR or
commit if known.]
Introduced in .NET 9
#104406
## Testing
[How was the fix verified? How was the issue missed previously? What
tests were added?]
Added a unit test to validate the scenario and validated that the repro
no longer fails.
## Risk
[High/Medium/Low. Justify the indication by mentioning how risks were
measured and addressed.]
Low. Reverts the incorrectly functioning part of the regressing PR to
the .NET 8 code path.
**IMPORTANT**: If this backport is for a servicing release, please
verify that:
- For .NET 8 and .NET 9: The PR target branch is `release/X.0-staging`,
not `release/X.0`.
- For .NET 10+: The PR target branch is `release/X.0` (no `-staging`
suffix).
## Package authoring no longer needed in .NET 9
**IMPORTANT**: Starting with .NET 9, you no longer need to edit a NuGet
package's csproj to enable building and bump the version.
Keep in mind that we still need package authoring in .NET 8 and older
versions.
---------
Co-authored-by: Jeremy Koritzinsky <jekoritz@microsoft.com>
@github-actionsgithub-actionsBot locked and limited conversation to collaborators Jan 5, 2026
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

DISP_E_UNKNOWNNAME for non-default interface members

3 participants

@jkoritzinsky@AaronRobinsonMSFT