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

Having .net core WPF project in Solution prevents Nuget Restore on Linux / macOS #3803

Open
GregAlexJames opened this issue Oct 26, 2019 · 13 comments
Milestone

Comments

@GregAlexJames
Copy link

By design, you do not want .net core WPF and WinForms projects building on platforms other than windows (as per @livarcocc on #3592 ). When you do so it presents the following error:

/usr/local/share/dotnet/sdk/3.0.100/Sdks/Microsoft.NET.Sdk/targets/Microsoft.NET.Sdk.FrameworkReferenceResolution.targets(59,5): error NETSDK1100: Windows is required to build Windows desktop applications

Which is fine. The problem is that if a solution simply contains a .net core WPF project, that solution will no longer be able to complete a "dotnet restore" on the solution, even if you intend to build other projects (eg a dotnet core console application on macOS). This prevents the ability to build other projects within the solution because you can not get the nuget packages. This also breaks the developers experience on the other platforms (with Visual Studio for Mac no longer able to restore packages easily).

Can the way you block WPF builds on linux / macOS be changed so not to break dotnet restore on the solution?

Reproduction Steps:
Be on MacOS
Create a new solution
Inside solution add new wpf core project using "dotnet new wpf"
Inside solution add new .net core console application

With the above steps you can no longer build the console application on macOS due to NETSDK1100 as the solution nuget restore fails.

The only workaround is to (a) use the command line to do a dotnet restore on the console application project itself. This doesnt help if you have multiple other projects though each requiring this to occur (or made more difficult if you have also a Xamarin.Mac project that does not use dotnet core). Another workaround is (b) separate solutions, but this will hinder development if they share common code.

(using dotnet core 3.0.100)

Context: We have multiple common code .net standard projects with multiple front end projects for platforms like Windows, macOS, iOS, Android etc. They all load under the single solution allowing to easily complete refactors / minor code changes on other platforms if you need to do a breaking change in common code, and multiple build configurations for building specific clients.

I am now forced to have two solutions, one for building on linux / macOS, and one for windows. This means that anyone developing on linux / macOS are now more likely to miss required changes for WPF. This has only become an issue since updating from .net framework to .net core.

@StefanStolz
Copy link

StefanStolz commented Oct 29, 2019

We have exactly the same issue.

Currently we restore project by project in a script.

@livarcocc
Copy link
Contributor

My concern with a change like this is that people my silent assume that because they build their solution in Linux with a WPF project that they take it to mean that it worked and is supported. And then they will get confused when there are not binaries for those projects.

Similarly, if you have P2P dependencies to WPF/WinForms projects, it will be confusing and hard to understand why it is not building if we have this implicit rules.

I prefer the simplicity of simply failing and proposed that you build a separate solution for your non-windows build. I recognize that is not ideal, but I believe it will end up being simpler and less confusing.

@livarcocc livarcocc added this to the Discussion milestone Oct 29, 2019
@GregAlexJames
Copy link
Author

@livarcocc I have no issue with the WPF core build failing on linux. The problem here is that you make all projects in a solution fail (including those specific to the linux / macOS world like a Xamarin.Mac client) because nuget restore / dotnet restore fails on the solution. Having dotnet build fail on the solution for the WPF project would be perfectly fine.

The way you stop the WPF build should not stop a nuget restore, but break when the project itself is built.

Everything about the simplicity I agree with you. The problem is not with the idea, but the current implementation as it is a touch overreaching (affecting dotnet restore instead of just dotnet build) , and affects other projects in the same solution.

@sharpSteff
Copy link

sharpSteff commented Sep 1, 2020

It would be great to have an optional -c "Configuration" parameter like in dotnet build, to be at least be able to filter out the WPF-projects via the solution-configuration

@PatrickRainer
Copy link

Same Problem, have a Solution with different Libraries, a WPF project and a Xamarin Project. When I want to build xamarin.iOS the nuget packages cannot be restored, due it's not a windows agent.

@bopin2020
Copy link

Same Problem, have a Solution with different Libraries, a WPF project and a Xamarin Project. When I want to build xamarin.iOS the nuget packages cannot be restored, due it's not a windows agent.

Me too. I used .NET5 to create a WPF project on the linux system, but "error NETSDK1100" devil become more hateful. Here: dotnet/core#5545. BTW, I hate red color :)

@brantburnett
Copy link

My use case I haven't even found a workaround for, yet. I have an application that can be built command-line only and run in Docker or when built for Windows shows a WinForms UI. Trying to upgrade to .NET 5, and use <TargetFrameworks>net5.0;net5.0-windows<TargetFrameworks>, all the WinForms stuff is excluded for the plain net5.0 target. However, I can't build the Docker image version, even though I'm only building the net5.0 target, because I can't run dotnet restore. Since it's one project, not separate projects in a solution, I can't even script it as separate restores.

I agree, blocking this in dotnet restore is too early, it should only block on build. Or, at least, a way to run a targetted restore for a specific framework is required. If I find a workaround I'll update.

@pitchalt
Copy link

pitchalt commented Jan 3, 2021

@livarcocc Please could you explain why it is not possible to build an application for windowsdesktop on Mac. Actually, I don't need to run it on a Mac. I would like to use CI/DI to build a solution on Linux. The SDK has a compiler, libraries have a single format, what prevents you from building windowsdesktop applications on platforms other than Windows?

@AraHaan
Copy link
Member

AraHaan commented Jan 27, 2021

@pitchalt I agree the winforms sdk only provides reference assemblies and the windows desktop runtime itself is separate, those reference assemblies are safe to use to build on linux.

Why not instead do the following when building on non-windows systems when having anything use the WindowsDesktop SDK:

warning NETSDK [somenumberhere]: Building for WPF or Windows Forms is supported on non-windows platforms, but the Runtime for them is not so they will not be possible to run on platforms other than Windows and will result in PlatformNotSupported exceptions on everything when attempting to run them.

I find a warning like that is better than failing build especially for cases like github actions where you need to do security scannings, but all the security scanners use docker containers which FORCES you to use their ubuntu-latest image which then BREAKS build because github does a crappy job at allowing docker container actions on their mac or even windows images.

How else can we build and then upload our secirity scanning to github so that it can be displayed in our security tabs when CI builds pass?

Yes I think explicit warning for them that they cannot possibly suppress is far better than just failing the build, just show the warning in dotnet restore and then be done with it.

At this rate why did I even drop using Azure Pipelines on even my open source projects? Oh wait because I want entirely automated pull request updates that merge themselves because I lack the time or maintainers to do it for me.

@PulsarFX
Copy link

Any progress or workaround for this issue?
I can't restore my solution on linux anymore after switching to net5.0 respectively net5.0-windows.
Building new solutions to just have a CLI branch for linux in there doubles maintenance effort.
That's why there are csproj files in a sln, right? To target specific frameworks. That's not the task of the sln file.

@AraHaan
Copy link
Member

AraHaan commented Feb 18, 2021

I do not think there has been any yet. Are they that busy to reply?

@sharpSteff
Copy link

sharpSteff commented Feb 18, 2021

@maulwuff I've created a 2nd solution file without WPF/WinForms project.

@brantburnett
Copy link

@maulwuff

I got it to work for WinForms with a hack like this:

Main CSPROJ file:

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFrameworks>net5.0</TargetFrameworks>
  </PropertyGroup>

  <!-- We do this as an import to override TargetFrameworks so that dotnet restore in the Docker Linux build doesn't lose its mind -->
  <Import Project="$(MSBuildThisFileDirectory)WinForms.props" Condition=" '$(DockerBuild)' != 'true' " />

  <PropertyGroup>
    <DebugType>embedded</DebugType>
    <LangVersion>9</LangVersion>

    <GenerateResourceUsePreserializedResources>true</GenerateResourceUsePreserializedResources>
    <DefineConstants Condition=" '$(TargetFramework)' == 'net5.0-windows' ">$(DefineConstants);WINFORMS</DefineConstants>
  </PropertyGroup>

WinForms.props:

<Project>
  <PropertyGroup>
    <TargetFrameworks>net5.0;net5.0-windows</TargetFrameworks>
    <UseWindowsForms Condition=" '$(TargetFramework)' == 'net5.0-windows' ">true</UseWindowsForms>
  </PropertyGroup>
</Project>

This takes advantage of the fact that NuGet restore respects conditions on Import commands, though not on anything else.

When building on Linux/Docker, I just set -p:DockerBuild=true on the command line so it suppresses the extra import.

FROM mcr.microsoft.com/dotnet/sdk:5.0 AS build-env
WORKDIR /app
COPY *.csproj ./
RUN dotnet restore
COPY . ./
RUN dotnet publish -c Release -p:DockerBuild=true -f net5.0 -o output

# Runtime image
FROM mcr.microsoft.com/dotnet/runtime:5.0
WORKDIR /app
COPY --from=build-env /app/output .
ENTRYPOINT ["dotnet", "app.dll"]

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

10 participants