生成.NET Core控制台应用程序以输出EXE


413

对于针对.NET Core 1.0的控制台应用程序项目,我无法弄清楚如何在构建过程中输出.exe。该项目在调试中运行良好。

我已经尝试发布该项目,但这也不起作用。这是有道理的,因为EXE文件是特定于平台的,但是必须有一种方法。我的搜索仅找到使用project.json的.NET Core早期版本的参考。

每当我构建或发布时,这都是我得到的:

建立目录



2
@geekzster请取消删除-我知道您没有回答OP问题,但是您回答了我的问题,我怀疑很多人都这么说dotnet <path>.dlldotnet run <path>.dll出于明显的原因,我没有想到并没有成功地打字)!(回想起来,如果以另一个具有相似答案的问题而结束,则将其关闭是很好的)
Ruben Bartelink

Answers:


480

出于调试目的,您可以使用DLL文件。您可以使用运行它dotnet ConsoleApp2.dll。如果要生成EXE文件,则必须生成一个自包含的应用程序。

要生成自包含的应用程序(Windows中的EXE),必须指定目标运行时(特定于目标操作系统)。

仅限于.NET Core 2.0之前的版本:首先,在.csproj文件(受支持的RID列表)中添加目标运行时的运行时标识符:

<PropertyGroup>
    <RuntimeIdentifiers>win10-x64;ubuntu.16.10-x64</RuntimeIdentifiers>
</PropertyGroup>

从.NET Core 2.0开始,不再需要上述步骤

然后,在发布应用程序时设置所需的运行时:

dotnet publish -c Release -r win10-x64
dotnet publish -c Release -r ubuntu.16.10-x64

15
我认为只能使用CLI才能做到这一点。顺便说一句,从.net core 2开始,您不需要RuntimeIdentifier在csproj中进行设置。
meziantou

26
.NET Core 2.0是否可以在Visual Studio中完成?还是我必须手动键入这些命令?
Tomasz Sikora

77
Hello World控制台应用程序超过60MB!
shox

13
@mikolaj只有一个目标运行时“可移植”。有没有办法实现所有目标?我可以使用命令行,但是认为这是退后一步。
gsharp

10
这不会创建独立的可执行文件。这将创建一个可执行文件,以及大量其他文件(在我的发布文件夹中)。包括一些带有自己文件的子文件夹。有没有办法创建真正的独立可执行文件?
马修

121

更新(31-OCT-2019)

对于任何想要通过GUI进行此操作的人:

  • 正在使用Visual Studio 2019
  • 已安装.NET Core 3.0(包含在最新版本的Visual Studio 2019中)
  • 想要生成一个文件

在此处输入图片说明

在此处输入图片说明

在此处输入图片说明

在此处输入图片说明

在此处输入图片说明

在此处输入图片说明

在此处输入图片说明

在此处输入图片说明

在此处输入图片说明

注意

注意这么小的应用程序的文件很大

在此处输入图片说明

您可以添加“ PublishTrimmed”属性。该应用程序将仅包括该应用程序使用的组件。注意:如果使用反射,请不要这样做

在此处输入图片说明

重新发布

在此处输入图片说明


上一篇

对于正在使用Visual Studio并希望通过GUI进行操作的任何人,请参见以下步骤:

在此处输入图片说明

在此处输入图片说明

在此处输入图片说明

在此处输入图片说明

在此处输入图片说明

在此处输入图片说明

在此处输入图片说明


19
不幸的是,输出是一堆文件,而不仅仅是像旧的.NET Framework这样的EXE。
Tomas Karban,

2
@Tomas Karban-是这样,直到我将部署模式更改为“自包含”,更改exe文件也出现在publish文件夹中之后:-)
Mariusz

@TomasKarban .NET Core不是通用运行时。它是专为1)云/容器部署,2)多平台而设计的。这也意味着是暂时的-在所有.NET都可以开源之前,这只是一个“快速”黑客。.NET 5.0将成为下一个通用的.NET。
六安

3
仍然可笑的是,当您以.NET Core为目标时,.NET IDE根本不支持最基本的功能。这就是每个人创建跨平台命令行应用程序(例如,编译器)必须面对的目标。
恢复莫妮卡

18

以下将在输出目录中产生:

  • 所有包装参考
  • 输出组件
  • 引导程序

但是它不包含所有.NET Core运行时程序集。

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

我将其包装在以下示例中:https : //github.com/SimonCropp/NetCoreConsole


除了($温度)指向我的C:\用户\ XXX \应用程序数据\本地\这显然不能被删除/清洗温度-也不是adviceable这样做
Adaptabi

1
@Adaptabi Temp在脚本开始时定义为属性
Simon

2

如果可接受.bat文件,则可以创建一个与DLL文件同名的bat文件(并将其放置在同一文件夹中),然后粘贴以下内容:

dotnet %~n0.dll %*

显然,这是假定计算机已安装.NET Core并在全球范围内可用。

c:\> "path\to\batch\file" -args blah

(此答案来自Chet的评论。)


0

这是我的解决方法-生成一个控制台应用程序(.NET Framework),该应用程序读取其自己的名称和参数,然后调用dotnet [nameOfExe].dll [args]

当然,这假定.NET已安装在目标计算机上。

这是代码。随时复制!

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();
        }
    }
}

6
如果您仍然要拥有一个附加文件,为什么不创建一个包含以下内容的蝙蝠文件dotnet [nameOfExe].dll %*
Chet,
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.