有没有办法在.NET Core中只使用一个文件来运行控制台应用程序?

Nig*_*888 17 .net c# console-application command-line-interface .net-core

在.NET框架中,您可以创建一个.EXE将从命令行运行的单个文件,而无需任何额外的配置文件(如果使用ILMerge,则可以将所有.DLL引用放入1个.EXE程序集中).

我正在尝试使用.NET Core来完成同样的事情,但到目前为止还没有成功.即使是Hello World没有依赖关系的最简单的应用程序也需要有一个命名的文件<MyApp>.runtimeconfig.json才能运行dotnet.exe.

dotnet F:\temp\MyApp.dll
Run Code Online (Sandbox Code Playgroud)

内容<MyApp>.runtimeconfig.json如下:

{
  "runtimeOptions": {
    "framework": {
      "name": "Microsoft.NETCore.App",
      "version": "1.1.1"
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

如果没有与此文件夹相同的配置文件.DLL,我会收到以下错误:

A fatal error was encountered. The library 'hostpolicy.dll' required to
execute the application was not found in 'F:\temp'.
Run Code Online (Sandbox Code Playgroud)

我的问题是:有没有办法改变应用程序,所以它不需要这个配置文件存在,所以这些信息的默认值是在编译内,.DLL但可以通过添加配置文件来覆盖?

注意:如果平台具有正确版本的.NET Core,我还要确保它"正常工作"而不管它上面安装的平台.

背景

我试图获得一个流畅的用户体验,运行一些有时很有用的实用程序,但很少需要.因为它似乎没有可以使用相同的.DLL是从客户端应用程序中引用作为控制台应用程序,未来最好的事情是有一个单一的文件是可以下载,没有任何依赖性运行.

例如,在Java中,您只需.jar在任何支持的平台上下载文件并运行:

java <package>.jar <namespace>.SomeClass [args]
Run Code Online (Sandbox Code Playgroud)

并且它将"正常工作"而没有任何额外的文件.如何使用.NET Core获得类似的用户体验?

简而言之,我想尽量避免"首先解压缩到目录"的额外步骤......

Mar*_*ich 13

更新2018: .NET Core 3.0旨在启用新方案:将.NET Core运行时和所有应用程序依赖项打包到单个可执行文件中.

目前,没有用于创建单个可执行文件的故障安全方法.由于涉及很多类型转发dll文件,即使ILMerge和类似工具也可能无法产生正确的结果(尽管这可能会有所改进,但问题是这些方案未经过大量测试,尤其是在生产应用程序中)

目前有两种部署.NET Core应用程序的方法:

  • 作为"可移植应用程序"/"依赖于框架的应用程序",需要dotnet在目标机器上安装可执行文件并安装框架.这里,XYZ.runtimeconfig.json它用于确定要使用的框架版本,还指定运行时参数.此部署模型允许在各种平台(windows,linux,mac)上运行相同的代码
  • 作为"自包含应用程序":这里整个运行时包含在已发布的输出中,并生成可执行文件(例如yourapp.exe).此输出特定于平台(通过运行时标识符设置),并且只能在目标操作系统上运行.但是,生成的可执行文件只是一个小垫片,可以启动运行时并加载应用程序的主dll文件.这也允许XYZ.runtimeconfig.json设置其他运行时属性,如垃圾收集设置.(将其视为"新" app.config文件)

将来,CoreRT运行时(在编写本文时仍在开发中)旨在允许创建特定于运行时的单个预编译本机可执行文件,而不需要任何其他文件.


Max*_*lin 6

控制台应用程序上使用 .NET Core 2.2 进行测试:

  1. 在您的输出项目中引用Microsoft.DotNet.ILCompiler包。你需要在 Visual Studio 设置中添加 MyGet 包存储库。*
  2. 通过命令行发布项目, dotnet publish C:\src\App\App.csproj -c release -r win-x64 -o output-win-x64。如果没有安装“C++ 桌面开发”组件,请在 Visual Studio 安装程序中安装,否则命令将失败。
  3. 转到输出文件夹(例如“C:\src\App\output-win-x64”)并获取本机映像(.exe 文件)。

在 Windows 上,它生成了一个功能齐全的 5Mb .exe 文件(与原始自包含发布相比,文件夹大小约为 60Mb)。在 macOS 上,ILComplier 虽然产生了没有任何错误的输出,但应用程序因未处理的预期而崩溃(在带有 LINQ 表达式的行上)。

*转到“工具 -> 选项 -> 包管理器 -> 包源”并在https://dotnet.myget.org/F/dotnet-core/api/v3/index.json添加新源


Mar*_*oth 6

在 .NET Core 3.0+ 中是可能的

通过在项目文件 (.csproj) 中使用以下属性来启用该功能:

<PropertyGroup>
    <PublishSingleFile>true</PublishSingleFile>
</PropertyGroup>
Run Code Online (Sandbox Code Playgroud)

还有其他选项,例如将pdb打包到捆绑包中,或保留某些文件。

文档可以在这里找到: https: //learn.microsoft.com/en-us/dotnet/core/deploying/#publish-self-contained

确实,它只是有效

将此技术与自包含部署工作流程相结合,您可以为您的用户获得真正的“它就是有效”的体验,他们甚至不需要安装 .NET Core 运行时即可运行您的应用程序。

我目前正在将应用程序作为单个.exe文件部署到我的客户端。

在这里阅读更多相关信息:https://learn.microsoft.com/en-us/dotnet/core/deploying/#self-contained-deployments-scd