3
votes

I am developing a simple, cross-platform .NET application. I need to distribute it as a self-contained deployment as I can't assume if .NET is already installed.

.NET publish for Windows 10 64 bit generates a 64 MB directory. I am pretty sure most of the DLL files are not needed. Is there a way to optimize the distribution so that only the necessary DLL file are kept?

4
side note: if you should be using .net core 2.0, use win-x64 over win10-x64Martin Ullrich
thanks. makes sense.sumo

4 Answers

3
votes

I'm facing the same problem. So far, here's what I found:

Microsoft released a Trim tool that finds unused assemblies and removes them.

With .NET CLI:

  • dotnet add package Microsoft.Packaging.Tools.Trimming -v 1.1.0-preview1-25818-01
  • dotnet publish -r win-x64 -c release /p:TrimUnusedDependencies=true

Your application's footprint is now much smaller (normally)


For a better optimization you can use it with ILLinker:

  • dotnet new nuget

Open nuget.config and add <add key="dotnet-core" value="https://dotnet.myget.org/F/dotnet-core/api/v3/index.json" />between <packageSource>

Here is an example of what your nuget.config should look like.

Then execute the following commands:

  • dotnet add package ILLink.Tasks -v 0.1.4-preview-981901
  • dotnet add package Microsoft.Packaging.Tools.Trimming -v 1.1.0-preview1-25818-01
  • dotnet publish -r win-x64 -c release /p:TrimUnusedDependencies=true

Using these two tools I managed to divide the size of my application by three.

Source: Reducing the size of self-contained .NET Core applications


I'm still trying to get better optimization. I want to run my ASP.NET Core application (currently 72 MB) in an embedded system with only 10 MB.

If anyone has found a better optimization, I'm a buyer.

2
votes

Since .NET Core 3.0, it's as simple as adding a flag to your project's .csproj file:

<PropertyGroup>
  <OutputType>Exe</OutputType>
  <TargetFramework>netcoreapp3.0</TargetFramework>
  <RuntimeIdentifier>win-x64</RuntimeIdentifier>
  <PublishSingleFile>true</PublishSingleFile>

  <PublishTrimmed>true</PublishTrimmed> <!-- Add this flag to enable trimming -->
</PropertyGroup>

Then you can just use dotnet publish to generate a trimmed executable.

And here's a warning from the documentation:

It's important to consider that applications or frameworks (including ASP.NET Core and WPF) that use reflection or related dynamic features, will often break when trimmed. This breakage occurs because the linker doesn't know about this dynamic behavior and can't determine which framework types are required for reflection. The IL Linker tool can be configured to be aware of this scenario.

Above all else, be sure to test your app after trimming.

A typical reduction result for a simple console applications seems to be from about 70 MB to about 28 MB.

2
votes

Update 2020: This is now part of the toolchain, see Pawel's answer.

This task can be done by using the IL linker. By adding a NuGet package to your project it can reduce the size of the published self-contained application by removing code that is not needed. However, it is still in preview (as of 2017). See the announcement post and sample instructions for self-contained applications.

0
votes

Microsoft.DotNet.ILCompiler seems to be an even better option than ILLinker. See this reply.

My testing of .NET Core 2.2 self-contained outputs on the same source code gave:

  1. Default self-contained publish: 68 MB
  2. ILLinker: 36 MB
  3. ILCompiler: 5 MB