Publish ONE executable file - c#

Is there a possibility to publish .NET Core Console Application as single file (no matter if it's EXE or DLL)?
I am using .NET Core 1.1 but I am elastic to port my project to another version.

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 a deps.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.

Related

C# .NET 6.0 - exe only?

Hey I switched from NET Framework 4.8 to .NET 6.0
When I build my file it outputs the build.exe (130kb) and an build.dll (2.3mb).
So it looks like the exe is using the dll to run as the dll has the source code inside and the .exe doesn't.
Is it possible to build an .exe only without the dll?
I tried to use a Costura Fody an resource embedder but that didn't work.
Edit:
I was able to use the "publish" feature to create a self contained exe but the file size increased from 3mb to an 180mb exe... Is there any other method?
You probably want a single file framework dependent deployment and not "self contained". This way you would not have to include all the framework file in your deployment package, instead the computer would have to have the framework already installed. To do this, change deployment mode in the deployment settings from self contained to framework dependent. See Single file deployment
You might also check out "trimming" to remove unneeded dependencies, since this should significantly reduce the size of a self contained application.
Your observation is right.
The .exe file of a .NET core app is only a stub loader. The actual code is in the .dll file. For the application project, you now have both an application.dll and an application.exe.
Unless you use any of the options you mentioned (deploy as single file), I don't think there's a way around this.

Is there a way to restrict .NET Core projects to generate only .dll as output files when using .NET Core 3.1 sdk

When i build my .NET Core Console Application using .NET Core 3.1 sdk,it generates both .exe as well as .dll as output. When i was using .NET Core 2.1 it was generating only .dll as output. Is there a way to restrict .NET Core 3.1 sdk to generate only .dll as output?
You can control this with the UseAppHost MSBuild setting:
The UseAppHost property was introduced in the 2.1.400 version of the .NET Core SDK. It controls whether or not a native executable is created for a deployment. A native executable is required for self-contained deployments.
In .NET Core 3.0 and later versions, a framework-dependent executable is created by default. Set the UseAppHost property to false to disable generation of the executable.
<PropertyGroup>
<UseAppHost>false</UseAppHost>
</PropertyGroup>
If you want to disable this when building from the command line, instead of setting it within the .csproj, pass the property as an argument. For example:
dotnet build /p:UseAppHost=false
In .NET, the difference between a .exe and a .dll is actually very small. .exe tend to be little more then .dll's with some bootstrap code and a start point (the class whose main method is to be called).
You can use both .NET .exe and .dll as project references. There might be some difference in some fringe details like COM interop, but I do not expect it.
What exactly the compiler will build, depends on it's inputs. Wich includes the project settings. There is a special type of project for library. And with version changes, the proper reading of projects files could be broken. And of course the option that some code is "seperated out" into a .dll is also there. Most programms nowadays are more .dll's then executeables. And it can be beneficial to keep .exe small.

Is there a way to make a console application run using only a single file in .NET Core?

In .NET framework, you can make a single .EXE file that will run from the command line without having any extra config files (and if using ILMerge, you can put all .DLL references into the 1 .EXE assembly).
I am taking a stab at using .NET Core to accomplish the same thing, but so far without success. Even the simplest Hello World application with no dependencies requires there to be a file named <MyApp>.runtimeconfig.json in order to run using dotnet.exe.
dotnet F:\temp\MyApp.dll
The contents of the <MyApp>.runtimeconfig.json are as follows:
{
"runtimeOptions": {
"framework": {
"name": "Microsoft.NETCore.App",
"version": "1.1.1"
}
}
}
Without this config file in the same folder as the .DLL, I get the following error:
A fatal error was encountered. The library 'hostpolicy.dll' required to
execute the application was not found in 'F:\temp'.
My question is: Is there some way to change the application so it doesn't require this config file to be present, so that the defaults of this information are compiled within the .DLL but can be overridden by adding the config file?
NOTE: I also want to ensure it "just works" regardless of the platform it is installed on it provided the platform has the right version of .NET Core.
Background
I am trying to get a smooth user experience for running some utilities that are useful sometimes, but are rarely ever needed. Since it doesn't appear to be possible to use the same .DLL that is referenced from a client application as a console application, the next best thing would be to have a single file that could be downloaded and run without any dependencies.
For example, in Java you can simply download a .jar file on any supported platform and run:
java <package>.jar <namespace>.SomeClass [args]
and it will "just work" without any extra files. How can I get a similar user experience using .NET Core?
In a nutshell, I want to try to avoid the extra step of "unzip to a directory first"...
Update 2018: .NET Core 3.0 aims to enable a new scenario: packing the .NET Core runtime and all application dependencies into a single executable.
At the moment, there are no fail-safe methods to create a single executable file. Since there are a lot of type-forwarding dll files involved, even ILMerge and similar tools might not produce correct results (though this might improve, the problem is that those scenarios haven't undergone extensive testing, esp. in production applications)
There are currently two ways to deploy a .NET Core application:
As a "portable application" / "framework-dependent application", requiring a dotnet executable and installed framework on the target machine. Here, the XYZ.runtimeconfig.json is used to determine the framework version to use and also specifies runtime parameters. This deployment model allows running the same code on various platforms (windows, linux, mac)
As a "self-contained application": Here the entire runtime is included in the published output and an executable is generated (e.g. yourapp.exe). This output is specific to a platform (set via a runtime identifier) and can only be run on the targeted operating system. However, the produced executable is only a small shim that boots the runtime and loads the app's main dll file. This also allows an XYZ.runtimeconfig.json to set additional runtime properties like garbage collection settings.(think of it as a "new" app.config file)
In the future, the CoreRT runtime – which is still under development at the time of writing – aims to allow creating a single pre-compiled native executable that is specific to a runtime and does not require any other files.
Tested with .NET Core 2.2 on a console app:
Reference Microsoft.DotNet.ILCompiler package in your output project. You'll need to add MyGet package repository in Visual Studio settings. *
Publish the project via command line,
dotnet publish C:\src\App\App.csproj -c release -r win-x64 -o output-win-x64. If there's no "Desktop Development for C++" component installed, do it in Visual Studio Installer, or the command will fail.
Go to the output folder (e.g. "C:\src\App\output-win-x64") and grab the native image (.exe file).
On Windows it produced a fully functional 5Mb .exe file (compared to original self-contained publish with folder size at ~60Mb). On macOS the ILComplier though produced output without any error, the app crashed with unhandled expection (on the line with LINQ expression).
*Go to "Tools -> Options -> Package Manager -> Package Sources" and add new source at https://dotnet.myget.org/F/dotnet-core/api/v3/index.json
It is possible in .NET Core 3.0+
The feature is enabled by the usage of the following property in your project file (.csproj):
<PropertyGroup>
<PublishSingleFile>true</PublishSingleFile>
</PropertyGroup>
There are other options as well, such as packaging the pdb into the bundle, or leaving certain files out.
Documentation can be found here: https://learn.microsoft.com/en-us/dotnet/core/deploying/#publish-self-contained
True it just works:
Combine this technique with the Self Contained Deployment workflow, you can get a true "it just works" experience for your user, they don't even have to install the .NET Core runtime for your app to run.
I am currently deploying applications to my clients as single .exe files.
Read more about that here: https://learn.microsoft.com/en-us/dotnet/core/deploying/#self-contained-deployments-scd

Sharing a DLL between projects

Microsoft says it's platform neutral these days, so I'm trying to build on Mac and Linux only with VS Code and deploy to Azure. Why? It's mainly to prove that I can.
Our project has several parts which include a couple of different websites, a Web API, er API and a few other bits. On my Mac I've built a .Net Core Class Library with a load of objects in. Command line, dotnet build, DLL out, no problem.
I want to put that DLL on the Linux machine where the MVC website is being built - the objects forming the models part of that site hopefully. I cannot figure out how to get the website project to reference my DLL and use the objects.
I had assumed I copy it to the other machine, place it in the bin folder of the site being developed and reference it in the Dependencies section of the site's project.json. Nope. I saw a few articles that said .Net Core only works with NuGet and it had to be a package. Is that really true?
I've found and read (if not entirely understood) everything you could imagine on sharing between .net core and .net framework. This is a core-only project so not applicable. Frankly I'm lost, and something called .Net Standard has just rolled into my field of vision.
So instead of copying the DLL, use dotnet pack to build a nuget package on your Mac, and copy that to your Linux machine instead. Put it in a directory that you configure as a local nuget repository (no server or anything required) and you're away.
I agree it's not as straightforward as a reference to a DLL, but it's not too bad. Note that you'll need to version the package appropriately, so that the tool system can detect when it's changed.

What do I need to run a program that uses Roslyn API?

I'm a newbie to Roslyn compiler services, I would like to create an .exe with .net full or .net core which can call Roslyn API, that program must run on a machine that does not have installed Visual Studio, I just want to distribute (copy/paste) the .exe and it should work.
I have no idea what programs must be installed on that machine to my .exe can work properly (making calls to Roslyn API).
Can it run only with .net framework installed?
Most of Roslyn is just a library, so if you build a project that references the Roslyn NuGet packages, it will compile into a directory of files that are all you need to run the application (assuming you have the appropriate version of .Net Framework or .Net Core installed).
If you really want just a single EXE file, you will need a tool that combines an application and its dependencies into a single file, like ILMerge.

Categories