.Net 5 Publish Single File - Produces exe and dlls - c#

I am using VS 2019 and .Net 5 to build a simple console application. I wanted to share this app with a friend so I tried to publish it as a single file but I keep getting some extra DLLs that the executable needs to run correctly.
Edit: Switching this project to .net core 3.1 works as expected I am able to export a single Exe file without any required DLLs.
Dotnet Cli:
dotnet publish -c Release -o publish -p:PublishReadyToRun=true -p:PublishSingleFile=true -p:PublishTrimmed=true --self-contained true
Csproj:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net5.0</TargetFramework>
<PublishSingleFile>true</PublishSingleFile>
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
<PlatformTarget>x64</PlatformTarget>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="HtmlAgilityPack" Version="1.11.28" />
</ItemGroup>
</Project>

Its known issue that described here: https://github.com/dotnet/runtime/issues/36590
And new dev experience provided here: https://github.com/dotnet/designs/blob/main/accepted/2020/single-file/design.md#user-experience
So in your case you need use p:IncludeNativeLibrariesForSelfExtract=true additionaly.
Full command:
dotnet publish -c Release -o publish -p:PublishReadyToRun=true -p:PublishSingleFile=true -p:PublishTrimmed=true --self-contained true -p:IncludeNativeLibrariesForSelfExtract=true
or include this flag in .csproj file
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net5.0</TargetFramework>
<PublishSingleFile>true</PublishSingleFile>
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
<PlatformTarget>x64</PlatformTarget>
<IncludeNativeLibrariesForSelfExtract>true</IncludeNativeLibrariesForSelfExtract>
</PropertyGroup>

Related

Create Self Contained Single exe File From C# WPF Application

I'm trying to create a single exe distributable of this basic little application:
using System;
using System.Windows;
namespace BlackScreen
{
public partial class App : Application
{
[STAThread]
public static void Main()
{
App app = new App();
Window window = new Window();
window.Show();
app.MainWindow = window;
app.Run();
}
}
}
My csproj file contains:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>net7.0-windows</TargetFramework>
<Nullable>enable</Nullable>
<UseWPF>true</UseWPF>
<PublishSingleFile>true</PublishSingleFile>
<IncludeAllContentForSelfExtract>true</IncludeAllContentForSelfExtract>
<IncludeNativeLibrariesForSelfExtract>true</IncludeNativeLibrariesForSelfExtract>
</PropertyGroup>
</Project>
However, when I run dotnet publish -r Release I get dozens of files in the Release folder, not a single exe file. If I take just the exe file out of that folder and place it somewhere else it doesn't run, so clearly those dozens of other files are required.
In older answers to similar questions the recommended approach is to use ilmerge, however, that has now been deprecated. Is there an alternative or is creating a self contained exe file no longer possible?
The following project file:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>net6.0-windows</TargetFramework>
<Nullable>enable</N7llable>
<UseWPF>true</UseWPF>
<IncludeNativeLibrariesForSelfExtract>true</IncludeNativeLibrariesForSelfExtract>
</PropertyGroup>
</Project>
...and the following command...:
dotnet publish -c Release -r win-x64 --self-contained -p:PublishSingleFile=true -p:PublishReadyToRun=true
...can be used to create a self-contained and single-file deployment WPF app.

dotnet publish not detected runtimeidentifiers

In my .csproj file, i have the following written:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp3.1</TargetFramework>
<RootNamespace>SCR_Number_Generator</RootNamespace>
<RuntimeIdentifiers>win-x64;osx-x64</RuntimeIdentifiers>
</PropertyGroup>
</Project>
This is because I want to build a single/self contained executable for my app. I run the following command: dotnet publish -p:PublishSingleFile=true --no-self-contained and it gives the following error:
/usr/local/share/dotnet/sdk/6.0.302/Sdks/Microsoft.NET.Sdk/targets/Microsoft.NET.Publish.targets(102,5): error NETSDK1097: It is not supported to publish an application to a single-file without specifying a RuntimeIdentifier. You must either specify a RuntimeIdentifier or set PublishSingleFile to false. [/Users/lincolnmuller/SCR-Random-Number/SCR-Number-Generator/SCR-Number-Generator.csproj]
When i do a single RuntimeIdentifier, it detects it. But it doesn't detect RuntimeIdentifiers. How do I fix this?

How prevent copy unnecessary libraries on publish

I have three simple projects:
SampleApp.Cli1
SampleApp.Cli2
SampleApp.Lib
SampleApp.Cli1 use Microsoft.Extensions.Configuration directly
SampleApp.Cli2 uses Microsoft.Extensions.Configuration through SampleApp.Lib
SampleApp.Cli1:
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<OutputType>Exe</OutputType>
<OutputPath>../_out1</OutputPath>
<TargetFramework>netcoreapp3.1</TargetFramework>
<NoDefaultLaunchSettingsFile>true</NoDefaultLaunchSettingsFile>
</PropertyGroup>
</Project>
SampleApp.Cli2:
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<OutputType>Exe</OutputType>
<OutputPath>../_out2</OutputPath>
<TargetFramework>netcoreapp3.1</TargetFramework>
<NoDefaultLaunchSettingsFile>true</NoDefaultLaunchSettingsFile>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\SampleApp.Lib\SampleApp.Lib.csproj" />
</ItemGroup>
</Project>
SampleApp.Lib:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.1</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Configuration" Version="3.1.6" />
</ItemGroup>
</Project>
Script for publishing:
#echo off
if exist "%~dp0_out1" (
rd "%~dp0_out1" /s /q
)
if exist "%~dp0_out2" (
rd "%~dp0_out2" /s /q
)
dotnet publish "%~dp0SampleApp.Cli1/SampleApp.Cli1.csproj"
dotnet publish "%~dp0SampleApp.Cli2/SampleApp.Cli2.csproj"
After build
publish dir for SampleApp.Cli1 contains this files
web.config
SampleApp.Cli1.deps.json
SampleApp.Cli1.dll
SampleApp.Cli1.exe
SampleApp.Cli1.pdb
SampleApp.Cli1.runtimeconfig.json
publish dir for SampleApp.Cli2 contains this files
SampleApp.Lib.pdb
web.config
Microsoft.Extensions.Configuration.Abstractions.dll
Microsoft.Extensions.Configuration.dll
Microsoft.Extensions.Primitives.dll
SampleApp.Cli2.deps.json
SampleApp.Cli2.dll
SampleApp.Cli2.exe
SampleApp.Cli2.pdb
SampleApp.Cli2.runtimeconfig.json
SampleApp.Lib.dll
Question
For some unknown for me reason, the publication understands that for SampleApp.Cli1 Microsoft.Extensions.* must be taken from the shared runtime(Program Files\dotnet\shared\Microsoft.AspNetCore.App), but does not understand the same for SampleApp.Cli2. Of course, I understand that the matter is most likely in SampleApp.Lib(in real application it was Microsoft.Extensions.Hosting.WindowsServices).
In my situation, I have to build all libraries from sources that go into the publish folder. In real application Microsoft.Extensions.* libraries much more, and I would not really like to build all libraries from asp net core runtime.
Is any way to prevent copy(publish) Microsoft.Extensions.* libraries?
Sdk: 3.1.6

Publish via VS vs dotnet.exe publish why is the second faster

I have a solution with many projects, when it's time to publish we usually go one by one and publish it on VS. This was consuming a lot of time so we tried to publish it via "dotnet.exe publish" and it was a massive improvement in publish times for each project.
This leaves me with some questions that the internet has been unable to answer me so far:
Is the command skipping any steps?
Are the published projects different in any way?
Why is it faster?
Here are both configurations I'm using:
VS Publish Profile:
<PropertyGroup>
<WebPublishMethod>FileSystem</WebPublishMethod>
<LastUsedBuildConfiguration>DEV</LastUsedBuildConfiguration>
<LastUsedPlatform>Any CPU</LastUsedPlatform>
<PrecompileBeforePublish>True</PrecompileBeforePublish>
<EnableUpdateable>True</EnableUpdateable>
<DebugSymbols>True</DebugSymbols>
<Optimize>False</Optimize>
<UseMerge>True</UseMerge>
<WDPMergeOption>MergeAllOutputsToASingleAssembly</WDPMergeOption>
<SingleAssemblyName>_DEV</SingleAssemblyName>
<DeleteAppCodeCompiledFiles>True</DeleteAppCodeCompiledFiles>
<ExcludeApp_Data>True</ExcludeApp_Data>
<publishUrl>C:\Inetpub\Dev</publishUrl>
<DeleteExistingFiles>True</DeleteExistingFiles>
</PropertyGroup>
PowerShell:
dotnet.exe publish "C:\Projects\ProjectFolder\Project\Project.csproj" --configuration "DEV" --framework netcoreapp2.0 --force --output "C:\Inetpub\Dev"

VS Code: How to copy files to output directory depending on build configurations

I just started a new project in VS Code (C#, .NET Core). Anyways, I want to be able to copy files from within my project directory to the output directory like I can in visual studio. But I also want to copy specific files depending on whether or not I'm building for 32 or 64 bit.
I've looked around but so far all I've learnt how to do is copy files regardless of my build configurations.
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp2.1</TargetFramework>
</PropertyGroup>
<ItemGroup Condition="'$(RuntimeIdentifier)' == 'win-x86' Or '$(RuntimeIdentifier)' == 'win-x64'">
<None Update="foo.txt">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>
<ItemGroup Condition="'$(RuntimeIdentifier)' == 'win-x64'">
<None Update="foo.xml">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
</Project>
Steps:
Create a console app by running dotnet new console
Add foo.txt and foo.xml to the project folder.
Edit the .csproj file as above.
Build the project with multiple configurations.
dotnet build -c Release -r win-x86
foo.xml is copied only for a x-64 build whereas foo.txt is copied for both RID's

Categories