-
Notifications
You must be signed in to change notification settings - Fork 4.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Invoking method of .NET 5 COM object (inproc server) from .NET 5 client app using the 'dynamic' keyword throws 'NotSupportedException' #47329
Comments
I later debugged the CoreCLR with the The code that returns the runtime/src/coreclr/vm/stdinterfaces.cpp Lines 553 to 556 in 01116d4
When I just skip the check, my type lib gets loaded successfully and my method gets successfully invoked dynamically as well. To not manually keep skipping the check, I now added the ImportedFromTypeLibAttribute to my [assembly: Guid(ContractGuids.TypeLibrary)]
[assembly: ImportedFromTypeLib("COMServer.tlb")] // <-- added So the project version, where I let a type library being generated from an IDL file via MIDL.exe, manually register it in a However, discovering the |
@lauxjpn Thank you for the analysis. This is annoying and we should fix this. I believe all that would be needed is removing the following. runtime/src/coreclr/vm/stdinterfaces.cpp Lines 553 to 556 in 004eb75
I don't believe we could get this through .NET 5 servicing given there is a workaround. Would a .NET 6+ fix be acceptable for you? |
I think its fine, as long as the impact of using (or not using) the
It might also be a good idea to add a dynamic call to the COMServerDemo. While this would also apply to in-proc COM servers, this sample is the only one that demonstrates an approach to build a type library, and it should be good enough to extend it with a bit of code and comments for context. Finally, in the spirit of James Newton-King's recent tweet, it's definitely a good idea to make the exception message more explicit:
What's the reasoning (e.g. guidelines) or possible risk for implementing this as a feature in .NET 6 instead of as a bugfix in .NET 5, or is it about consistency within a major release? |
Risk, always risk. In this case there is a reasonable workaround (i.e. no one is technically blocked) and it isn't worth even the remote possibility of causing issues in some other non-obvious scenario. |
@AaronRobinsonMSFT Thanks for clarifying. In that case, making the exception message more explicit will not be an option for now, because there might exist obscure cases, where apps explicitly check for the current behavior and not (or not only) use the exception type for that, but its message. |
Dynamic support for COM objects has been added in .NET 5 (see #12587).
However, I am unable call methods of a .NET 5 COM class (inproc server) from a .NET 5 client app using the
dynamic
keyword.I used the COM Server Demo sample as a base and altered it in a way that I would expect to work when invoked dynamically.
The
COMClient\WscriptClient.js
script executes correctly and demonstrates, thatIDispatch
is implemented by the CCW and works as expected:The script is simple:
However, when running the
COMClient.exe
, I get the following exception when dynamically invoking theComputePi()
method:Full stack trace
The script is simple as well:
According to the full stack trace, the exception is being thrown in
ComRuntimeHelpers.GetITypeInfoFromIDispatch()
, where it is being thrown for theHRESULT
ofdispatch.TryGetTypeInfoCount(out uint typeCount)
.This might be a bug. The remarks section states:
The docs at COM Callable Wrapper: Simulating COM interfaces state, that
ITypeInfo
is not implemented by the CCW for .NET Core:Which might be indirectly backed up by #3740.
However, if a scripting host like WScript is able to dynamically call a dual interface via
IDispatch
, I would expect the same to be true for a .NET 5 client (at least for common cases).I also created another project version, that explicitly generates a type library from an IDL file using the MIDL.exe tool (I changed the GUIDs for this project version).
Contract.idl
When the COM class is registered, the project also registers the type library (via
[ComRegisterFunction]
).When my
Server
COM class is instantiated, I load the type library and retrieve the defaultITypeInfo
interface (provided by the type library parser) in the class constructor (see Essential COM page 353 by @donbox):My
Server
COM class explicitly implementsITypeInfo
and forwards all calls to the retrieved default implementation. According to COM Callable Wrapper: Simulating COM interfaces, my explicitITypeInfo
implementation should be honored:The COMClient project demonstrates, that the type information is available via the interface, but the internal
ComRuntimeHelpers.GetITypeInfoFromIDispatch()
call by .NET when dynamically invokingComputePi()
throws the sameNotSupportedException
as before:The text was updated successfully, but these errors were encountered: