Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

dotnet new console, publish, makes a dll not an exe #8065

Closed
danmosemsft opened this issue Apr 4, 2017 · 137 comments
Closed

dotnet new console, publish, makes a dll not an exe #8065

danmosemsft opened this issue Apr 4, 2017 · 137 comments
Assignees
Milestone

Comments

@danmosemsft
Copy link
Member

@danmosemsft danmosemsft commented Apr 4, 2017

C:\PLAy\asdf>dotnet --version
2.0.0-preview1-005694

C:\PLAy\asdf>dotnet new console
The template "Console Application" was created successfully.

C:\PLAy\asdf>dotnet restore

...
C:\PLAy\asdf>dotnet run
Hello World!

C:\PLAy\asdf>dotnet publish
Microsoft (R) Build Engine version 15.2.47.30403
Copyright (C) Microsoft Corporation. All rights reserved.

  asdf -> C:\PLAy\asdf\bin\Debug\netcoreapp2.0\asdf.dll

Shouldn't I have a console .exe? How do I run this dll?

@omajid

This comment has been minimized.

Copy link
Member

@omajid omajid commented Apr 4, 2017

Does dotnet bin\Debug\netcoreapp2.0\asdf.dll work?

Edit: dotnet publish --self-contained should generate an exe, though: dotnet/cli#6234

@benaadams

This comment has been minimized.

Copy link
Member

@benaadams benaadams commented Apr 4, 2017

If you add

<RuntimeIdentifier>win7-x64</RuntimeIdentifier>

you get a apphost.exe as only exe but when you run it it says it

This executable is not bound to a managed DLL to execute. The binding value is: 'c3ab8ff13720e8ad9047dd39466b3c8974e592c2fa383d4a3960714caef0c4f2'
A fatal error was encountered. This executable was not bound to load a managed DLL.

and you have to run it with dotnet xxx.dll which isn't expected

e.g. if you were following UsingYourBuild.md#change-project-to-be-self-contained from coreclr

@danmosemsft

This comment has been minimized.

Copy link
Member Author

@danmosemsft danmosemsft commented Apr 4, 2017

@omajid yes,

C:\PLAy\asdf>dotnet bin\Debug\netcoreapp2.0\asdf.dll
Hello World!

The project does contain <OutputType>Exe</OutputType> so I guess the bug is that it doesn't work.

@dasMulli

This comment has been minimized.

Copy link
Contributor

@dasMulli dasMulli commented Apr 4, 2017

.net core apps aren't supposed to be ".exe" files as this is a windows concept. When a portable app is published, the resulting .dll is supposed to be run on the target platform through dotnet app.dll which will then use the platform-specific runtime.

In project.json, the property was emitEntryPoint: true. In csproj, <OutputType>Exe</..> has existed before and should rather be interpreted as Executable rather than .exe file..

Tooling already exists for OutputType, yet it would be more clear if there was <Runnable>true</..> (which would internally just set the output type).

@livarcocc

This comment has been minimized.

Copy link
Contributor

@livarcocc livarcocc commented Apr 4, 2017

The important concepts here are that of a portable app (which is what you get by default) and self-contained apps (which are the ones for which an exe is produced).

A portable app is an application that runs independently of the platform and require that you have the shared framework installed. When you published it, the shared framework bits are not copied to the publish folder, including the native host. So, in order to run it, you need to do dotnet <path_to_your_dll>. dotnet in this case is the native piece, the host.

For self-contained apps, when you publish it you need to specify a RID (the distro you want to publish to, so that we know which native pieces to copy). In this case, because we will know your distro, we will generate an exe for you that you can then use for that specific platform.

This is a by design behavior.

@livarcocc livarcocc closed this Apr 4, 2017
@danmosemsft danmosemsft reopened this Apr 11, 2017
@danmosemsft

This comment has been minimized.

Copy link
Member Author

@danmosemsft danmosemsft commented Apr 11, 2017

Can we reduce the confusion somehow? I work on .NET Core and I was confused.

  1. <OutputType>Exe</OutputType> reads exe but does not correspond to an exe. That's clearly confusing. Are we really out of options due to back compat? Why?
  2. Console Application is the name of the template. For 15 years in .NET that has meant an .exe. Can we call the template something else, that's meaningful?

@terrajobst

@livarcocc

This comment has been minimized.

Copy link
Contributor

@livarcocc livarcocc commented Apr 11, 2017

Sorry for the confusion.
The concept of portable and self-contained applications are actually old concepts in the .net core world. We have had it for a while. I think one part of the confusion is the expectation that .NET Core should be similar to .NET Framework, which it is not.

You can read more about portable and self-hosted apps here: https://docs.microsoft.com/en-us/dotnet/articles/core/deploying/.

Also, at this point, I don't see how we could make changes to this without causing breaks for everyone building applications for .NET Core right now.

@richlander

This comment has been minimized.

Copy link
Member

@richlander richlander commented Apr 11, 2017

@danmosemsft This isn't new ... was in 1.x, too. It also isn't a compat thing. We have choices here, but most of them come back to this experience as the best choice. It's one of those "this experience has three awesome characteristics (drawn as a triangle) ... pick 2".

Here are the characteristics you can choose from.

  1. Cross-platform applications (meaning you can take the folder and run on Windows, macOS and Linux), provided .NET Core is installed there).
  2. Produces an exe (whatever "exe" means on your OS) by default (what you are asking for).
  3. Produces an app that doesn't require .NET Core installed.
  4. Small apps.

You can have all of them, but not all of them can be the default. I also lied. You can pick two of the 4. So, today, the default is 1 and 4. Standalone gives you 2 and 3 and you give up and 1 and 4. We could have an experience that was 2 and 4 but we don't. We could do it in such a way that you don't give up on 1 (with scripts). It's all a question of what the base of the process should be.

I'm being somewhat vague because I want you to think about the characteristics and determine for yourself why this is the case. I'm not going to explain it. It's important to have the "a ha" moment on what "dotnet publish" really means.

Thoughts?

@danmosemsft

This comment has been minimized.

Copy link
Member Author

@danmosemsft danmosemsft commented Apr 11, 2017

That all makes sense -- the same project will only make an actual .exe or equivalent iff you choose standalone aka self-contained. Once you make an .exe or equivalent, you made your app runtime specific.

I think @dasMulli 's suggestion that ideally <OutputType>Exe</OutputType> in the 2.0 templates could be <Runnable>true</Runnable> which the targets just translated. But I'm going to guess that would involve a VS update to know to write the new name.

It is unfortunate that I'm not the only person who will have to go through this learning process :) Feel free to close

@benaadams

This comment has been minimized.

Copy link
Member

@benaadams benaadams commented Apr 11, 2017

Would have gone for 2 for <OutputType>Exe</OutputType> and give a (very informative) publish error if target runtime not specified.

Rather than sticks a bunch of dlls in an output folder and not actually produce an "exe".

Windows world use case: publish; open folder, what to double click on to run?

@benaadams

This comment has been minimized.

Copy link
Member

@benaadams benaadams commented Apr 11, 2017

Do understand the difficulty that that "exe" wouldn't be portable though 😢

@benaadams

This comment has been minimized.

Copy link
Member

@benaadams benaadams commented Apr 11, 2017

Could you output multiple?

dotnet publish

outputs

MyApp.dll
MyApp.exe
MyApp rwxrwxr--

@richlander

This comment has been minimized.

Copy link
Member

@richlander richlander commented Apr 12, 2017

@benaadams Good idea, but I'd rather not. While, this would allow all scenarios by default, I think we'd have a different class of confusion. For example:

  • Can I use MyApp on both Linux and Mac?
  • Why doesn't MyApp.exe work on 32-bit windows?
  • Why doesn't MyApp.exe work on Mac?

That all said, it's very obvious that the current situation is not great.

I'll put one stake in the ground ...

Deployment choices should not be specified in the project file. The corollary of this is that multiple deployment options should be possible from one project file.

I continue to think that the launcher case (and also the cross-plat scenario) should be the default and the exe case should be opt-in. That said, it should be much easier and intuitive to do so than it is now. Also, EXE and standalone don't need to be conflated.

Fair?

@richlander

This comment has been minimized.

Copy link
Member

@richlander richlander commented Apr 12, 2017

@danmosemsft The primary problem isn't VS updates. It's that the EXE output type really means "application". It's the entry point into a variety of publishing types. It doesn't mean ".exe". If we're going to change something, I'd make it "app", which would make it clear that we are talking about a logical concept. Hey, that's a good idea!

The primary issue, as I said above, is that this choice isn't a project-level concern.

@benaadams

This comment has been minimized.

Copy link
Member

@benaadams benaadams commented Apr 12, 2017

dll launcher is covered; self-contained is covered; however I'd argue that there is an expectation for a targeted shared runtime exe (as you get from full framework and netcoreapp1.0-1.1)

The biggest issue with not having a local exe is the OS limitation on expressing what is running I raised as issues https://github.com/dotnet/cli/issues/6279, https://github.com/dotnet/core-setup/issues/2007

This is where the OS picks up info about what is running from the exe file e.g.

image

The exe provides an entry point for process name, process description and icon which is lost with just the launcher

@livarcocc livarcocc closed this Apr 12, 2017
@svick

This comment has been minimized.

Copy link

@svick svick commented Apr 12, 2017

Would it make sense to include a platform-independent launcher with a framework-dependent application?

I can imagine doing that by creating a shell script that calls dotnet (for Unix) with a unique extension (for Windows).

Specifically, running dotnet publish for framework-dependent deployment would create something like MyApp.dotnet with the contents of:

#!/bin/sh
dotnet MyApp.dll

On Linux and macOS, this should run the installed version of .Net Core. On Windows, the .dotnet extension would be registered with dotnet.exe, which would ignore the contents of the file and execute MyApp.dll.

This way, double-clicking MyApp.dotnet on Windows and ./MyApp.dotnet on Unix would both work.

@mellinoe

This comment has been minimized.

Copy link

@mellinoe mellinoe commented Apr 12, 2017

It's a clever idea, but I don't know if it's worth it for the relatively small benefit. I'm also worried that getting into the business of OS file associations is going to be clunky and bug-ridden, but maybe that's just my pessimism. 😄

@benaadams

This comment has been minimized.

Copy link
Member

@benaadams benaadams commented Apr 18, 2017

Actually, still not sure why this doesn't produce an exe

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <TargetFramework>netcoreapp2.0</TargetFramework>
    <IsPackable>false</IsPackable>
    <OutputType>exe</OutputType>
    <NetStandardImplicitPackageVersion>1.6.1</NetStandardImplicitPackageVersion>
    <RuntimeFrameworkVersion>2.0.0-*</RuntimeFrameworkVersion>
    <RuntimeIdentifier>win10-x64</RuntimeIdentifier>
  </PropertyGroup>

</Project>

Really not sure why it also outputs a apphost.exe that errors when you run it

publish>apphost
This executable is not bound to a managed DLL to execute. The binding value is: 'c3ab8ff13720e8ad9047dd39466b3c8974e592c2fa383d4a3960714caef0c4f2'
A fatal error was encountered. This executable was not bound to load a managed DLL.
@benaadams

This comment has been minimized.

Copy link
Member

@benaadams benaadams commented Apr 18, 2017

Ok updating to newest nightly and creating with dotnet new does create the exe

All good...

@JoseFMP

This comment has been minimized.

Copy link

@JoseFMP JoseFMP commented Jun 21, 2017

So what is the key tag to get the exe? I really do not care to run "dotnet acool.dll" but legacy tools are expecting my application to have an exe file.

@borgdylan

This comment has been minimized.

Copy link

@borgdylan borgdylan commented Jun 24, 2017

@benaadams On Linux, I am getting an apphost binary that fails as mentioned previously.

What happened to just renaming the coreconsole binary to get a working self-contained app? This new apphost methodology is a regression :/ .

@damircolak

This comment has been minimized.

Copy link

@damircolak damircolak commented Jun 28, 2017

Same question here, I do dotnet publish -c Release -r win7-x64 and I get ONLY DLL.

How to create an EXE file?

If I target win10-x64 I do get an .EXE file but it won't run on Windows 7 because of this error:

Error: assembly specified in the dependencies manifest was not found -- package:
'microsoft.codeanalysis.common', version: '1.3.0', path: 'lib/netstandard1.3/Microsoft.CodeAnalysis.dll'

After googling for hours I still don't know how to fix that error.

Does building a simple EXE file really have to be this complicated?

What have become of the mighty Microsoft?

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>netcoreapp1.1</TargetFramework>

	<RuntimeIdentifiers>
		<RuntimeIdentifiers>win10-x64;osx.10.11-x64;win7-x64;ubuntu.14.04-x64</RuntimeIdentifiers>
	</RuntimeIdentifiers>

  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Newtonsoft.Json" Version="10.0.3" />
  </ItemGroup>
</Project>
@danmosemsft

This comment has been minimized.

Copy link
Member Author

@danmosemsft danmosemsft commented Jun 28, 2017

@livarcocc for feedback above (since issue is closed)

@damircolak

This comment has been minimized.

Copy link

@damircolak damircolak commented Jun 28, 2017

Why did you close issue when it was not fixed? See my post for more details. I did check @livarcocc and it did not help at all.

@danmosemsft

This comment has been minimized.

Copy link
Member Author

@danmosemsft danmosemsft commented Jun 28, 2017

@damircolak I cited @livarcocc so he could see your comments. I think it would be better for you to open a new issue for what you're encountering.

@mattcanty

This comment has been minimized.

Copy link

@mattcanty mattcanty commented Jul 19, 2017

@damircolak did you open a new issue for this? I am experiencing the same problem.

@AronParker

This comment has been minimized.

Copy link

@AronParker AronParker commented Aug 15, 2017

Same problem here, is there a new issue regarding this yet?

@NimishDhruv

This comment has been minimized.

Copy link

@NimishDhruv NimishDhruv commented Jul 5, 2018

I have one question related to self contained deployment.

I have created two console application named "ConsoleApp1" and "ConsoleApp2". Now when I publish the solution using self contain command "dotnet publish -c release -r win7-x64" the relevant files have been generated in their project bin folder along with "ConsoleApp1.exe" and "ConsoleApp2.exe".

My question is that If my project have two executable files then do I need to copy both the publish folder to production?
Or
Is there any other way where all the lib and executable files are copied to single folder from where we can copy that folder to production?

@ylhyh

This comment has been minimized.

Copy link

@ylhyh ylhyh commented Jul 16, 2018

I have a project with COM reference, and the project must to be running in x86(32-bit) environment. so I have to use Visual Studio or MSBUILD to build the project. And I have to use:
"C:\Program Files (x86)\dotnet\dotnet.exe" MyWebApi.dll
to start it.

After I created a Publish Profile with RuntimeIdentifier and SelfContained specified, I have found that using Vistual Studio to publish the project will create an exe file named MyWebApi.exe, so I can run the exe file directly to start the web api and it will be ran in x86(32-bit) env. See the .csproj and .pubxm below:
csproj

pubxml

BUT! If I use MSBUILD to publish the project with the PublishProfile specified, it's never to create the .exe file, who can tell me WHY?

MSBuild.exe" /p:DeployOnBuild=true /p:PublishProfile=Release-winx86-SelfContained

HELP !!!

The component versions of my project:
Microsoft.AspNetCore.App (2.1.1)
Microsoft.NETCore.App (2.1.2)
Vistual Stuio 2017 15.7.3

@vijayrkn

This comment has been minimized.

Copy link
Contributor

@vijayrkn vijayrkn commented Jul 25, 2018

@ylhyh - Can you please run the following command and share the output log?

MSBuild.exe" /p:DeployOnBuild=true /p:PublishProfile=Release-winx86-SelfContained /bl

*Please remove any sensitive information from the log (if present)

@ylhyh

This comment has been minimized.

Copy link

@ylhyh ylhyh commented Jul 26, 2018

Thanks @vijayrkn. but /bl is not work

@vijayrkn

This comment has been minimized.

Copy link
Contributor

@vijayrkn vijayrkn commented Jul 26, 2018

When you pass /bl , it should create a log file in that folder, can you please share that?

@ylhyh

This comment has been minimized.

@peterhuene peterhuene reopened this Jul 27, 2018
peterhuene referenced this issue in peterhuene/sdk Aug 7, 2018
This commit changes `UseAppHost` to true for both self-contained and
framework-dependent applications.

Additionally, an implicit reference is now added for the apphost package when
building or publishing a framework-dependent application that uses the apphost.
This package reference uses the latest patch version, which ensures the apphost
is patched appropriately, while keeping the application itself targeting the 0
patch level.

Fixes dotnet/cli#6237.
@peterhuene

This comment has been minimized.

Copy link
Contributor

@peterhuene peterhuene commented Aug 16, 2018

I'm going to re-open this against 3.0 as we're hoping to unify the build / publish experience (while remaining backwards compatible) and make it much easier to get executables built for .NET Core projects.

For 2.2, we are enabling the application host (i.e. the executable) to be built when publishing a framework dependent (--self-contained=false application with a RID).

@peterhuene peterhuene reopened this Aug 16, 2018
peterhuene referenced this issue in peterhuene/sdk Oct 10, 2018
This commit implements building with an apphost by default, without specifying
a `RuntimeIdentifier`.

This works by using the runtime identifier of the SDK to restore the apphost
package.  The apphost will be the only native asset copied to the build output.

Because SDK error messages are expected to be sequential and without gaps, the
removal of the apphost requires a runtime identifier message has resulted in
renaming to an "unused" error message.  In the future, we should probably
retool this to have a list of "deleted messages" so we don't have to have the
resource at all.

Fixes dotnet/cli#6237.
peterhuene referenced this issue in peterhuene/sdk Oct 10, 2018
This commit implements building with an apphost by default, without specifying
a `RuntimeIdentifier`.

This works by using the runtime identifier of the SDK to restore the apphost
package.  The apphost will be the only native asset copied to the build output.

Because SDK error messages are expected to be sequential and without gaps, the
removal of the apphost requires a runtime identifier message has resulted in
renaming to an "unused" error message.  In the future, we should probably
retool this to have a list of "deleted messages" so we don't have to have the
resource at all.

Fixes dotnet/cli#6237.
peterhuene referenced this issue in peterhuene/sdk Oct 10, 2018
This commit implements building with an apphost by default, without specifying
a `RuntimeIdentifier`.

This works by using the runtime identifier of the SDK to restore the apphost
package.  The apphost will be the only native asset copied to the build output.

Because SDK error messages are expected to be sequential and without gaps, the
removal of the apphost requires a runtime identifier message has resulted in
renaming to an "unused" error message.  In the future, we should probably
retool this to have a list of "deleted messages" so we don't have to have the
resource at all.

Fixes dotnet/cli#6237.
peterhuene referenced this issue in peterhuene/sdk Oct 11, 2018
This commit implements building with an apphost by default, without specifying
a `RuntimeIdentifier`.

This works by using the runtime identifier of the SDK to restore the apphost
package.  The apphost will be the only native asset copied to the build output.

Because SDK error messages are expected to be sequential and without gaps, the
removal of the apphost requires a runtime identifier message has resulted in
renaming to an "unused" error message.  In the future, we should probably
retool this to have a list of "deleted messages" so we don't have to have the
resource at all.

Fixes dotnet/cli#6237.
peterhuene referenced this issue in peterhuene/sdk Oct 11, 2018
This commit implements building with an apphost by default, without specifying
a `RuntimeIdentifier`.

This works by using the runtime identifier of the SDK to restore the apphost
package.  The apphost will be the only native asset copied to the build output.

Because SDK error messages are expected to be sequential and without gaps, the
removal of the apphost requires a runtime identifier message has resulted in
renaming to an "unused" error message.  In the future, we should probably
retool this to have a list of "deleted messages" so we don't have to have the
resource at all.

Fixes dotnet/cli#6237.
peterhuene referenced this issue in peterhuene/sdk Oct 11, 2018
This commit implements building with an apphost by default, without specifying
a `RuntimeIdentifier`.

This works by using the runtime identifier of the SDK to restore the apphost
package.  The apphost will be the only native asset copied to the build output.

Because SDK error messages are expected to be sequential and without gaps, the
removal of the apphost requires a runtime identifier message has resulted in
renaming to an "unused" error message.  In the future, we should probably
retool this to have a list of "deleted messages" so we don't have to have the
resource at all.

Fixes dotnet/cli#6237.
peterhuene referenced this issue in peterhuene/sdk Oct 12, 2018
This commit implements building with an apphost by default, without specifying
a `RuntimeIdentifier`.

This works by using the runtime identifier of the SDK to restore the apphost
package.  The apphost will be the only native asset copied to the build output.

Because SDK error messages are expected to be sequential and without gaps, the
removal of the apphost requires a runtime identifier message has resulted in
renaming to an "unused" error message.  In the future, we should probably
retool this to have a list of "deleted messages" so we don't have to have the
resource at all.

Fixes dotnet/cli#6237.
peterhuene referenced this issue in peterhuene/sdk Oct 12, 2018
This commit implements building with an apphost by default, without specifying
a `RuntimeIdentifier`.

This works by using the runtime identifier of the SDK to restore the apphost
package.  The apphost will be the only native asset copied to the build output.

Because SDK error messages are expected to be sequential and without gaps, the
removal of the apphost requires a runtime identifier message has resulted in
renaming to an "unused" error message.  In the future, we should probably
retool this to have a list of "deleted messages" so we don't have to have the
resource at all.

Fixes dotnet/cli#6237.
peterhuene referenced this issue in peterhuene/sdk Oct 12, 2018
This commit implements building with an apphost by default, without specifying
a `RuntimeIdentifier`.

This works by using the runtime identifier of the SDK to restore the apphost
package.  The apphost will be the only native asset copied to the build output.

Fixes dotnet/cli#6237.
wli3 referenced this issue in wli3/cli Nov 14, 2018
This commit implements building and publishing a framework-dependent
application with the application host.

Building with `/p:UseAppHost=true` (when a `RuntimeIdentifier` is specified)
and with `/p:SelfContained=false` will create an executable apphost that can be
used to run the application against globally installed runtimes.

Fixes #6237.
@tonecas

This comment has been minimized.

Copy link

@tonecas tonecas commented Mar 24, 2019

just to bump up this issue. also had the same bad experience with this. not intuitive and very misleading for such a simple issue. spent a couple of hours to understand how this works. there should be a "portable executable" and a "stand-alone/self-contained executable" and the mention to "Exe" be removed.

@Banyc

This comment has been minimized.

Copy link

@Banyc Banyc commented Jun 2, 2019

Try modifying the value of TargetFramework in file *.csproj into like net48 then you will get an EXE that can be run under .NET Framework 4.8 after executing the command dotnet build.

learn more here https://docs.microsoft.com/en-us/dotnet/standard/frameworks

@bugproof

This comment has been minimized.

Copy link

@bugproof bugproof commented Jul 12, 2019

@peterhuene I would prefer to have a single exe (not a host + dll) on Windows like in .NET Framework. It looks really weird now.

@peterhuene

This comment has been minimized.

Copy link
Contributor

@peterhuene peterhuene commented Jul 12, 2019

@wrathofodin unfortunately that's not how .NET Core activation currently works. .NET Core is designed to be cross-platform and it needs a platform-native executable that cannot rely on special behavior in the operating system loader to work (like the Windows-only .NET Framework does for its executables).

We currently have no plans to change the design of application activation. .NET Core applications will still build to DLLs and an optional application host may be used to activate the application instead of dotnet exec.

While not the same thing, the 3.0 .NET Core SDK will have support for publishing a "single-file" executable that is essentially a packed version of your application that self-extracts to a temporary location (performed one time) before running.

@msftgits msftgits transferred this issue from dotnet/cli Jan 31, 2020
@msftgits msftgits added this to the 3.0.1xx milestone Jan 31, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

You can’t perform that action at this time.