What is the content of .Net publish resulting exe? - c#

I published a small C# .Net Core 2.2 console application as executable using the following command from this post:
dotnet publish -c Release -r win10-x64
The generated files contain both the classic ConsoleApp.dll, but also the executable that I was expecting to be generated ConsoleApp.exe.
My question is why there was still the DLL generated, since all its code, I suppose, could have been compiled to the .exe, as in a .Net Framework application?
On the other hand, I tried to decompile the .exe file with ILSpy but the content from it does not seem to be managed code. In this case I also suppose that the .exe file is just calling the DLL using the dotnet command. Is this assumption right?
Below is the Console Application .csproj file content:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp2.2</TargetFramework>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<PlatformTarget>AnyCPU</PlatformTarget>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="System.Management" Version="4.7.0-preview3.19551.4" />
</ItemGroup>
<ItemGroup>
<None Update="input.txt">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>
</Project>

Very interesting question. I'll try to cover it as much as I possibly can.
With the introduction of .net core 3.0 came the Single file publish as described in the design documentation of .Net. So If you have a .net 3.0 application then you can use the /p:PublishSingleFile=true to bundle everything in a single executable.
Watch out for the /p:PublishTrimmed=true option, as treeshaking can and probably will cause problems with reflection code, as access to it is not covered by the tree shaking.
For previous versions of net core, you need to use one of the packagers like wrap or Costura.
As per the exe file, I'll mention somthing from the wrap documentation:
The final self-contained single binary application consists of two
parts: 1) runner and 2) the compressed target application executable
and dependencies.
The dll that is created by the standard publisher is multi platform and non specific to windows. So the executable file has all the code needed to create the process in windows and call the actual code that is in the dll that can be used on any platform. It's just a wrapper.
More information about the executable Microsoft .net core deploying docs
Self-contained deployment. Unlike FDD, a self-contained deployment
(SCD) doesn't rely on the presence of shared components on the target
system. All components, including both the .NET Core libraries and the
.NET Core runtime, are included with the application and are isolated
from other .NET Core applications. SCDs include an executable (such as
app.exe on Windows platforms for an application named app), which is a
renamed version of the platform-specific .NET Core host, and a .dll
file (such as app.dll), which is the actual application.

I am not sure about your assumption. But use the following command it will generate only two files, one is .exe and other is .pdb in the publish directory inside win10-x64 directory.
dotnet publish -r win10-x64 -c Release /p:PublishSingleFile=true /p:PublishTrimmed=true

Related

Publish .NET Core app without EXE and runtimes

My question is more academic than a real problem: .NET Core has three different publish modes (see here). I'm interested in framework-dependent deployment (FDD) and framework-dependent executable (FDE).
As far as I understand, with framework-dependent deployment the publish folder will contain the project DLL, 3rd party DLLs and the runtimes. The app can only be started via dotnet run.
Using framework-dependent executable, the publish folder will contain the project DLL, the project EXE and 3rd party DLLs, but no runtimes. The app can be both launched via the EXE or dotnet run.
Now I'd like to host an ASP.NET Core Web API within IIS. The .NET Core runtime is installed system-wide. So I don't need the EXE and the included runtimes, but both FDE and FDD contain either one of them.
Now my question: is there any publish mode so that the publish folder contains a mixture of FDE and FDD, i. e. the DLL, 3rd party DLLs, no EXE and no runtime?
changing application .csproj file like below prevents exe to be written to publish path:
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<UseAppHost>false</UseAppHost>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
Here <UseAppHost>false</UseAppHost> makes trick

Enviroment.GetCommandLineArgs()[0] is a .dll file insted of of an .exe file [duplicate]

I created a .NET Core application (v1.1) in Visual Studio 2017. When I compile it, I get a DLL file produced instead of the expected EXE file for the built project. I did check the csproj file and confirmed the output type is set to exe, but no dice.
Why is Visual Studio 2017 is still producing a DLL file?
I'm sure it's a quick setting somewhere that I forgot...
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp1.1</TargetFramework>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<PlatformTarget>AnyCPU</PlatformTarget>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\Core.EF.SqlServer\Core.EF.SqlServer.csproj" />
</ItemGroup>
</Project>
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 .dllfiles. 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.
In Visual Studio 2017:
Right click on your project and select Publish (In Visual Studio 2019, click on menu Build → Publish <projectName>)
Select 'Folder' and create a new profile
In tab 'Publish', click 'Configure...'
Select Deployment Mode: Self-contained, Target Runtime: win-x86 (or win-x64)
Save
Publish
In the folder <Your project>\bin\Debug\netcoreapp2.1\win-x86\ you will see the EXE file:
Starting with .NET Core 2.2 you can build framework-dependent executables
Although building a self-contained deployment can be a good solution, it has its own drawbacks. (See R.Titov and Martin Ullrichs' answers on SCD-s.)
Fortunately, .NET Core 2.2 supports the building of so called framework-dependent executable-s, that are essentially a wrapper binary (.exe on Windows) around the standard dll-s.
This way you have all the advantages (and disadvantages) of the standard framework-dependent deployment (again, see Martin's answer), but you have a convenient way to launch it, without having to call it through the dotnet CLI.
You can publish your app as a Framework-Dependent Executable using the following syntax:
dotnet publish -c Release -r <RID> --self-contained false
Where RID is the usual runtime identifier, e.g. win-x64 or whatever platform you wish to build for (see the catalog here).
That's how you do a self-contained publish with command-line in any OS:
dotnet publish C:\src\App\App.csproj -c release -r win-x64 -o output-win-x64
Besides, you might want to get the output decreased from typical ~60 MB for a simple Hello World app to ~30 MB by using ILLink.
Also, you might want to go further and get a single .exe file of a size at around 5 MB and use ILCompiler. See this reply.
The other answers are good, but what I find sometimes convenient is:
Not have it self-contained because the target machine is likely to have .NET Core of the correct version installed. This cuts on number of the DLL files I need to ship.
Not have to specify dotnet on the command line
For this, a bat file wrapper can be used, similar to these lines:
#ECHO OFF
REM see http://joshua.poehls.me/powershell-batch-file-wrapper/
SET SCRIPTNAME=%~d0%~p0%~n0.dll
SET ARGS=%*
dotnet "%SCRIPTNAME%" %ARGS%
EXIT /B %ERRORLEVEL%
If your application ends up in yourapp.dll, name the bat file yourapp.bat and place it along side the DLL file. Now instead of dotnet yourapp.dll params you can call yourapp params.
Note that the context of this answer is in-house tooling, so all the developers using the utility will have a pretty standard development machine setup. If this is to be distributed to an external customer who is running who knows what on their boxes, the self-contained option is far superior.

Compile a .NET Core project to .exe file instead of .dll file [duplicate]

This question already has answers here:
Build Visual Studio project through the command line
(4 answers)
Closed 3 years ago.
I'm trying to create a C# application (.cs files). Since I'm using Visual Studio Code, I have to use the command line in order to compile the project, but when I launch MSBuild, it generates a .dll file.
MSBuild version : 15.8.169.51996
This is my .csproj:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp2.1</TargetFramework>
</PropertyGroup>
<PropertyGroup>
<LangVersion>latest</LangVersion>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Net.Compilers" Version="3.1.1">
<PrivateAssets>all</PrivateAssets>
</PackageReference>
</ItemGroup>
</Project>
Thanks in advance!
Deployment in .NET Core
Because of you are using a netcoreapp, officially called .NET Core, things are little different here.
.NET Core is a cross platform framework. It's mean that software you wrote will execute in both Windows, Linux and OSX. Have you seen an .exe running on Linux? Not in the usual way..
After you understand this, you have several options:
Use the .dll as expected. With . NET Core, you run your .dll by the command dotnet your.dll.
You can use the SCD deployment and set the RuntimeIdentifier to be win10-x64.
You can upgrade to .NET Core sdk 2.2 (netcoreapp2.2) and use the FDE deployment.

multi-platform native libraries in C# nuspec

We have a C# project (.net Core) which is cross-platform. It uses native libraries (C++), which are different for each platform.
We know that you can specify different frameworks in a single nuspec file, but this case is different:
There will be a single C# DLL file
There will be different native libraries (like a.linux.so and a.windows.dll)
We want be able to install only the libraries that are pertinent to a specific OS.
What is the recommended mechanism?
First, make sure you are using SDK-based projects to ensure you get correct dependency trimming for target frameworks like netstandard* (instead of using a .nuspec file).
The goal is to separate your native runtime assets into a runtimes subfolder inside your NuGet folder so that the layout is:
\lib\YourManagedCode.dll
\runtimes\win-x86\native\some.dll
\runtimes\win-x64\native\some.dll
\runtimes\linux-x64\native\libsome.so
\runtimes\osx-x64\native\some.dylib
An example project file could look like this, assuming you already have runtimes folder:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<None Update="runtimes\**" Pack="true" PackagePath="runtimes" />
</ItemGroup>
</Project>
If you need to test locally, you can also add CopyToOutputDirectory="PreserveNewest" to ensure the files are copied to the output. .NET Core should be able to resolve files located in runtimes directories for methods annotated with [DllImport("some")].
The resulting NuGet package can be referenced from both .NET Core and .NET Framework projects. If some "RID-fallback" (e.g. win10-x64 => win-x64) does not work on .NET Framework projects, make sure this project also references a recent version of the Microsoft.NETCore.Platforms package (it provides NuGet with a graph of known values, has nothing much to do with .NET Core itself..).

I can use csc.exe to compile one cs file to a dll in .net framework...but how can i do this in dotnet core by dotnet cli?

In .net framework i can use csc.exe to compile one cs file to a dll file.
C:\WINDOWS\Microsoft.NET\Framework\v1.1.4322\csc.exe /t:library /out:MyCScode.dll *.cs /debug /r:System.dll /r:System.Web.dll /r:System.Data.dll /r:System.Xml.dll
How can i do this in dotnetcore ?
At a minimum you'll need a .csproj file with this content:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
</PropertyGroup>
</Project>
That is assuming you'll be targeting netstandard2.0 which would allow your library to run on .NET Framework 4.6.1, .NET Core 2.0 and any other runtime that implements the standard.
And also have downloaded the .NET Core 2.0 SDK.
Unlike the old csproj, there's no need to add the individual .cs files to compile them.
So on a directory with such content:
Class1.cs
Class2.cs
Project.csproj (with the content mentioned above)
Simply running: dotnet build will output a dll at the bin folder as you'd expect.
It's worth mentioning that the .NET Core CLI have templates for ASP.NET Core, class library, xUnit test project, etc:
$ dotnet new classlib
Would give you the csproj and a first class file.
You can use dotnet build to build your project for asp.net core

Categories

Resources