Reduce the size of the .NET 5.0 console application

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





PrivateAssets="all". .





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.








All Articles