Creating Trimmed Self Contained Executables in .NET Core

Jeremy Morgan - Jul 23 '19 - - Dev Community

I'm going to show you a cool new feature in .NET Core 3.0.

Let's say you want to create a simple, lean executable you can build and drop on to a server.

For an example we'll create a console app that opens a line of text, reads it and displays the output.

First, let's create a new .NET Core app:

dotnet new console
Enter fullscreen mode Exit fullscreen mode

This will scaffold a new console application.

Now run it:

dotnet run
Enter fullscreen mode Exit fullscreen mode

It should look something like this:

I'm on a Mac here, but it doesn't matter as long as your development box has the .NET Core CLI Installed.

This displays "Hello World" on the console.

Now, lets create a file called test.txt:

this is a file!
With some lines
whatever
Enter fullscreen mode Exit fullscreen mode

Doesn't matter what you put in here, as long as it has some text in it.

Next we'll create a something that will read those lines and display them. Remove the "Hello World!" code and replace it with this:

string[] lines = System.IO.File.ReadAllLines(@"test.txt");

        foreach (string line in lines)
        {
            Console.WriteLine("\t" + line);
        }

Console.WriteLine("Press any key to exit.");
System.Console.ReadKey();
Enter fullscreen mode Exit fullscreen mode

This is pretty much your basic cookie cutter code for:

  • opening up a file
  • reading it into a string array
  • loop through the array line by line
  • print each line
  • exit

Pretty simple stuff. When I run it on my machine it looks like this:

And that's great. But I'm on a Mac here, what if I want it to run on a Windows Machine? Linux? No problem, this is .NET Core right? We'll just publish it to multiple targets.

But what if .NET Core isn't installed on the machine?

What if I just want a simple executable I can run to read this file without a pile of files or .Net core installed?

Publishing in .Net Core

Let's back up a little. .Net Core has had publishing profiles for a long time. The idea behind "target" publishing is one of the biggest selling points of the platform. Build your app, then publish it for a specific target, Windows, OSX, or Linux.

You can publish it a few different ways

  • Framework Dependent Deployment - This means relies on a shared version of .NET Core that's installed on the Computer/Server.
  • Self Contained Deployment - This doesn't rely on .Net Core being installed on the server. All components are included with the package (tons of files usually).
  • Framework Dependent Executables - This is very similar to a framework dependent deployment, but it creates executables that are platform specific, but require the .NET Core libraries.

Ok, so what's this cool new feature I'm going to show?

Well, when you do a self contained deployment it's cool because you don't need the runtime installed, but it ends up looking something like this:

This is the application we just built published as a Self Contained Deployment for Windows. Yikes.

Let's say you wanted to share this file reader application, and asking someone to copy all these files into a folder to run something to read a text file. It's silly.

New Feature: Self Contained Executables

So to build that self contained executable I ran the following command:

dotnet publish -c release -r win10-x64
Enter fullscreen mode Exit fullscreen mode

This should look pretty familiar to you if you've done it before. But .NET Core 3.0 has a cool new feature:

dotnet publish -r win-x64 -c Release /p:PublishSingleFile=true
Enter fullscreen mode Exit fullscreen mode

Using this flag, it will build something a little different:

That's MUCH better. It's now a single exe and .pdb. If we look at the info, it's not super small:

But it includes the .NET Core runtime with it as well. And here's another cool feature.

dotnet publish -r win-x64 -c Release /p:PublishSingleFile=true /p:PublishTrimmed=true
Enter fullscreen mode Exit fullscreen mode

So in our example it doesn't change the size, but if you have a large complex application with a lot of libraries, if you just publish it to a single file, it can get HUGE. By adding the PublishTrimmed flag it will only extract the libraries you need to run the application.

So when we copy the files to a Windows 10 machine, we have a nice small package:

And we run it and it works! Without .NET Core!

and if I change my target:

dotnet publish -r linux-x64 -c Release /p:PublishSingleFile=true /p:PublishTrimmed=true
Enter fullscreen mode Exit fullscreen mode

I can run it on a Linux server without .NET Core just as easily:

Just remember on a Linux machine you won't need the .NET Core runtime, but you will need the Prerequisites for .NET Core on Linux installed.

Conclusion

So this is a cool feature of .NET Core 3.0. If you want to build trimmed down self-contained executables for any of the platforms, you can do it easily with a couple of flags.

This is great for those stupid simple things: console apps, data readers, microservices, or whatever you want to build and just drop on a machine with no hassle. I thought it was a cool feature to show.

What's your .NET Core IQ??

My ASP.NET Core Skill IQ is 200. Not bad, can you beat it? Click here to try

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .