Douglas Gaskell
Douglas Gaskell

Reputation: 10030

Build .Net Core as an EXE not a DLL

I want to build a .NET Core project as a EXE and not a DLL so it can be executed.

The answer here did not work: How to run a .Net Core dll?

Here is the sample code:

using System;

namespace ConsoleApplication
{
    public class Program
    {
        public static void Main(string[] args)
        {
            Console.WriteLine("Hello World!");
        }
    }
}

Here is my project.json:

{
  "version": "1.0.0-*",
  "compilationOptions": {
    "emitEntryPoint": true
  },
  "buildOptions": {
    "debugType": "portable",
    "emitEntryPoint": true
  },
  "dependencies": {},
  "frameworks": {
    "netcoreapp1.1": {
      "dependencies": {
        "Microsoft.NETCore.App": {
          "type": "platform",
          "version": "1.1.0"
        }
      },
      "imports": "dnxcore50"
    }
  }
}

I'm currently using VSCode, whenever I build the project with the build task, or run dotnet restore I just get a .dll in my bin/Debug folder.

How do you build a .NET Core application as an exe?

Bonus: I do, will that run on a mac or other device?

Upvotes: 20

Views: 29476

Answers (3)

DGF
DGF

Reputation: 370

The accepted answer states that:

To produce an EXE instead of a DLL, you need a self-contained deployment.

However, you can produce an executable while publishing your app as framework-dependent. In .NET application publishing overview - Produce an executable:

Executables aren't cross-platform, they're specific to an operating system and CPU architecture. When publishing your app and creating an executable, you can publish the app as self-contained or framework-dependent. Publishing an app as self-contained includes the .NET runtime with the app, and users of the app don't have to worry about installing .NET before running the app. Publishing an app as framework-dependent doesn't include the .NET runtime; only the app and third-party dependencies are included.

For example, these MSBuild properties would produce both a native executable for linux x64 and a dll:

<RuntimeIdentifier>linux-x64</RuntimeIdentifier>
<SelfContained>false</SelfContained>
<TargetType>exe</TargetType>

Note: While dll's are meant to be cross-platform, a dll produced with these options are NOT guaranteed to run in a different OS besides the one specified. This happens because as mentioned in .NET application publishing overview - Platform-specific and framework-dependent:

If the app uses a NuGet package that has platform-specific implementations, only the targeted platform's dependencies are copied. These dependencies are copied directly to the publish folder.

While technically the binary produced is cross-platform, by targeting a specific platform, your app isn't guaranteed to run cross-platform. You can run dotnet <filename.dll>, but the app may crash when it tries to access platform-specific dependencies that are missing.

You can verify that by running one of the following on Linux:

  • cat /proc/<executable-pid>/maps
  • lsof -p <executable-pid>

The output will show a bunch of loaded Microsoft dll's from /usr/share/dotnet/shared.

Upvotes: 0

renaissanceMan
renaissanceMan

Reputation: 433

I think most people got to this page because they picked .net core and they can't get an executable .exe file from their VS 2017/VS 2019 build. vs 2015 always used to make a .exe file for a console application. With vs 2017/vs 2019 when you create the project you get 2 choices for a Console application. One is Console App (.NET Core) and the other choice is Console App (.NET Framework). If you pick the .NET Core option you are going to have to move heaven and earth to get a .exe file from your Build. The (.NET Core) option creates a .dll file from a Build. If you pick the (.NET Framework) option it will build a xxxx.exe executable for you by default.

Upvotes: 9

Shaun Luttin
Shaun Luttin

Reputation: 141442

To produce an EXE instead of a DLL, you need a self-contained deployment. What you are currently doing is a framework-dependent deployment. To convert yours to self-contained, take the following steps in your project.json file.

  1. Remove "type": "platform".
  2. Add a "runtimes" section for the operating systems your app supports.

When you build, pass in the target operating system. E.g. dotnet build -r osx.10.10-x64.

This is the resultant project.json

{
  "version": "1.0.0-*",
  "compilationOptions": {
    "emitEntryPoint": true
  },
  "buildOptions": {
    "debugType": "portable",
    "emitEntryPoint": true
  },
  "dependencies": {},
  "frameworks": {
    "netcoreapp1.1": {
      "dependencies": {
        "Microsoft.NETCore.App": {
          "version": "1.1.0"
        }
      },
      "imports": "dnxcore50"
    }
  },
  "runtimes": {
    "win10-x64": {},
    "osx.10.10-x64": {}
  }
}

See also: https://learn.microsoft.com/en-us/dotnet/articles/core/deploying/#self-contained-deployments-scd

Upvotes: 7

Related Questions