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

When TargetFramework=net5.0-windows, dotnet pack uses net5.0-windows7.0 instead #14553

Open
augustoproiete opened this issue Nov 15, 2020 · 14 comments
Milestone

Comments

@augustoproiete
Copy link

augustoproiete commented Nov 15, 2020

I can't tell if this is by design or if it's a bug, and I couldn't find any documentation via search engines that would explain this. I also read the Target Framework Names in .NET 5 design spec and didn't see any mention of this behavior there.

When running dotnet build on a .NET 5 WPF app or .NET 5 Windows Forms App with a TargetFramework set to net5.0-windows, all artifacts are correctly written to bin\{Configuration}\net5.0-windows as expected.

However, when running dotnet pack on the same project, the artifacts in the .nupkg are stored in /lib/net5.0-windows7.0 instead of /lib/net5.0-windows which is what one would expect.

image

To reproduce:

mkdir repro
cd repro
dotnet new wpf --framework net5.0
dotnet pack repro.csproj

repro.csproj

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>WinExe</OutputType>
    <TargetFramework>net5.0-windows</TargetFramework>
    <UseWindowsForms>true</UseWindowsForms>
  </PropertyGroup>

</Project>

Expectation

The expectation is that dotnet pack would honor exactly what has been defined in the .csproj and exactly what is written to the disk... Which leads me to believe that this could be a bug in dotnet pack.

If this is by design, then I'd like to put in a feature request to throw an error that prevents devs from using net5.0-windows in WPF & WinForms projects and force developers to be specific with net5.0-windows7.0 or net5.0-windows10.0.17763.0 instead, because otherwise it is very confusing to have net5.0-windows in the project, net5.0-windows on disk in the build output, but then a different folder in the NuGet package.


C:\Users\augustoproiete>dotnet --info
.NET SDK (reflecting any global.json):
 Version:   5.0.100
 Commit:    5044b93829

Runtime Environment:
 OS Name:     Windows
 OS Version:  10.0.18363
 OS Platform: Windows
 RID:         win10-x64
 Base Path:   C:\Program Files\dotnet\sdk\5.0.100\

Host (useful for support):
  Version: 5.0.0
  Commit:  cf258a14b7

.NET SDKs installed:
  2.1.801 [C:\Program Files\dotnet\sdk]
  2.1.802 [C:\Program Files\dotnet\sdk]
  2.2.401 [C:\Program Files\dotnet\sdk]
  3.1.101 [C:\Program Files\dotnet\sdk]
  3.1.102 [C:\Program Files\dotnet\sdk]
  3.1.302 [C:\Program Files\dotnet\sdk]
  3.1.404 [C:\Program Files\dotnet\sdk]
  5.0.100 [C:\Program Files\dotnet\sdk]
@Skyppid
Copy link

Skyppid commented Nov 16, 2020

I had the same phenomenon and when I tried to install these packages in a .NET 5 app, it told me that "net5.0" and "net.5.0-windows7.0" aren't compatible. All my projects where "net5.0-windows" actually, though.

@marcpopMSFT marcpopMSFT added the untriaged Request triage from a team member label Nov 17, 2020
@mrbiglari
Copy link

I had the same issue as @Skyppid , in my case it was because I had a project with .net5.0 referencing .net5.0-windows projects.

I got it resolved by just changing the .net5.0 to .net5.0-windows as well.

@augustoproiete
Copy link
Author

Confirmed by @zkat on Twitter that this is by design.

image

@augustoproiete
Copy link
Author

I'll leave this issue open as a suggestion to add some consistency here between the build output, and the NuGet packaged library, either on the .NET SDK side or on the NuGet side.

When developing libraries that should be consumed by Windows Desktop apps, and given that I defined net5.0-windows in my project, I'd expect NuGet to also store the files under net5.0-windows, but it doesn't:

image

However, if set the TargetFramework in my project to net5.0-windows7.0, then my build output now uses net5.0-windows7.0 and now it matches the NuGet package folder structure.

image


One alternative could be modifying the logic of the warning NETSDK1136 that requires net5.0-windows when the project has <UseWPF>true</UseWPF> or <UseWindowsForms>true</UseWindowsForms>, to require net5.0-windows7.0 instead, when the user specified net5.0-windows as the TFM.

Error NETSDK1136 The target platform must be set to Windows (usually by including '-windows' in the TargetFramework property) when using Windows Forms or WPF, or referencing projects or packages that do so.

Another alternative could be changing NuGet to use net5.0-windows instead of net5.0-windows7.0 and have it understand that it's the same thing.

image

@dsplaisted dsplaisted added this to the Discussion milestone Dec 2, 2020
@dsplaisted
Copy link
Member

As mentioned, this is by design.

@zkat @nkolev92 is there an explanation to link to about how / why this works?

@dsplaisted dsplaisted removed the untriaged Request triage from a team member label Dec 2, 2020
@dsplaisted dsplaisted removed their assignment Dec 2, 2020
@zkat
Copy link

zkat commented Dec 2, 2020

I looked through https://github.com/dotnet/designs/blob/main/accepted/2020/net5/net5.md but didn't find anywhere where this was actually documented. I don't think we have it documented anywhere but in our heads right now. Did you have anything, @terrajobst ?

@nkolev92
Copy link
Contributor

nkolev92 commented Dec 2, 2020

The pack behavior described in spec is carries the gist of platform versions are required in packages, but doesn't use the terminology that was implemented.

See

TFM has an OS but no OS version. If the user omits the OS version number from the project's <TargetFramework> property, all usages of the TFM should not contain an OS version number, including the project's output directory, the lib folder in the NuGet package, and other corresponding entries in the .nuspec. However, the effective OS version will be recorded in the .nuspec's <platform> element that corresponds to the TFM.

I think this is ok, because the general spec can't reasonable call out all technical details.

I think it'd be nice to have specific docs describing this behavior.

@tripleacoder
Copy link

tripleacoder commented Jan 15, 2021

I had the same phenomenon and when I tried to install these packages in a .NET 5 app, it told me that "net5.0" and "net.5.0-windows7.0" aren't compatible. All my projects where "net5.0-windows" actually, though.

I get the same error, specifically:

NU1202: Package MyControls is not compatible with net50-windows (.NETFramework,Version=v5.0,Profile=windows) / win-x64.

Package MyControls supports:

net50-windows7.0 (.NETFramework,Version=v5.0,Profile=windows7.0)
netcoreapp3.1 (.NETCoreApp,Version=v3.1)

Both projects use the TFM "net50-windows".

If I then go in under .nuget/packages and /lib on the build server and copy the folder "net50-windows7.0" to a new folder "net50-windows", the Nuget error goes away.

But then I get this compile error:

errorCS0103: The name 'Windows' does not exist in the current context

@nkolev92
Copy link
Contributor

nkolev92 commented Jan 15, 2021

I get the same error, specifically:

@tripleacoder

What's your SDK version?
If you look at your error more closely, it says, net50-windows7.0 is .NET Framework, which is how SDKs older than 5.0.100 would interpret it.

@tripleacoder
Copy link

What's your SDK version?
If you look at your error more closely, it says, net50-windows7.0 is .NET Framework, which is how SDKs older than 5.0.100 would interpret it.

I am not sure. Does the MSBuild log show the SDK version?

@sam-wheat
Copy link

Please take a look at this issue I raised on Stackoverflow and let me know if it is related. Suggestions on how I might fix it will be greatly appreciated.

@Menelion
Copy link

Menelion commented Jun 4, 2024

It's .NET 8 and the issue persists. I have:

<Project Sdk="Microsoft.NET.Sdk">

    <PropertyGroup>
        <!-- NOTE THIS! -->
        <TargetFramework>net8.0-windows</TargetFramework>
        <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
        <Platforms>x64</Platforms>
        <!-- further info not relevant -->
    </PropertyGroup>

    <PropertyGroup Condition="'$(Configuration)' == 'Debug'">
        <DebugSymbols>true</DebugSymbols>
        <DebugType>full</DebugType>
        <Optimize>false</Optimize>
    </PropertyGroup>

    <PropertyGroup Condition="'$(Configuration)' == 'Release'">
        <DebugSymbols>false</DebugSymbols>
        <Optimize>true</Optimize>
    </PropertyGroup>

    <ItemGroup>
        <None Update="LibLouis\**">
            <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
            <Pack>true</Pack>
            <Visible>false</Visible>
            <!-- NOTE THIS! -->
            <PackagePath>lib/$(TargetFramework)</PackagePath>
        </None>
        <None Include="../../README.md" Pack="true" Visible="false" PackagePath="/" />
    </ItemGroup>
</Project>

So, In the <TargetFramework> I have net8.0-windows, but when packing, NuGet resolves the $(TargetFramework) to net8.0-windows7.0.
What is the correct way of handling this issue please? Thanks! // CC @nkolev92

Menelion added a commit to accessmind/sharp-louis that referenced this issue Jun 4, 2024
@nkolev92
Copy link
Contributor

@Menelion

That's expected.

net8.0-windows is just sugar around specifying the exact platform version.
The platform version is necessary.

I think this issue is really on a documentation issue at this point: #14553 (comment).

@dsplaisted should we move this to dotnet/docs?

@dsplaisted
Copy link
Member

Yes, this is the way it is supposed to work and it would be good to have that documented, if it isn't already.

As for this:

<None Update="LibLouis\**">
    <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
    <Pack>true</Pack>
    <Visible>false</Visible>
    <!-- NOTE THIS! -->
    <PackagePath>lib/$(TargetFramework)</PackagePath>
</None>

The PackagePath there won't apply to any output of the project, as the ItemGroup is evaluated before the project is built and those files are written. There may be other ways to customize the package paths of build outputs.

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