有没有一种方法可以在.NET Core中仅使用单个文件运行控制台应用程序?

22
在.NET框架中,您可以创建一个单独的.EXE文件,无需任何额外的配置文件即可从命令行运行(如果使用ILMerge,您可以将所有.DLL引用放入1个.EXE程序集中)。
我尝试使用.NET Core来完成同样的事情,但迄今为止没有成功。即使是最简单的没有依赖关系的Hello World应用程序也需要一个名为<MyApp>.runtimeconfig.json的文件才能使用dotnet.exe运行。
dotnet F:\temp\MyApp.dll

"

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

"
{
  "runtimeOptions": {
    "framework": {
      "name": "Microsoft.NETCore.App",
      "version": "1.1.1"
    }
  }
}

如果没有将此配置文件与 .DLL 文件放在同一文件夹中,我会收到以下错误提示:

A fatal error was encountered. The library 'hostpolicy.dll' required to
execute the application was not found in 'F:\temp'.

我的问题是:有没有办法更改应用程序,使其不需要存在这个配置文件,以便该信息的默认值被编译在{code}.DLL{/code}中,但可以通过添加配置文件来覆盖?
引用: 注意:我还想确保它“只要安装了正确版本的.NET Core,就可以在任何平台上“正常工作”。
背景: 我试图为运行一些有用但很少需要的实用程序获得流畅的用户体验。由于它似乎不可能使用从客户端应用程序引用的相同{code}.DLL{/code}作为控制台应用程序,所以最好的选择是拥有一个可以下载和运行而不需要任何依赖关系的单个文件。
例如,在Java中,您可以在任何受支持的平台上简单地下载一个{code}.jar{/code}文件并运行:
java <package>.jar <namespace>.SomeClass [args]

如果没有任何额外文件,它将“只需工作”。如何使用.NET Core获得类似的用户体验?

简而言之,我想尝试避免“首先解压缩到目录”的额外步骤...


你需要生成一个DLL,还是EXE对你的情况足够? - Shaun Luttin
3
考虑到需要为每个支持的平台建立和维护一个文件,所以我更倾向于使用.DLL,因为只需维护一个二进制文件即可在任何平台上正常工作(前提是已安装了.NET Core版本),这样要维护的东西就会少得多。 - NightOwl888
3个回答

16

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 runtime(目前仍在开发中)旨在允许创建一个特定于运行时的单个预编译本机可执行文件,而不需要任何其他文件。


1
关于.NET Core 3.0解决方案,请查看我的答案,我在其中详细解释了它。我刚刚完成了使用该解决方案的第一个实时部署。 - Marcell Toth

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 Installer 中安装它,否则命令将失败。
  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 上添加新源。


5

.NET Core 3.0及以上版本支持此功能

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

<PropertyGroup>
    <PublishSingleFile>true</PublishSingleFile>
</PropertyGroup>

还有其他选择,例如将 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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接