【问题标题】:Build .NET Core console application to output an EXE构建 .NET Core 控制台应用程序以输出 EXE
【发布时间】:2017-10-19 19:47:05
【问题描述】:

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

我已尝试发布该项目,但这也不起作用。这是有道理的,因为 EXE 文件将是特定于平台的,但必须有一种方法。我的搜索只出现了对使用 project.json 的旧 .NET Core 版本的引用。

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

【问题讨论】:

  • @geekzster 请取消删除 - 我知道你没有回答 OP 问题,但你回答了我的问题,我怀疑很多其他人说 dotnet <path>.dll (我没有思考和输入 dotnet run <path>.dll成功的原因显而易见)! (反思一下,如果这有利于另一个具有类似答案的问题,那就太好了)

标签: .net-core


【解决方案1】:

出于调试目的,您可以使用 DLL 文件。您可以使用dotnet ConsoleApp2.dll 运行它。如果你想生成一个EXE文件,你必须生成一个独立的应用程序。

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

仅限 Pre-.NET Core 2.0:首先,在 .csproj 文件中添加目标运行时的运行时标识符 (list of supported RIDs):

<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

【讨论】:

  • 我认为这只能通过 CLI 完成。顺便说一句,从.net core 2开始,你不需要在csproj中设置RuntimeIdentifier
  • 对于 .NET Core 2.0 可以在 Visual Studio 中完成吗?还是我必须手动输入这些命令?
  • Hello world 控制台应用程序超过 60MB!
  • @mikolaj 只有一个目标运行时“便携式”。有没有办法把所有的目标都带进来?我可以使用命令行,但认为这是后退一步。
  • 这不会创建独立的可执行文件。这将创建一个可执行文件以及许多其他文件(我的意思是在发布文件夹中)。包括一些带有自己文件的子文件夹。有没有办法创建真正的独立可执行文件?
【解决方案2】:

更新:2022 年 2 月 以下仍然适用于 .NET 6

.NET 5 更新!

以下内容适用于 .NET 5 正式发布的 2020 年 11 月/之后。

(请参阅下面的快速术语部分,而不仅仅是操作方法)

操作方法 (CLI)

先决条件

  • 下载最新版本的 .net 5 SDK。 Link

步骤

  1. 打开终端(例如:bash、命令提示符、powershell)并在 .csproj 文件所在的目录中输入以下命令:
dotnet publish --output "{any directory}" --runtime {runtime}
  --configuration {Debug|Release} -p:PublishSingleFile={true|false}
  -p:PublishTrimmed={true|false} --self-contained {true|false}

示例:

dotnet publish --output "c:/temp/myapp" --runtime win-x64 --configuration Release
  -p:PublishSingleFile=true -p:PublishTrimmed=true --self-contained true

操作方法 (GUI)

先决条件

  • 如果阅读 2020 年 11 月之前的内容:Visual Studio Preview 的最新版本*
  • 如果阅读 NOV2020+:Visual Studio 的最新版本*

*在以上两种情况下,最新的 .net5 SDK 会自动安装在您的 PC 上。

步骤

  1. 右键单击项目,然后单击发布

  2. 单击开始并选择文件夹目标,单击下一步并选择文件夹

  3. 输入任意文件夹位置,点击完成

  4. 点击编辑

  5. 选择一个目标运行时并勾选生成单个文件并保存。*

  6. 点击发布

  7. 在您发布应用的位置打开终端,然后运行 ​​.exe。例子:

一些术语

目标运行时
See the list of RID's

部署模式

  • Framework Dependent 是指生成的小 .exe 文件,但应用假定主机上安装了 .Net 5
  • 自包含意味着更大的 .exe 文件,因为 .exe 包含框架,但是您可以在任何机器上运行 .exe,无需预安装 .Net 5。注意:使用自包含时,会产生额外的依赖项 (.dll),而不仅仅是 .EXE

启用 ReadyToRun 编译
TLDR:它相当于 .Net5 的提前编译 (AOT)。预编译为本机代码,应用程序通常会启动得更快。应用程序性能更高(或不是!),取决于许多因素。更多信息here

修剪未使用的程序集
当设置为 true 时,dotnet 将生成一个非常精简和小型的 .exe,并且只包含它需要的内容。这里要小心。示例:在您的应用中使用反射时,您可能不想将此标志设置为 true。

Microsoft Doc


【讨论】:

  • 太糟糕了,输出是一堆文件,而不是像旧的 .NET Framework 那样只有一个 EXE。
  • @Tomas Karban - 直到我将部署模式更改为“独立”后,发布文件夹中也出现了更改 exe 文件 :-)
  • @TomasKarban .NET Core 不是通用运行时。它专为 1) 云/容器部署,2) 多平台而设计。它也意味着是暂时的——在所有 .NET 都可以开源之前,它只是一个“快速”的黑客攻击。 .NET 5.0 将成为下一个通用 .NET。
  • 不过,当您以 .NET Core 为目标时,适用于 .NET 的 IDE 根本不支持最基本的功能,这很荒谬。这就是每个人创建跨平台命令行应用程序的目标——比如编译器。
  • 这对我不起作用。我尝试了很多组合,我的可执行文件根本不会显示我的程序的内容,一个非常简单的,Hello World。一年有什么变化吗?
【解决方案3】:

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

  • 所有包参考
  • 输出程序集
  • 引导 exe

但它并不包含所有 .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

【讨论】:

  • 除了 ($Temp) 指向我的 c:\Users\xxx\AppData\Local\Temp 显然无法删除/清理 - 也不建议这样做
  • @Adaptabi Temp 被定义为脚本开头的属性
【解决方案4】:

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

dotnet %~n0.dll %*

显然,这假定计算机已安装 .NET Core 并且全局可用。

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

(此答案来源于Chet's comment。)

【讨论】:

    【解决方案5】:

    这是我的解决方法 - 生成一个控制台应用程序 (.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();
            }
        }
    }
    

    【讨论】:

    • 如果你仍然想要一个额外的文件,为什么不直接创建一个包含dotnet [nameOfExe].dll %*的bat文件
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多