Reputation: 3066
I have a simple .NET Core application and publish it by the following command:
dotnet publish -c Release -r win10-x64
SqlLocalDbStarter.csproj
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp2.1</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Win32.Registry" Version="4.5.0" />
</ItemGroup>
</Project>
When the publish process finished, dotnet
created a win10-x64
folder in the bin\Release
folder. Then after opening it, the folder contains a publish
folder and some DLL and EXE files.
There are some issues for me:
exe
files (inside / outside publish folder) do I need for the PE application?exe
file and move it in other place, doesn't it run (without a message)?dll
files to run the application, so there are two options for me (inside / outside publish folder). Inside the 'publish' folder, the size is 66 MB, but outside the 'publish' folder, it is 1 MB.exe
file to run my program without DLL files.Upvotes: 23
Views: 38540
Reputation: 1321
Before .NET Core 3.0
dotnet publish -r win-x64 -c Release --self-contained
Pretty self-explanatory:
So this works right, we end up with a folder that has our exe and everything that is required to run it, but the issue is that there is a tonne required to run even a HelloWorld console app.
After .NET Core 3.0
dotnet publish -r win-x64 -c Release /p:PublishSingleFile=true
All this does is runs our publish command but tells it to package it within a single file. You’ll notice that we no longer specify the self-contained flag. That’s because it’s assumed that if you are packaging as a single exe, that you will want all it’s dependencies along with it. Makes sense.
A single tidy exe! When this is executed, the dependencies are extracted to a temporary directory and then everything is ran from there. It’s essentially a zip of our previous publish folder! I’ve had a few plays around with it and honestly, it just works. There is nothing more to say about it. It just works.
File Size And Startup Cost
Modify the .csproj file and add PublishTrimmed = true.
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp3.0</TargetFramework>
<PublishTrimmed>true</PublishTrimmed>
</PropertyGroup>
</Project>
Now run the below command:
dotnet publish -r win-x64 -c Release /p:PublishSingleFile=true
Upvotes: 16
Reputation: 13167
.NET Core 3.0 supports it out of the box. It packs all stuff in one .exe
file (~68 MB for a basic console application). 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 a 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 a csproj
file:
dotnet publish -r win-x64 -p:PublishSingleFile=true
For more details, see the great answer given by Gopi.
Warp
(thanks to Darien Shannon for mentioning it in the comment) and dotnet CoreRT
. Both work with previous versions of .NET Core also
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.
As of Jan 2022 this project is superseded by NativeAOT experiment in dotnet/runtimelab repository. 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/
Upvotes: 26
Reputation: 3112
This documentation from Microsoft uses the same dotnet publish -c Release -r win10-x64
that you have used, and documents it as follows (emphasis added):
This creates a Release (rather than a Debug) version of your app for each target platform. The resulting files are placed in a subdirectory named publish that's in a subdirectory of your project's .\bin\Release\netcoreapp1.1 subdirectory. Note that each subdirectory contains the complete set of files (both your app files and all .NET Core files) needed to launch your app.
Along with your application's files, the publishing process emits a program database (.pdb) file that contains debugging information about your app. The file is useful primarily for debugging exceptions. You can choose not to package it with your application's files. You should, however, save it in the event that you want to debug the Release build of your app.
So the correct files to deploy are the ones in the publish
subdirectory. That directory is 60+ MB because it includes the .NET core libraries needed for self-contained deployment.
Upvotes: 2