Publish .NET Core App As Portable Executable
.NET Core 3.0
.NET Core 3.0 supports it out of the box. It packs all stuff in one .exe
file (~68 MB for a basic console app). There is PublishTrimmed=true
option that can decrease size to ~28 MB by analyzing static code references and excluding unused framework assemblies from the final build.
To configure single exe
build edit your csproj
file:
<PropertyGroup>
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
<PublishSingleFile>true</PublishSingleFile>
</PropertyGroup>
or on the command line in a folder with csproj
file:
dotnet publish -r win-x64 -p:PublishSingleFile=true
For more details see a great answer given by Gopi.
Standalone utils
Warp
(thanks to Darien Shannon for mentioning it in the comment) and dotnet CoreRT
. Both work with previous versions of .Net Core also
Warp
It is a tool similar to ILMerge for the classic .NET Framework
. It is very easy to use. For the basic console app, It can produce .exe
~35 MB without tree shaker and around 10-15 MB with tree shaker.
Dotnet CoreRT
As of Jan 2022 this project is superseded by NativeAOT experiment in dotnet/runtimelab repo. Thanks to @t.j.
For now, you can try to pre-compile the application into a native single-file executable using dotnet CoreRT
project. I'm saying "try" because documentation says:
This project is in the early stages of its development.
Nevertheless, it works at least for simple applications. See the sample here.
According to its description, you need to run the following command in the project folder:
dotnet new nuget
This will add a nuget.config file to your application. Open the file
and in the element under add the following:
<add key="dotnet-core" value="https://dotnet.myget.org/F/dotnet-core/api/v3/index.json" />
<add key="nuget.org" value="https://api.nuget.org/v3/index.json" protocolVersion="3" />
Then run this:
dotnet add package Microsoft.DotNet.ILCompiler -v 1.0.0-alpha-*
Then run this:
dotnet publish -r win-x64 -c release
Once completed, you can find the native executable in the root folder
of your project under /bin/x64//netcoreapp2.0/publish/
Build .NET Core console application to output an EXE
For debugging purposes, you can use the DLL file. You can run it using dotnet ConsoleApp2.dll
. If you want to generate an EXE file, you have to generate a self-contained application.
To generate a self-contained application (EXE in Windows), you must specify the target runtime (which is specific to the operating system you target).
Pre-.NET Core 2.0 only: First, add the runtime identifier of the target runtimes in the .csproj file (list of supported RIDs):
<PropertyGroup>
<RuntimeIdentifiers>win10-x64;ubuntu.16.10-x64</RuntimeIdentifiers>
</PropertyGroup>
The above step is no longer required starting with .NET Core 2.0.
Then, set the desired runtime when you publish your application:
dotnet publish -c Release -r win10-x64
dotnet publish -c Release -r ubuntu.16.10-x64
Publish ONE executable file
At the moment, this is not possible because:
- portable applications still need at least a
runtimeconfig.json
to tell the host (dotnet
/dotnet.exe
) which shared runtime to use. Even if you IL-Merge all your managed code into a single dll, this file is still required. The host also expects adeps.json
expressing the dependencies of the application. - self-contained applications rely on building a
.dll
+.deps.json
and copying over content from runtime-specific NuGet packages. This also includes native libraries that are searched for by file name.
The CoreRT project aims to compile a .NET Core application to a single native binary using ahead-of-time compilation but is still in development.
What to copy for a .Net Core console application publish?
Copying just the files from the win-x64 directory was not enough. I needed to copy up the entire publish folder and run the application from that directory, otherwise error messages such as not being able to find a dependency would occur.
Compile a .NET Core application as an EXE file using Visual Studio 2017
Update 2019:
.NET Core 3.0+ projects will now include an executable for the platform you build on by default. This is just a shim executable and your main logic is still inside a .dll
file.
But .NET Core 3.0 also introduced single-file deployments so deploying with
dotnet publish -r win-x64 -p:PublishSingleFile=True --self-contained false
will create a single .exe file containing all your dependencies. You can change --self-contained
to true
to also include the .NET Core Runtime as well so .NET Core does not need to be installed globally on the target machine.
Original
.NET Core applications are supposed to be .dll
files. OutputType
set to Exe
in this case means "executable" and does everything necessary to ensure that the output is runnable (entry point from Main()
method, .runtimeconfig.json
file). The resulting DLL file is meant to be run using:
dotnet yourapp.dll
This DLL file works across all platforms that are supported by the .NET Core runtime (Windows, Linux, and macOS). This is called a "portable" or "framework dependent" deployment.
If you want really a .exe
file, consider self-contained deployments. This will create an output that contains its own copy of the .NET Core runtime and an yourapp.exe
file - but it also increases the size of the published application and it needs to be updated when new versions of the runtime are released.
Also, the resulting application only works on the operating system published for.
Refer to .NET Core application deployment for more details on the deployment options and how to set them up.
Related Topics
C# Serialized JSON Date to Ruby
Should I Use Mkannotation, Mkannotationview or Mkpinannotation
Openssl.Net Porting a Ruby Example to C# (From Railscasts 143 Paypal-Security)
Entity Framework Specification Pattern Implementation
What Is Ruby (1.8.7) Analog to Sorteddictionary in C#/.Net
C++, C# and JavaScript on Winrt
Xamarin: Android: System.Unauthorizedaccessexception: Access to The Path Is Denied
Ruby Equivalent of C# 'Using' Statement
How to Develop iOS App Using Xamarin Studio on Windows
Executing a Cygwin Process from .Net
Reading/Writing from Named Pipes Under Mono/Linux
C# Httpwebrequest and JavaScript
Why Must C# Operator Overloads Be Static
How to Pass Variables from C# to JavaScript
Why Accessviolationexception Cannot Be Caught by .Net4.0