For a console application project targeting .NET Core 1.0, I cannot figure out how to get an .exe to output during build. The project runs fine in debug.
I've tried publishing the project, but that does not work either. It makes sense since an EXE file would be platform-specific, but there must be a way. My searches have only turned up reference to older .NET Core versions that used project.json.
Whenever I build or publish, this is all I get:
This question is related to
.net-core
UPDATE for .NET 5!
The below applies on/after NOV2020 when .NET 5 is officially out.
(see quick terminology section below, not just the How-to's)
dotnet publish --output "{any directory}" --runtime {runtime} --configuration {Debug|Release} -p:PublishSingleFile={true|false} -p:PublishTrimmed={true|false} --self-contained {true|false}
example:
dotnet publish --output "c:/temp/myapp" --runtime win-x64 --configuration Release -p:PublishSingleFile=true -p:PublishTrimmed=true --self-contained true
*In above 2 cases, the latest .net5 SDK will be automatically installed on your PC.
Click Start and choose Folder target, click next and choose Folder
Enter any folder location, and click Finish
Choose a Target Runtime and tick on Produce Single File and save.*
Click Publish
Open a terminal in the location you published your app, and run the .exe. Example:
Target Runtime
See the list of RID's
Deployment Mode
Enable ReadyToRun compilation
TLDR: it's .Net5's equivalent of Ahead of Time Compilation (AOT). Pre-compiled to native code, app would usually boot up faster. App more performant (or not!), depending on many factors. More info here
Trim unused assemblies
When set to true, dotnet will generate a very lean and small .exe and only include what it needs. Be careful here. Example: when using reflection in your app you probably don't want to set this flag to true.
Previous Post
UPDATE (31-OCT-2019)
For anyone that wants to do this via a GUI and:
Note
Notice the large file size for such a small application
You can add the "PublishTrimmed" property. The application will only include components that are used by the application. Caution: don't do this if you are using reflection
Publish again
If a .bat file is acceptable, you can create a bat file with the same name as the DLL file (and place it in the same folder), then paste in the following content:
dotnet %~n0.dll %*
Obviously, this assumes that the machine has .NET Core installed and globally available.
c:\> "path\to\batch\file" -args blah
(This answer is derived from Chet's comment.)
Here's my hacky workaround - generate a console application (.NET Framework) that reads its own name and arguments, and then calls dotnet [nameOfExe].dll [args]
.
Of course this assumes that .NET is installed on the target machine.
Here's the code. Feel free to copy!
using System;
using System.Diagnostics;
using System.Text;
namespace dotNetLauncher
{
class Program
{
/*
If you make .NET Core applications, they have to be launched like .NET blah.dll args here
This is a convenience EXE file that launches .NET Core applications via name.exe
Just rename the output exe to the name of the .NET Core DLL file you wish to launch
*/
static void Main(string[] args)
{
var exePath = AppDomain.CurrentDomain.BaseDirectory;
var exeName = AppDomain.CurrentDomain.FriendlyName;
var assemblyName = exeName.Substring(0, exeName.Length - 4);
StringBuilder passInArgs = new StringBuilder();
foreach(var arg in args)
{
bool needsSurroundingQuotes = false;
if (arg.Contains(" ") || arg.Contains("\""))
{
passInArgs.Append("\"");
needsSurroundingQuotes = true;
}
passInArgs.Append(arg.Replace("\"","\"\""));
if (needsSurroundingQuotes)
{
passInArgs.Append("\"");
}
passInArgs.Append(" ");
}
string callingArgs = $"\"{exePath}{assemblyName}.dll\" {passInArgs.ToString().Trim()}";
var p = new Process
{
StartInfo = new ProcessStartInfo("dotnet", callingArgs)
{
UseShellExecute = false
}
};
p.Start();
p.WaitForExit();
}
}
}
The following will produce, in the output directory,
But it does not contain all .NET Core runtime assemblies.
<PropertyGroup>
<Temp>$(SolutionDir)\packaging\</Temp>
</PropertyGroup>
<ItemGroup>
<BootStrapFiles Include="$(Temp)hostpolicy.dll;$(Temp)$(ProjectName).exe;$(Temp)hostfxr.dll;"/>
</ItemGroup>
<Target Name="GenerateNetcoreExe"
AfterTargets="Build"
Condition="'$(IsNestedBuild)' != 'true'">
<RemoveDir Directories="$(Temp)" />
<Exec
ConsoleToMSBuild="true"
Command="dotnet build $(ProjectPath) -r win-x64 /p:CopyLocalLockFileAssemblies=false;IsNestedBuild=true --output $(Temp)" >
<Output TaskParameter="ConsoleOutput" PropertyName="OutputOfExec" />
</Exec>
<Copy
SourceFiles="@(BootStrapFiles)"
DestinationFolder="$(OutputPath)"
/>
</Target>
I wrapped it up in a sample here: https://github.com/SimonCropp/NetCoreConsole
Source: Stackoverflow.com