Compile a .NET Core application as an EXE file using Visual Studio 2017

.Net CoreVisual Studio-2017

.Net Core Problem Overview


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>

.Net Core Solutions


Solution 1 - .Net Core

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.

Solution 2 - .Net Core

In Visual Studio 2017:

  1. Right click on your project and select Publish (In Visual Studio 2019, click on menu BuildPublish <projectName>)
  2. Select 'Folder' and create a new profile
  3. In tab 'Publish', click 'Configure...'
  4. Select Deployment Mode: Self-contained, Target Runtime: win-x86 (or win-x64)
  5. Save
  6. Publish

In the folder <Your project>\bin\Debug\netcoreapp2.1\win-x86\ you will see the EXE file:

Publish settings

Solution 3 - .Net Core

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).

Solution 4 - .Net Core

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.

Solution 5 - .Net Core

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.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionajawad987View Question on Stackoverflow
Solution 1 - .Net CoreMartin UllrichView Answer on Stackoverflow
Solution 2 - .Net CoreR.TitovView Answer on Stackoverflow
Solution 3 - .Net CoreMarcell TothView Answer on Stackoverflow
Solution 4 - .Net CoreMaxim SaplinView Answer on Stackoverflow
Solution 5 - .Net CoreAndrew SavinykhView Answer on Stackoverflow