We have .NET code libraries we'd like to change from full .NET to .NET standard so we can share them across multiple platforms. However, that .NET code is also used by legacy systems via COM. At the moment the code runs fine in .NET Standard, but there's no Make Assembly COM-Visible checkbox for a .NET Standard project, so there's no way that I can see to make those libraries consumable via COM?
I appreciate the idea of having very platform specific COM stuff in .NET Standard is a total contradiction, but as it only requires some interfaces in the actual code, i.e. it's not referencing things that wouldn't be available on some platforms, it seems like it could be possible?
At the moment the example from the C# docs does compile in .NET Standard 1.6, but gives the warning
'ComInterfaceType.InterfaceIsIDispatch' is obsolete: 'Support for IDispatch may be unavailable in future releases.'
But this github issue seems to question whether it should be marked obsolete?
So, is COM definitely out with .NET Standard?
Hi, how would you share an assembly that uses COM with Mono on Linux? (reminder: Mono implements .NET standard and runs on other platforms than Windows :wink: )
Hi @picrap, I'm not talking about using COM though, I'm talking about making my assembly available to be used by COM? My grasp of COM is not great, so I'm quite possibly misunderstanding all of this.
PS: I've reworded the question a bit, sorry, it wasn't massively clear what I was asking.
you could 'wrap' the standard library by referencing it from a netfx library which is com-visible
@yizhang82 Any input here?
My guess is that whatever facilities the CLR has for COM support don't really care if your library is compiled as a netfx or netstandard library. I'm really not familiar with this part of the runtime, though; others should chip in.
COM is definitely in with .NET Standard.
There's nothing precluding it, since .NET Standard is a standard and not a runtime. As long as a runtime that implements .NET Standard also implements COM visibility, a .NET Standard library can be made COM visible.
I threw together an example using Visual Studio 2017 and WiX here: ComVisibleNetStandard
I never really trusted Visual Studio with COM visibility, anyways, and have always preferred bona fide installers made with WiX. Let me know if you need more info. Nailing down this process was not trivial, but we use it extensively at work to interop .NET and VB6 apps.
@kyourek that's really helpful, many thanks, it's great to know it's possible via WiX.
If possible I'd avoid switching to a different installer because this is an old legacy system and most of our work is now delivered as web apps, so it's not really a skill set we need, but if this gets it going then perhaps WiX is the way forward.
cc @jeffschwMSFT
@tomRedux I'm entirely sure what you are asking from the original issue. Are you asking for the check-box in VS to mark a .NET Standard library you are building as ComVisible? I could be wrong but I suspect that simply adds some assembly level attributes that you should be able to do manually even if the tooling doesn't allow it.
@weshaggard originally I was just asking whether there was a fundamental reason that meant it wouldn't be possible, which it sounds like there isn't. So, if it's OK for a .NET Standard assembly to be COM-Visible then what would be really useful is to know how to achieve that.
A check-box in VS would make it consistent with the existing full .NET experience, but in the short term if it is just a case of adding assembly level attributes then an explanation of how to do that would be really useful.
Have a read over https://stackoverflow.com/questions/3699767/register-for-com-interop-vs-make-assembly-com-visible. If all you want to do is make something COM visible just add the ComVisible attribute, ideally to the type but it could be the entire assembly as well. If you want to register it there is an extra step that needs to happen.
I have a similar issue here. I have a COM service implemented in .NET full framework, but it doesn't seem to function properly in UWP apps (clr.dll was not loaded). See this Stackoverflow question: https://stackoverflow.com/questions/50660726/clr-cannot-create-net-based-com-objects-in-uwp
As an alternative, I am trying to use .NET Core and CoreRT to generate a native DLL that implements the same COM interface, so that the CLR doesn't need to be loaded at runtime. I am not sure whether this will work.
You should be able to annotate your types so that they are COM visible with .NET Standard. However, you won't be able to easily activate a COM component written in .NET Standard as tooling doesn't support this. But they same applies to .NET Core today. In that sense, I don't think is an area worth exploring for .NET Standard yet unless .NET Core has full support for this (because otherwise you're better off simply creating a .NET Framework COM component anyways).
FWIW, in .NET Core 3.0 we are adding support for .NET COM Servers. So as long as the comvisible and guid attribute are part of .NET Standard, there should not be a reason this scenario would not work. We plan on having the tooling support for this in Preview 4.
Excellent! Thanks @jeffschwMSFT.
@jeffschwMSFT Great! Would that be "In process" or "Out of process" .NET COM servers?
.NET Core .NET COM servers behavior much more similar to navtive COM servers: for instance, can use reg free registration (without custom manifest nodes), use regsvr32, etc. We are just finishing up the design time experience and we will ensure to create samples for all the supported scenarios.
cc @AaronRobinsonMSFT
Would that be "In process" or "Out of process" .NET COM servers?
@ztl8702 At present this would only be for "In process". See https://github.com/dotnet/core-setup/blob/master/Documentation/design-docs/COM-activation.md for more details.
@AaronRobinsonMSFT Actually, in-process is great, because some use-cases can only utilize in-process COM servers. Like the TSF text service I mentioned above, where the COM server is activated by mstsf.dll with a CLSCTX_INPROC_SERVER context.
@jeffschwMSFT Did the samples you mentioned get into Preview 4?
@danharlin Sorry to say, but I haven't had time to get out a sample for this. I will try over the next few days.
The trick for this is to use a 3.0 release (preview 4+) and add the <UseComHost>True</UseComHost> property to your class library project. The result with contain a customized *.comhost.dll along with *.runtimeconfig.json files that define the .NET framework to use if one is not already loaded in process. Additional details are in https://github.com/dotnet/core-setup/blob/master/Documentation/design-docs/COM-activation.md#net-core-class-com-activation. There is a bug in preview 4 that will make consumption of a managed COM server from a managed COM client impossible. However, consumption of a managed COM server will work as expected from a native client. Preview 5 will have the fix for managed COM client consuming a managed COM server.
Thanks, @AaronRobinsonMSFT
Is there any documentation on making .net standard com visible? Ialso asked on Stack Overflow
@kgreed This has been asked a few times, but alas I can't see to find where I wrote the response. Let me summarize here how people should think about this.
The linked Stack Overflow describes the results very well. Compiling a .NET Standard 2.0 project will never produce a COM host for important technical reasons. The purpose of a .NET Standard 2.0 project is to produce a library that is consumable by any runtime that supports .NET Standard 2.0. .NET Framework 4.6.1 as well as Mono supports .NET Standard 2.0. COM is tightly coupled with Windows and a .NET runtime's implementation, so support for a .NET Standard library to be a COM server can't be satisfied unless the target runtime is known.
Most helpful comment
FWIW, in .NET Core 3.0 we are adding support for .NET COM Servers. So as long as the comvisible and guid attribute are part of .NET Standard, there should not be a reason this scenario would not work. We plan on having the tooling support for this in Preview 4.