.NET Core 6.0 standalone binary compilation - c#

I'm trying to create a .NET Core 6.0 binary as a standalone, with all dependencies packaged in one .exe file.
The trouble I am having is that whilst the binary compiles ok it is reliant on the DLLs placed in the Release/Debug folder.
I have tried compiling from the command line with
dotnet publish --standalone
but in that instance I just get a similar issue with a load more DLLs and the binary itself is the same size and needs to be in that folder to run.
Is what I'm looking for even possible and if so how can this be achieved? I have tried with Visual Studio, dotnet cli and Rider so far.
There are a number of old solutions that mention solutions such as ilmerge but this appears to have been long since deprecated and is no longer maintained.
-- EDIT for future me:
Final solution looked like this, thanks to Andrew's answer below.
My final project.csproj file looked like this based on MS Docs
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>net6.0-windows</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<PublishSingleFile>true</PublishSingleFile>
<EnableCompressionInSingleFile>true</EnableCompressionInSingleFile>
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
<PublishReadyToRun>true</PublishReadyToRun>
</PropertyGroup>
Publish either via Visual Studio GUI or:
dotnet publish -c release -r win-x64

I'd suggest looking at https://learn.microsoft.com/en-us/dotnet/core/deploying/single-file which should hopefully be up to date. I believe the key bit is <PublishSingleFile>true</PublishSingleFile> in the .csproj.

Related

.NET 4.8 not creating a self-contained file for Linux

I have a a little .NET Core console application that I would like to make a self-contained file of. Not only that, I would also like to create a self-contained file that will run on CentOS.
The issue I am having is when I run dotnet publish -r linux-x64 -c release --self-contained true I get multiple files and the files seem to be configured for Windows only. I also tried removing <OutputType>Exe</OutputType>. This makes sure there isn't any EXE file file when publishing, but I still get multiple files that I am not sure if they can even run on CentOS since they are only .dll files. My target framework is set to <TargetFramework>net4.8</TargetFramework>.
Here are some visuals of the output I am getting:
Having <OutputType>Exe</OutputType> set in my .csproj:
Having <OutputType>Exe</OutputType> removed:
As pointed out by Jonathon Chase and Herohtar, I targeted the wrong framework. The framework I used (net4.8) is Windows only.
The correct framework to use would be something like netcoreapp3.0.

Wpf .Net Core 3 <PublishSingleFile> Builds but won't run

I am working inside of a WPF application that I created using a preview version of VS 2019. This WPF app is running .net 3.0 and everything is fine and such. I can debug the application and everything works all nice. I publish it using the Publish util inside VS and I have the settings as such:
Release
netcoreapp3.0
Self-Contained
win-x64
I then added this to my .csproj file
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>netcoreapp3.0</TargetFramework>
<UseWPF>true</UseWPF>
<PublishSingleFile>true</PublishSingleFile>
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
</PropertyGroup>
This will compile and even builds a single executable which is awesome. The problem is when I click to run this new executable nothing happens, no errors, no windows, it just fails to launch.
EDIT:
I compiled it to a regular console window executable and I can now see an error. I have files that need to be copied into the directory like appsettings.json files. They are marked to be copied but because of the single file settings they aren't or are somehow being bundled with the exe.

Deploying C# Program as a Command Line Utility

I wrote a pretty simple program in C# to automatically generate csv files of a specific format from data from other spreadsheets, and I'd like to deploy it as a command line interface utility, i.e a .exe file that can be run outside of VS Code, the IDE I'm using. I have the dotnet sdk tools installed, and I tried using dotnet msbuild with the .csproj file below:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<Configuration>Release</Configuration>
<RuntimeIdentifiers>win10-x64</RuntimeIdentifiers>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp2.1</TargetFramework>
</PropertyGroup>
</Project>
The command dotnet msbuild in the terminal built into VS Code generates a folder in bin called release that contains a .dll file, but not a .exe file. What parameters can I add to dotnet msbuild to generate a .exe file, or do I have to use another tool?
EDIT: I checked Build .NET Core console application to output an EXE?
and tried dotnet publish -c Release -r win10-x64 and got this error: Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host.
SOLUTION: msbuild was the wrong tool to use-- I believe csc is the correct tool, as it created an application file.
msbuild was the wrong tool to use-- I believe csc is the correct tool, as it created an application file.

Nuget MsBuild Integration - Snapshot and Release versioning

Currently we are evaluating NuGet tool for our dot net project built on framework 4.6.2 using VS2017. Our goal is to refer our common libraries in our solution as reference (like Maven dependencies) pulling it from internal nexus repository.
We are familiar with maven concepts like snapshot and release. We would like to achieve the same using NuGet tool. Brief search on internet says this is not supported in Nuget. Any pointers to do it in elegant way for dotnet projects with NuGet?
Any assistance in this regards is appreciated. Thanks
Using the new SDK-based project system, NuGet and MSBuild are integrated. There currently isn't a project template for this in VS2017 but you can create a .NET Standard library and change the <TargetFramework> value in the .csproj file to:
<TargetFramework>net462</TargetFramework>
Then you need to define a version number for your library. This can be done through setting a Versionproperty OR setting a combination of VersionPrefix and VersionSuffix property that are combined during build. For CI-szenarios, you usually want to set only the VersionPrefix value in your .csproj file, inside of a <PropertyGroup> element:
<VersionPrefix>1.2.3</VersionPrefix>
This can also be set inside a Directory.Build.props file in the solution directory to have a single place to set the property for all projects in one place:
<Project>
<PropertyGroup>
<VersionPrefix>1.2.3</VersionPrefix>
</PropertyGroup>
</Project>
When building through CI or locally, you can set the VersionSuffix property through command line, the pack command of the dotnet cli offers a convenience option for this:
dotnet pack -c Release --version-suffix SNAPSHOT
Alternatively, the same result can be accomplished when using the VS version of MSBuild via the Developer Command Prompt:
msbuild /t:Pack /p:Configuration=Release /p:VersionSuffix=SNAPSHOT
Currently (VS 2017 15.2, .NET CLI 1.0.*), there is a bug when having multiple projects that reference each other - the dependency versions aren't generated with a the specified version suffix. There is a workaround: Perform an additional restore before packing using the same property:
dotnet msbuild "/t:Pack;Restore" /p:Configuration=Release /p:VersionSuffix=SNAPSHOT
On your CI system you would typically overwrite the Suffix with a build number to generate a version like 1.2.3-ci-20170102 or just generate SNAPSHOT / PREVIEW etc. packages.
Since msbuild allows for scripting, you can also extend the csproj file to set the version suffix automatically if some conditions are met - e.g. always generate a suffix for debug builds so you don't accidentally publish a debug build.
<VersionSuffix Condition=" '$(Configuration)' != 'Release' ">SNAPSHOT</VersionSuffix>

Setup exe file version when publishing with dotnet

I have a net core consoleapp project, as follows (VS 2017 style):
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp1.1</TargetFramework>
<Version>2.0.0</Version>
<AssemblyVersion>3.0.0.0</AssemblyVersion>
<FileVersion>4.0.0.0</FileVersion>
<RuntimeIdentifiers>win10-x64</RuntimeIdentifiers>
<RuntimeFrameworkVersion>1.0.4</RuntimeFrameworkVersion>
</PropertyGroup>
</Project>
I can build the project without any issues, I can publish it using dotnet publish -r win10-x64 and it will generate an exe file together with the dll file. My problem is that the exe file has some strange FileVersion and ProductVersion fields (in my case FileVersion = 1.0.1.4500 and ProductVersion 1.0.1.cee57... (some guid)). Also the rest of the file details (name, copyrights) are related to dotnet instead of my own project.
Is there any way I can control the exe details when publishing?
No, the main build output of your project still is a .dll file, the .exe (or linux, mac executables) file is a copied and renamed dotnet.exe (or in case of upcoming 2.0 versions, apphost.exe with the dll name to run embedded).
The exe file is only a helper that boots the runtime and then loads your dll. However, you can try to use binary editing tools like editbin.exe (VS C++ Tools) to modify the file after publishing.
Dotnet core 3.0 added the functionality of versioning the shim exe during publish, like OP was expecting. It should work out of the box now. However that feature does not function if running builds on a Nanoserver based docker environment.
warning NETSDK1074: The application host executable will not be
customized because adding resources requires that the build be
performed on Windows (excluding Nano Server)

Categories