Open arknu opened 3 years ago
Tagging subscribers to this area: @vitek-karas, @agocke See info in area-owners.md if you want to be subscribed.
Author: | arknu |
---|---|
Assignees: | - |
Labels: | `area-Host`, `untriaged` |
Milestone: | - |
/cc: @AaronRobinsonMSFT
@arknu Sorry this is causing issues for your prototyping. This issue isn't specific to COM as it is a .NET Core and .NET 5+ technical limitation - there can only be a single instance of the .NET runtime loaded at a time in any given process. There are multiple reasons for this that have been discussed in various issues over the years so I won't belabor them here, but the reference issue https://github.com/dotnet/runtime/issues/12018 does contain the most important points.
As far as a work around for COM scenarios, I would recommend looking at an out-of-proc COM solution. We have a sample for this here.
@AaronRobinsonMSFT thanks for the example.
Side question: would it be possible to bundle the .NET Core runtime with the COM dll or somehow place it in a subdirectory and load it from there, so it is not necessary to rely on a separate installation? I have only found documentation for EXE so far but not something applicable for out-of-proc COM. If there is no built-in way is there an equivalent of metahost->CLRCreateInstance, metahost->EnumerateInstalledRuntimes or metahost->GetRuntimes in .NET Core?
You can do custom hosting: https://docs.microsoft.com/en-us/dotnet/core/tutorials/netcore-hosting
The comhost
is using those same APIs - but I don't think we publicly documented all of the entry points it's using on the runtime side.
In .NET6 we've added a new API to hostfxr
to enumerate installed runtimes: PR and the issue with design.
For Excel-DNA we've taken the approach to support only .NET 6.0 (in addition to .NET Framework 4.x) for in-process Excel add-ins. So far this seems to work fine, and in our experience is working fine when loaded alongside .NET Framework 4.x as well. If another version of .NET Core is loaded already by some independent component or add-in (say targeting .NET 5 or .NET 7), then loading the Excel-DNA add-in will fail. These add-ins are a combination of native .dll exports and COM interop, using a custom runtime host. I think that's fine and seems like a stable plan for the duration of the long-term support window of .NET 6.
In the future - say in the .NET 8 timeframe - we might try to take a Native AOT / DNNE approach to making the add-ins. Is the intention that Native AOT libraries based on .NET 8 would be able to load into the same process where .NET 6 runs (and the .NET Framework 4.x also runs)? I hope so @AaronRobinsonMSFT :-)
Is the intention that Native AOT libraries based on .NET 8 would be able to load into the same process where .NET 6 runs (and the .NET Framework 4.x also runs)?
That is a good question. My guess is it will work fine, but diagnostics will be very bad for the Native AOT portion. Unclear if this will be a supported scenario or not, but I don't see why it would be any worse.
/cc @agocke @jkotas
cc @MichalStrehovsky
I don't think there are any known issues with loading multiple NativeAOT libraries into the app, although each will be a fully independent process with its own GC space. I don't know what the debugging experience would be like for multiple NativeAOT libraries. The NativeAOT debugging experience is mostly a native (C++) debugging experience, so it may have little difference.
The diagnostics will be the same as Native AOT in general - on a high level: stack, stepping, breakpoints work, local variable inspection works. Properties don't show up (one has to look at backing fields), async debugging doesn't work, the names of types are mangled, but human-readable.
I think the bigger problem is that Native AOT has no built-in COM support. It's possible to do COM manually through function pointers, but it's not pretty.
My guess is it will work fine, but diagnostics will be very bad for the Native AOT portion
I would reserve the term "very bad" to how it would be with two CoreCLR's in the same process, where at least for one of them there would likely be no stack, no locals, no source breakpoints, and stepping only on assembly-level.
I think the bigger problem is that Native AOT has no built-in COM support. It's possible to do COM manually through function pointers, but it's not pretty.
Am I correct that this is covered by the COM source generator proposal? https://github.com/dotnet/runtime/blob/main/docs/design/features/source-generator-com.md
@govert Yes, that is how COM interop would be supported. The underlying ComWrappers
API is at least partially supported on Native AOT.
I would reserve the term "very bad" to how it would be with two CoreCLR's in the same process, where at least for one of them there would likely be no stack, no locals, no source breakpoints, and stepping only on assembly-level.
I think that is a rather narrow interpretation. It would be bad in the sense that the managed debugging experience wouldn't exist at all. One would need to "attach" and guess for which .NET version it was attached to (.NET FX vs .NET Core), but far more unintuitive is the user would then need to reattach in native (perhaps mixed?) to get their AOT'd managed code. It is just bad all around and will likely be rather confusing.
I just hit this too after migrating some projects from .NET Framework. Unfortunately, there doesn't seem to be any warnings in the documentation, as this is a pretty major caveat!
https://learn.microsoft.com/en-us/dotnet/core/native-interop/expose-components-to-com
It would be great if there were some option for EnableComHosting
that worked out-of-process by default
Description
I'm currently doing a proof-of-concept of using .NET 5+ COM hosting to create an Office (in this case Outlook) addin. See https://github.com/dotnet/winforms/issues/4370 for further details.
As part of testing with both .NET 5 and .NET 6 preview, it emerged that COM hosting apparently can only support loading one version of .NET at a time. This effectively makes COM hosting useless for a lot of scenarios since you cannot control what else happens to be loaded in the hosting process.
I was also under the impression that the new .NET was supposed to solve the side-by-side issues suffered by .NET Framework, so I'm disappointed to see that this has not been solved. I'm aware of the discussion in https://github.com/dotnet/runtime/issues/12018, but I believe this need to be re-assessed. With .NET Framework all 4.x versions could essentially co-exist, so this was less of an issue. But with the much more frequent release cycles of the new .NET, this issue is going to become a lot more common in the future.
At least when doing COM hosting, .NET should be able to handle multiple version co-existing at the same time. Otherwise, having support for COM hosting is basically useless.
Potentially, these APIs could then be utilized to make hosting multiple .NET versions in other scenarios possible.
Configuration
.NET 5 and .NET 6 preview 2