构建.NET Core控制台应用程序以输出EXE?

Build .NET Core console application to output an EXE?

对于以.NET核心1.0为目标的控制台应用程序项目,我无法确定如何在生成期间获取要输出的.exe。项目在调试中运行良好。

我试过出版这个项目,但也没用。有道理,因为.exe是特定于平台的,但必须有一种方法。我的搜索只找到了对使用project.json的旧.NET核心版本的引用。

每当我构建或发布时,这就是我所得到的。

build directory


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

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

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

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

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

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

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


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

enter image description here

enter image description here

enter image description here

enter image description here

enter image description here

enter image description here

enter image description here


下面将在输出目录中生成,

  • 所有包引用
  • 输出组件
  • 引导执行文件

但不包含所有NetCore运行时程序集

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<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


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

dotnet %0.dll %*

显然,这假设机器安装了.NET内核。

称之为没有"蝙蝠"部分。即:c:\>"path\to\program" -args blah。(此答案来源于Chet的评论)


这是我的黑客解决方案——生成一个控制台应用程序(.NET框架),它读取自己的名称和参数,然后调用dotnet [nameOfExe].dll [args]

当然,这假设dotnet安装在目标计算机上。

这是密码,请随意复制!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
using System;
using System.Diagnostics;
using System.Text;

namespace dotNetLauncher
{
    class Program
    {
        /*
            If you make .net core apps, they have to be launched like dotnet blah.dll args here
            This is a convenience exe that launches .net core apps via name.exe
            Just rename the output exe to the name of the .net core dll 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();
        }
    }
}