Closed danmoseley closed 4 years ago
Does dotnet bin\Debug\netcoreapp2.0\asdf.dll
work?
Edit: dotnet publish --self-contained
should generate an exe, though: https://github.com/dotnet/cli/pull/6234
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
@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.
.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).
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
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.
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
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.
@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.
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?
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
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?
Do understand the difficulty that that "exe" wouldn't be portable though 😢
Could you output multiple?
dotnet publish
outputs
MyApp.dll
MyApp.exe
MyApp
rwxrwxr--
@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:
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?
@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.
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.
The exe provides an entry point for process name, process description and icon which is lost with just the launcher
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.
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. 😄
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.
Ok updating to newest nightly and creating with dotnet new
does create the exe
All good...
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.
@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 :/ .
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>
@livarcocc for feedback above (since issue is closed)
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.
@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.
@damircolak did you open a new issue for this? I am experiencing the same problem.
Same problem here, is there a new issue regarding this yet?
@AronParker try the following:
dotnet publish -c Release
Now navigate to bin/Release/netcoreapp1.x/publish
and you should see the exe in there.
Alternatively see if it's worth going up to .Net Core 2.0 as it appears to be supporting standalone applications as a flag on publish
:
https://docs.microsoft.com/en-us/dotnet/core/tools/dotnet-publish?tabs=netcore2x
@AronParker try the following:
dotnet publish -c Release
Now navigate to bin/Release/netcoreapp1.x/publish and you should see the exe in there.
Alternatively see if it's worth going up to .Net Core 2.0 as it appears to be supporting standalone applications as a flag on publish: https://docs.microsoft.com/en-us/dotnet/core/tools/dotnet-publish?tabs=netcore2x
@mattcanty Thanks for your response! Although I still see .dll files even when compiling with dotnet publish -c Release
, could that be because I'm on .NET core 2.0? And yes indeed I've seen that you can make a standalone package which does an exe, however it contains the entire .NET core files which I don't really want.
I agree with @AronParker . Exactly the same things happen to me. Why is this closed?
Reopening just so @livarcocc and @richlander can see the feedback. Although, this is by design - see @richlander 's explanation: https://github.com/dotnet/cli/issues/6237#issuecomment-293425139
sigh...thanks @danmosemsft
I wonder if sth simple can be done here to help out. The scenario seems to be "I want to double-click something" (correct me if I'm wrong) which can be easily done by creating a .cmd
and .sh
file calling dotnet foo.dll
..
Am I missing any special reason why everything cannot be bundled up inside the executable somehow.
Coming at this from a totally naive viewpoint...
If you wanted an executable package containing the supporting libraries, why would you ever want those as individual files that you also have to lug around.
On Mon, 28 Aug 2017 at 20:10 Martin Andreas Ullrich < notifications@github.com> wrote:
I wonder if sth simple can be done here to help out. The scenario seems to be "I want to double-click something" (correct me if I'm wrong) which can be easily done by creating a .cmd and .sh file calling dotnet foo.dll..
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/dotnet/cli/issues/6237#issuecomment-325449456, or mute the thread https://github.com/notifications/unsubscribe-auth/AB_ibRjTwEa5udh5x8USruiqfIHkziDQks5scxCRgaJpZM4MyTtj .
Gotta say, I'm scratching my head over this one too.
This isn't a new problem. Wrapper creators for .jar files that package them into Windows/Linux/macOS executables have existed for 15 years.... JSmooth, Jar2exe, launch4j, and others are all are actively developed and used in the Java world.
These tools exist because it has long been understood that it is necessary to provide a smooth execution experience for end-users. This is doubly true for people who write command-line utilities. If that tool isn't easy to reach, folks just won't use it.
Asking people to type "dotnet" before running my command-line tool would be like asking a gamer to type "directx" or "unity" before running my game.
Ideally, "dotnet publish" would provide these wrappers based on the requested RID(s).
Asking people to type "dotnet" before running my command-line tool would be like asking a gamer to type "directx" or "unity" before running my game.
Ideally, "dotnet publish" would provide these wrappers based on the requested RID(s).
This does happen. If you publish for "win-x64", you will get a native Windows executable which can be run by double-clicking it. If you publish for "linux-x64", you will get a native Linux executable (extensionless ELF file) that can be run directly.
@mattcanty that is not possible because an executable that works in one platform won't necessarily work in another (like a windows executable and a linux one).
@warrenrumak If you provide a RID and are building a self-contained application, we will publish an executable with the application name in the publish output folder.
See now that @mellinoe posted with me!
cc @KathleenDollard
Maybe it's just a discoverability/convenience issue. I didn't originally discover dotnet.exe publish -r win-x64
and we don't seem to expose the list of RID's in the help.
Or the just to be sure:
dotnet.exe publish -c Release -r win-x64 -f netcoreapp2.0
Maybe cli should offer common selection on a help param; with link to look up more?
Yeah, I meant -? help.
There is probably a distinct scenario here: wrappers to allow calling ./theapp
in a RID-specific but not self-contained publish. While it is currently possible to creat such a deployment (dotnet publish -r RID --self-contained false
), there is room for a few extras here:
.bat
file for windows which just calls dotnet exec theapp.dll
and an extensionless shell script to do the same on *nix
That could be called via dotnet publish -c Release -r win-x64 --self-contained false --create-launcher
.
@mellinoe
It sure does, then I have to package, what, 60MB of DLLs with each executable? No thank you. You cannot convince me that this is a good path forward, especially if I want to build several command-line tools or small GUIs. Now instead of asking the user for, say, 1MB of disk space for ten small tools, I'm asking for 600MB?
What's being asked for here is a middle-ground between -f and -r: An executable that uses the installed runtime. You know, like we did successfully for 15 years....
@livarcocc Isn't there a way to produce a framework-dependent deployment but still get an executable launcher?
@eerhardt will the feature you implemented address this?
No unfortunately not. Even when you publish '-r RID --self-contained false', you still run on the shared framework. And today to run on the shared framework, you need to be invoked with the 'dotnet' host executable.
We could add a feature to the apphost executable to know where to find the shared framework when it is invoked and the coreclr doesn't exist in the same directory. An issue with that is there is no "global" location on non-Windows. We have %PROGRAMFILES% on Windows, but there isn't currently the same well-known global location on Unix.
How about adding a custom file extension called .dotnet, which will be registered to run the runtime with the specified file?
How about on any build or publish you just automatically create a ".bat", ".ps1" or some other file that does the "dotnet myfile.dll".
It could even be named myfile.exe.ps1
On publish if you wanted to auto-create a Linux flavored one, you could do that too.
Might be a dumb question, but is there a .Net Core 2.0 version of this document?
https://docs.microsoft.com/en-us/dotnet/core/deploying/
We're working on cross-platform standalone build and would like to know the right way to keep dotnet build
working and building a proper DLL and have dotnet publish
create the standalone executable. As it stands right now I can only seem to make a DLL that works fine with dotnet my_app.dll
or a standalone executable with dotnet publish
but the build DLL complains about missing libraries.
Thanks!
Ok, so part of my issue was that dotnet restore
wasn't being called. That solves the dotnet build
issue. But running dotnet publish -r osx.10.12-x64
with OutputPath set builds a standalone executable without dependencies in the OutputPath that doesn't work, and under that in publish
a standalone executable with dependencies that does. I can work around that but it seems odd to have both.
Shouldn't I have a console .exe? How do I run this dll?