通过命令行构建 .NET Core 应用程序,使其可以在未安装 .NET Core 的机器上运行

Posted

技术标签:

【中文标题】通过命令行构建 .NET Core 应用程序,使其可以在未安装 .NET Core 的机器上运行【英文标题】:Building a .NET Core app via command line, so that it works on a machine without .NET Core installed 【发布时间】:2016-01-03 19:20:28 【问题描述】:

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

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

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


我有什么

我设法让它在 Visual Studio 2015 社区版中工作,如下所示:

    在 Visual Studio 中创建新项目:"New Project" ⇒ "Web" ⇒ "Console Application (Package)"

    在 Visual Studio 中创建新的发布配置文件(菜单中的“构建”⇒“发布”)。 这将创建a PowerShell script(和an XML file with settings)

Here's my test project on GitHub.

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

当我将它复制到另一台机器上时(安装了 Win 7 / .NET 4 / 安装了 .NET Core ),它可以工作。


我试图在 Visual Studio 之外得到相同的结果

1。 dotnet 发布

This answer 和 this answer 听起来我可以使用 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(在我创建发布配置文件时创建)outside Visual Studio,但它失败了,因为脚本需要一些参数并且我不知道要传递什么:

param($publishProperties, $packOutput, $nugetUrl)

脚本中也有这一行:

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

...但链接只指向the landing page of the .NET Web Development and Tools Blog。


TL;DR

我做错了什么?

我知道 .NET Core 的第一个版本主要关注 ASP.NET,但据我了解,ASP.NET Core 应用程序也只是控制台应用程序,所以我认为现在可以使用基本的控制台应用程序。 另一方面,大部分console app "getting started" docs 仍然丢失,所以可能还为时过早,控制台应用程序的dotnet publish 还没有完成?

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

【问题讨论】:

你见过这个吗? github.com/dotnet/cli/blob/master/Documentation/intro-to-cli.md 你可以尝试运行dotnet build 来生成可运行的资产。 @DanielMann:不,我以前没有看到这个。不过,它对我不起作用。首先,dotnet build 在我的机器上不存在。然后我从您的链接安装了最新版本,现在dotnet build 存在,但抛出异常:Unhandled Exception: System.TypeLoadException: Could not load type 'Microsoft.DotNet.Tools.Compiler.CompilerCommandApp' from assembly 'dotnet-compile, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'. at Microsoft.DotNet.Tools.Build.Program.Main(String[] args) @DanielMann:也许我应该更好file an issue on GitHub?我最初在这里发布问题是因为我认为我做错了什么,但如果 dotnet build 是现在的当前方式并且它在我的机器上崩溃,我想这实际上是一个错误。 我在尝试在命令行上重现 Visual Studio Publish 时遇到了类似的问题。对我来说,它缺少运行时选项。这是有效运行时值的链接:docs.microsoft.com/en-us/dotnet/core/rid-catalog 【参考方案1】:

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

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

三天前的“真实”解决方案was made in a pull request,现在包含在latest installer中。 在此版本中,dotnet publish确实捆绑了 C++ 运行时,因此结果可以在没有 .NET Core 的机器上运行。

【讨论】:

【参考方案2】:

对于dnu

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

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

对于dotnet

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

dotnet-publish 命令还需要 project.json 中的某些依赖项才能工作。即必须将 Microsoft.NETCore.Runtime 包作为依赖项引用,以便命令将运行时文件以及应用程序文件复制到发布位置

【讨论】:

也适用于dotnet、it's --runtime or -r。但我在我的问题代码中did use that:-r win7-x64 你从哪里拉取win7-x64?您需要使用完整的运行时名称。查看我编辑的回复。 It's from here,根据此链接,win7-x64 是 Windows 的唯一有效值。我尝试了您编辑的响应中的参数,并收到以下错误消息:'...\CoreTestVisualStudio' cannot be published for '<no framework provided>' 'dnx-clr-win-x86.1.0.0-rc1'。提供框架(dnxcore50,如在 project.json 中)也无济于事。 从哪里拉出dnx-clr-win-x86.1.0.0-rc1它看起来不像我在运行dnvm list时看到的版本号。 其实我测试用的是dnx-clr-win-x86.1.0.0-beta8。我从我的配置文件中的已安装框架列表中将其拉出,位于 C:\users\\.dnx\runtimes 下。但是,从您链接的页面来看,自 -beta8 以来情况似乎发生了很大变化,所以我可能需要一点时间来重新了解一下...... 您的 project.json 中是否将 Microsoft.NETCore.Runtime 列为依赖项?根据你链接的页面,需要引用,否则runtime不会被捆绑。

以上是关于通过命令行构建 .NET Core 应用程序,使其可以在未安装 .NET Core 的机器上运行的主要内容,如果未能解决你的问题,请参考以下文章

.Net Core 命令行应用程序 | Process.Start() 在某些机器上运行,但在其他机器上不运行

通过命令行构建和发布 C# .NET Web App

从命令行构建 APK 后使用 zopfli 重新压缩运行 zipalign 以使其更小

使用命令行如何在 ASP.NET 中首先从 DB 搭建脚手架 - 而不是 ASP.NET Core MVC?

.Net Core 构建解决方案

使用.NET Core快速开发一个较正规的命令行应用程序