Target Framework Moniker
Let's get acquainted. In .NET 5.0, to use Windows Forms or WPF, it's not enough for us to just specify net5.0:
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
<UseWindowsForms>true</UseWindowsForms>
</PropertyGroup>
When trying to use Windows Forms or WPF, we get the error
C:\Program Files\dotnet\sdk\5.0.201\Sdks\Microsoft.NET.Sdk\targets\Microsoft.NET.Sdk.DefaultItems.targets(369,5): 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.
The solution, as the error suggests, is to specify the Target Framework Moniker
<PropertyGroup>
<TargetFramework>net5.0-windows</TargetFramework>
<UseWindowsForms>true</UseWindowsForms>
</PropertyGroup>
How it works
The build will automatically import files from Microsoft.NET.Sdk \ targets.
Further, dotnet \ sdk \ 5.0 \ Sdks \ Microsoft.NET.Sdk.WindowsDesktop \ targets \ Microsoft.NET.Sdk.WindowsDesktop.props contains the code:
<FrameworkReference Include="Microsoft.WindowsDesktop.App" IsImplicitlyDefined="true"
Condition="('$(UseWPF)' == 'true') And ('$(UseWindowsForms)' == 'true')"/>
<FrameworkReference Include="Microsoft.WindowsDesktop.App.WPF" IsImplicitlyDefined="true"
Condition="('$(UseWPF)' == 'true') And ('$(UseWindowsForms)' != 'true')"/>
<FrameworkReference Include="Microsoft.WindowsDesktop.App.WindowsForms" IsImplicitlyDefined="true"
Condition="('$(UseWPF)' != 'true') And ('$(UseWindowsForms)' == 'true')"/>
Where is the problem
, FrameworkReference : .NET , NuGet
, - , Windows Forms WPF 'net5.0-windows'.
, .
Windows Forms WPF , 60 .
using System.Windows.Forms;
namespace Library
{
public class Demo
{
void ShowForm()
{
var f = new Form();
f.Show();
}
}
}
using System;
class Program
{
public static void Main()
{
Console.WriteLine("Hello World!");
}
}
, Library.Demo.
dotnet publish:
dotnet publish ConsoleApp.csproj --self-contained -c Release -r win-x64 /p:PublishSingleFile=true /p:PublishTrimmed=true /p:IncludeAllContentForSelfExtract=true
81,8!
IncludeAllContentForSelfExtract %TEMP%\.net .
?
Library.Demo, PublishTrimmed, Windows Forms .
dotnet publish , !
1
:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
<!-- -->
<DisableImplicitFrameworkReferences>true</DisableImplicitFrameworkReferences>
</PropertyGroup>
<ItemGroup>
<!-- .NET Runtime -->
<!-- PrivateAssets="all" , -->
<FrameworkReference Include="Microsoft.NETCore.App" />
<!-- Windows Desktop -->
<!-- PrivateAssets="all" - -->
<FrameworkReference Include="Microsoft.WindowsDesktop.App" PrivateAssets="all" />
<!-- :
Microsoft.WindowsDesktop.App.WPF
Microsoft.WindowsDesktop.App.WindowsForms -->
</ItemGroup>
</Project>
DisableImplicitFrameworkReference
2
.net5.0-windows .net5.0
:
dotnet publish ConsoleApp.csproj --self-contained -c Release -r win-x64 /p:PublishSingleFile=true /p:PublishTrimmed=true /p:IncludeAllContentForSelfExtract=true
18.8
Should you do this in libraries?
Definitely yes!
On the one hand, this allows you to use types from Windows Forms or WPF, on the other hand, the collector is able to throw out all unused and produce a smaller file size.