通过命令行构建 .NET Core 应用程序,以便它可以在没有安装 .NET Core 的机器上运行

Building a .NET Core app via command line, so that it works on a machine without .NET Core installed

我的最终目标是创建一个跨平台(非 Web)控制台应用程序,所以我现在正在探索 .NET Core。

在我以前的 .NET 项目中,我在 Visual Studio 中进行了所有开发,但我还创建了一个 batch/MSBuild 文件,以便我可以构建整个项目 (包括设置、NuGet 包、带二进制文件的 zip 文件等) 只需单击一下。 Here's an example from a previous project.

最后,我想对我的 .NET Core 测试项目做一些类似的事情。
但是现在我在第一步失败了:我无法在 Visual Studio 之外构建它,因此结果可以在另一台没有安装 .NET Core 的 Windows 机器上运行。
(在第一步中,我忽略了跨平台部分 - 我很乐意让它在 Windows 上运行)


我有什么

我设法让它在 Visual Studio 2015 Community Edition 中工作,如下所示:

  1. 在 Visual Studio 中创建新项目:

  2. 在 Visual Studio 中创建新的发布配置文件("Build" ⇒ "Publish" 在菜单中)。
    这将创建 a PowerShell script (and an XML file with settings)

Here's my test project on GitHub.

当我再次在菜单中执行 "Build" ⇒ "Publish" 时,Visual Studio 显然会再次执行之前创建的 PowerShell 脚本。
结果略大于 90 MB,由 598 个文件夹中的 825 个文件组成,如下所示:

当我在另一台机器上复制它时(安装了 Win 7 / .NET 4 / 安装了 .NET Core ),它有效。


我在Visual Studio

之外尝试得到相同的结果

1。网络发布

and 听起来我可以使用 dnu publish 通过命令行实现相同的结果。
我知道 .NET Core 的某些部分现在仍在移动目标,所以 apparently dnu is now dotnet instead

所以我尝试为它执行 dotnet publish(并创建 a batch file):

dotnet publish "%~dp0\src\CoreTestVisualStudio" -c Release -r win7-x64 -o "%~dp0\release\cli"

结果由一个 .exe 文件和一堆 DLL 组成,只有 25 个文件和 1.5 MB,全部在一个文件夹中:

显然这里缺少 .NET Core 运行时,正如预期的那样,当我尝试在没有安装 .NET Core 的机器(与上面提到的相同)上执行它时,这个应用程序崩溃了。

2。来自发布配置文件的 PowerShell 脚本

我尝试执行 the PowerShell script (which was created when I created the publish profile) outside Visual Studio,但它失败了,因为脚本需要一些参数,而我不知道要传递什么:

param($publishProperties, $packOutput, $nugetUrl)

脚本中还有这一行:

# to learn more about this file visit http://go.microsoft.com/fwlink/?LinkId=524327

...但是 link 只是指向 the landing page of the .NET Web Development and Tools Blog.


TL;DR

我做错了什么?

我知道 .NET Core 的第一个版本主要集中在 ASP.NET,但据我了解,ASP.NET 核心应用程序也只是控制台应用程序,所以我认为一个基本的控制台应用程序现在可以运行了。
另一方面,大多数 console app "getting started" docs 仍然缺失,所以也许现在还为时过早,控制台应用程序的 dotnet publish 尚未完成?

几天后编辑:我怀疑我没有做错任何事,这是 the.NET 核心命令行工具中的一个问题,所以我 posted it to the command line tools' issue tracker .

对于dnu

dnu publish 有一个名为 --runtime 的选项,用于指定发布时要包含的运行时。您将在命令中使用完整的运行时名称,例如:

dnu publish --runtime dnx-clr-win-x86.1.0.0-rc1

对于dotnet

您不需要指定运行时或框架版本——默认情况下,dotnet publish 将使用来自 project.json 的框架和当前的运行时风格。但是,documentation 指出:

dotnet-publish command also requires certain dependencies in the project.json to work. Namely the Microsoft.NETCore.Runtime package must be referenced as a dependency in order for the command to copy the runtime files as well as the application's files to the published location.

问题已解决!
我将它发布在 issue tracker of the .NET Core command line tools 上,结果证明它是 dotnet publish 中的一个错误 - 它没有捆绑 C++ 运行时,这是在没有 .NET 的机器上执行编译的应用程序所必需的已安装核心。

  • 临时解决方案是安装 C++ 运行时。

  • 现在 "real" 解决方案 was made in a pull request three days ago, which is included in the latest installer
    使用此版本,dotnet publish 确实 捆绑了 C++ 运行时,因此结果将在没有 .NET Core 的机器上运行。