dotnet / msbuild

The Microsoft Build Engine (MSBuild) is the build platform for .NET and Visual Studio.
https://docs.microsoft.com/visualstudio/msbuild/msbuild
MIT License
5.21k stars 1.35k forks source link

Add support for COMReference items on .NET Core #3986

Open AaronRobinsonMSFT opened 5 years ago

AaronRobinsonMSFT commented 5 years ago

Steps to reproduce

The following COM sample doesn't build from the dotnet command. It only builds from within Visual Studio.

Command line

dotnet build ExcelDemo.csproj

Expected behavior

The project should build

Actual behavior

There is a failure to find the ResolveComReferences task.

See dotnet/core#2104 See dotnet/samples#487

dotMorten commented 5 years ago

Any update on this? I'd like to be able to build with COM references using a locally-installed .NET Core SDK without putting a dependency on VS2019.

AaronRobinsonMSFT commented 5 years ago

@dotMorten Just to set expectations and I will let @rainersigwald have the final say, but I am doubtful including full COM build support outside MSBuild will happen in the near future. There are too many dependencies between COM and Windows to reconcile in a reasonable way and since one of the primary goals of .NET Core SDK is to be as platform agnostic as possible, this tight coupling violates that principle. As I mentioned, @rainersigwald can comment better on how much work this would be and when it might occur, but I would be very surprised if this occurred in the .NET 3.0 timeframe.

dasMulli commented 5 years ago

Another ask: https://github.com/dotnet/cli/issues/12129

I've heard this from a few other customers as well - e.g. creating WinForms Apps that interface with COM components supplied by hardware vendors.

While using VS is workable, I think it should not be necessary.

There are too many dependencies between COM and Windows to reconcile in a reasonable way and since one of the primary goals of .NET Core SDK is to be as platform agnostic as possible, this tight coupling violates that principle

There are already platform-specific cases of tight coupling to windows, e.g. the logic to embed resources (Icons) into built .exe files for 3.0 GUI apps (source). Being platform-specific for platform-specific use cases is fine or at least better than not having it work at all.

So I'd say it is not urgent but somewhat important in the long run. I'd like to see this work in .NET 5 or 6 when more businesses start to port their desktop apps to core.

dotMorten commented 5 years ago

I just went out of my way to try and avoid a com reference I needed. It was a lot of work, but I did it because I'm realizing it's not just the library you build that requires vs2019, but it's contagious and will affect all downstream projects that reference that library.

ghost commented 4 years ago

The dotnet CLI doesn't support it. I'm currently investigating a workaround using MSBuild for VS 2019 without the IDE, which I finally got to work with the following in my tasks.json file, using msbuild instead of dotnet

    "tasks": [
        {
            "label": "build",
            "type": "shell",
            "command": "msbuild",
            "args": [
                "/property:GenerateFullPaths=true",
                "/t:build",
                "/consoleloggerparameters:NoSummary"
            ],
            "group": {
                "kind": "build",
                "isDefault": true
            },
            "presentation": {
                "reveal": "silent"
            },
            "problemMatcher": "$msCompile"
        }
    ]

And in the csproj file, in my case, I needed to force the platform target to x86

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>netcoreapp3.1</TargetFramework>
    <PlatformTarget>x86</PlatformTarget>
  </PropertyGroup>
JensNordenbro commented 4 years ago

Moving a big application from .NET FW4.8 to .NET5 seems very feasible; this is one of the few roadblocks. Sure, long term nobody wants COM-references but since the genie is out of the bottle with winforms and wpf not being cross platform but still included in .NET Core, fixing this is just more of the same! Any news on this @AaronRobinsonMSFT.

AaronRobinsonMSFT commented 4 years ago

Any news on this @AaronRobinsonMSFT.

@JensNordenbro Not that I am aware of. Since support exists by using the .NET Framework version of MSBuild, there hasn't been the strong need to add support in the .NET Core SDK. Is using the .NET Framework MSBuild not a workable solution for your scenario?

JensNordenbro commented 4 years ago

I guess I could build the interop-assemblies using netfw msbuild and then consume them in .net5.

There seems to be some suggestions on improved COM-scenarios on .NET5 https://github.com/dotnet/runtime/blob/master/docs/design/features/COM-activation.md I guess if that journey is embarked upon this scenarion should be included.

jamers99 commented 4 years ago

@dotMorten a pretty clean workaround would seem to be using dotnet msbuild instead. https://docs.microsoft.com/en-us/dotnet/core/tools/dotnet-msbuild

Edit: this does not resolve the problem Unfortunately, this didn't fix my problem. Gave the same error.

nick-beer commented 4 years ago

We're also running into this as we port our large .NET Framework application. We've really liked the simplicity of dotnet build on our top level solution - it would be nice to be able to maintain that simplicity.

janschreier commented 3 years ago

I also tripped over the issue of dotnet build not supporting interop (MSB4803). I had the problem when using EF core's dotnet ef dbcontext scaffold

would be nice to see some elegant solution to being able to speak to office components with .net 5

ghost commented 3 years ago

Seems very counter-intuitive for me that .NET 5.0 does not support elements of .NET Framework.

Can we hope to see COMReferences supported in .NET 5.0? Or do we have to keep hacking our way around it to use MSBuild?

JensNordenbro commented 3 years ago

Also add support for easy regfreecom

wagenheimer commented 2 years ago

I'm using DOT NET 6 and I also tripped over the issue of dotnet build not supporting interop (MSB4803). I had the problem when using EF core's dotnet ef dbcontext scaffold

calvin-charles commented 2 years ago

and why dotnet pack also fail when I have COMreference and I pass '--no-build' command argument? I am not trying to build here, just pack?

quicoli commented 1 year ago

I just faced this now in my .NET 6.0 WPF application. Some context: my application needs to list the installed Windows Updates, for that I referenced the WUApi.dll. It works, the build works in my VS. Building in Azure pipeline using dotnet CLI it fails as you all already know. My workaround (probably you all have done the same):

Like I said, it's a workaround, it's not beautiful however it doesn't brake my main pipeline anymore.

snechaev commented 1 year ago

@quicoli just as a side note: you can just use tlbimp from net framework to generate PIA (interop dll) which will be usable in net 6 project with simple : tlbimp C:\Windows\System32\wuapi.dll. So, you will not need to write any wrapping class library code by hands. Additional reference https://github.com/dotnet/runtime/issues/27698#issuecomment-442930605 Anyway, I still hope that full-featured support of COM-scenarios will be added in net.

quicoli commented 1 year ago

Hi Sergey

Yes, I did that 😊

Sent from Outlook for Androidhttps://aka.ms/AAb9ysg


From: Sergey Nechaev @.> Sent: Friday, March 10, 2023 2:53:01 PM To: dotnet/msbuild @.> Cc: Paulo Quicoli @.>; Mention @.> Subject: Re: [dotnet/msbuild] Add support for COMReference items on .NET Core (#3986)

@quicolihttps://github.com/quicoli just as a side note: you can just use tlbimp from net framework to generate PIA (interop dll) which will be usable in net 6 project with simple : tlbimp C:\Windows\System32\wuapi.dll. So, you will not need to write any wrapping class library code by hands. Additional reference dotnet/runtime#27698 (comment)https://github.com/dotnet/runtime/issues/27698#issuecomment-442930605 Anyway, I still hope that full-featured support of COM-scenarios will be added in net.

— Reply to this email directly, view it on GitHubhttps://github.com/dotnet/msbuild/issues/3986#issuecomment-1463917812, or unsubscribehttps://github.com/notifications/unsubscribe-auth/AB775D5THB2NGL6EE2QG6JTW3M543ANCNFSM4GINSBJA. You are receiving this because you were mentioned.Message ID: @.***>

mika76 commented 1 year ago

Adding my support for this request. I have a really old dll I can't escape

Blinchik91 commented 1 year ago

Same here, still not fixed

xDaevax commented 1 year ago

and why dotnet pack also fail when I have COMreference and I pass '--no-build' command argument? I am not trying to build here, just pack?

Exactly this.

Due to https://learn.microsoft.com/en-us/visualstudio/msbuild/resolvecomreference-task?view=vs-2022#msb4803-error, I use msbuild to build the project in a CI pipeline and this works fine, but then I can't create a NuGet package on the next step of the pipeline because the --no-build option of dotnet pack seems to be ignored, and the build is re-run.

As a workaround, I have updated our process to do the following:

msbuild -t:pack -p:PackageVersion=0.0.0.0 -p:Configuration=release

Dolotboy commented 7 months ago

In one of my project in WPF with .NET 6.0 I installed the following NuGet https://www.nuget.org/packages/Microsoft.Office.Interop.Word It didn't work because it wasn't supported by .NET Core, So I found a work around to pass it by COMReference to make it work. When I launch the application, everything seems to be working, but when I try "dotnet build" I get an error saying: "The task "ResolveComReference" is not supported on the .NET Core version of MSBuild. Please use the .NET Framework version of MSBuild."

Would be nice to be able to build COMReference in .NET Core, since WPF a more largely used frame then WinForms...

oscarromero commented 3 months ago

I know this is closed, but I ended up here trying to find a solution, I applied and tested but it was not what I was looking for. so, I'm sharing my "solution" or "workaround" about my situation.

My case was about a COM reference as part of a NET Framework project migrated to NET8. I was unable to build on an OSX environment. I could end up rewriting it or adding support to the new version, but it was more costly and time-consuming. So I created a mock library project and implemented the classes, methods, and properties to get a successful build.

The goal was not to run on Linux/OSX but to be able to develop and upgrade the ecosystem, this impacted the build of the artifact in the end, but our deployments to prod are executed on Windows, so no problem.

So, along with the mock lib project I implemented conditions and constants during the build of the project, so, if we are on Linux/OSX we just build using the mock project otherwise with the COM.

If you want to try, add the next lines to your .csproj file...

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>net8.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>disable</Nullable>
    <GenerateAssemblyInfo>false</GenerateAssemblyInfo>
    <IsWindows Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Windows)))' == 'true'">true</IsWindows>
  </PropertyGroup>

  <PropertyGroup Condition="'$(IsWindows)'=='true'">
    <DefineConstants>Windows</DefineConstants>
  </PropertyGroup>

  <Target Name="DisplayMessages" BeforeTargets="Build">
    <Message Condition="'$(IsWindows)'=='true'" Text="Building for Windows" Importance="High" />
    <Message Condition="'$(IsWindows)'==''" Text="Building for Linux/OSX" Importance="High" />
  </Target>

  <ItemGroup Condition="'$(IsWindows)'=='true'">
    <COMReference Include="YOUR-COM-OBJECT-NAME">
      <Guid>{YOUR-GUID}</Guid>
      <VersionMajor>10</VersionMajor>
      <VersionMinor>0</VersionMinor>
      <Lcid>0</Lcid>
      <WrapperTool>tlbimp</WrapperTool>
      <Isolated>False</Isolated>
      <EmbedInteropTypes>True</EmbedInteropTypes>
    </COMReference>
  </ItemGroup>

  <ItemGroup Condition="'$(IsWindows)'==''">
    <ProjectReference Include="../MockCOMCore/MockCOMCore.csproj">
      <Name>MockCOMCore</Name>
    </ProjectReference>
  </ItemGroup>
</Project>
#if Windows
    using YOUR-OFFICIAL-COM;
#else
    using YOUR-OFFICIAL-COM = MockCOMCore;
#endif