通过命令行构建 .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\Microsoft.NETCore.Runtime
列为依赖项?根据你链接的页面,需要引用,否则runtime不会被捆绑。以上是关于通过命令行构建 .NET Core 应用程序,使其可以在未安装 .NET Core 的机器上运行的主要内容,如果未能解决你的问题,请参考以下文章
.Net Core 命令行应用程序 | Process.Start() 在某些机器上运行,但在其他机器上不运行
从命令行构建 APK 后使用 zopfli 重新压缩运行 zipalign 以使其更小