Skip to content
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

COM hosting breaks with multiple versions of .NET being loaded #49686

Open
arknu opened this issue Mar 16, 2021 · 12 comments
Open

COM hosting breaks with multiple versions of .NET being loaded #49686

arknu opened this issue Mar 16, 2021 · 12 comments
Milestone

Comments

@arknu
Copy link

arknu commented Mar 16, 2021

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 dotnet/winforms#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 #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

@dotnet-issue-labeler dotnet-issue-labeler bot added area-Host untriaged New issue has not been triaged by the area owner labels Mar 16, 2021
@ghost
Copy link

ghost commented Mar 16, 2021

Tagging subscribers to this area: @vitek-karas, @agocke
See info in area-owners.md if you want to be subscribed.

Issue Details

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 dotnet/winforms#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 #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.

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

Author: arknu
Assignees: -
Labels:

area-Host, untriaged

Milestone: -

@RussKie
Copy link
Member

RussKie commented Mar 29, 2021

/cc: @AaronRobinsonMSFT

@AaronRobinsonMSFT
Copy link
Member

@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 #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.

@1R053
Copy link

1R053 commented Mar 29, 2021

@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?

@vitek-karas
Copy link
Member

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.

@vitek-karas vitek-karas added this to the Future milestone Jul 9, 2021
@vitek-karas vitek-karas removed the untriaged New issue has not been triaged by the area owner label Jul 9, 2021
@govert
Copy link
Contributor

govert commented Jun 24, 2022

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 :-)

@AaronRobinsonMSFT
Copy link
Member

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

@agocke
Copy link
Member

agocke commented Jun 24, 2022

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.

@MichalStrehovsky
Copy link
Member

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.

@govert
Copy link
Contributor

govert commented Jun 27, 2022

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

@AaronRobinsonMSFT
Copy link
Member

@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.

@jeremy-visionaid
Copy link

jeremy-visionaid commented May 15, 2024

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: No status
Development

No branches or pull requests

9 participants