如何将NET Core应用打包成一个单独的exe文件

假设我有一个简单的 “Hello World” 控制台程序,我想发给朋友并让他运行,朋友没有安装 .NET Core 环境,所以我打包时必须以self contained方式打包,这很简单,只需在项目所在目录,运行下边命令即可。

dotnet publish -r win-x64 -c Release --self-contained

命令解释 :

  • 从当前目录发布该项目
  • 目标平台是Windows 64位
  • 以release模式发布
  • 以“self-contained” 方式发布,这会将程序运行所需所有依赖项一起发布。

运行命令后,我们将得到一个包括exe执行程序和所有依赖项的文件夹,问题来了,仅仅发布一个HelloWorld控制台程序,文件夹中充满了大量依赖文件。

大概有200多个文件. 当然这也在情理之中,因为为了运行HelloWorld必须打包.NET Core运行时.

虽然这确实可以运行,但总感觉怪怪的。假设我把这个文件夹发给客户,然后说:“我发了一个文件夹给你,里边有几百个文件,你找一下一个叫 MyApplication.exe 的文件,双击运行,其他的你不用理会”。这对于已经习惯了在电脑桌面找程序图标,并双击运行的用户来说,似乎少了点什么。

安装.NET Core 3.0 (Preview 5+)

这里必须黑体加粗,因为如果你不是.NET Core 3.0 , 那么将不能将所有文件打包成一个文件。如果你还不是最新.NET Core 3.0 , 这就需要升级了,至少在 preview 5 以上。

PublishSingleFile参数

说了这么多,其实这只需一个简单的命令行参数:

dotnet publish -r win-x64 -c Release /p:PublishSingleFile=true

命令行意思是发布当前项目,但要把所有文件打包成一个单独文件。你可能注意到了,命令行没有了self-contained参数,这是因为如果你打包成单一exe文件,它会认为你肯定需要将所有依赖项文件一起打包,这很好理解。

打包后的文件夹如图所示 :

只有一个exe文件,点击该文件时,所有依赖项将被解压至一个临时目录,然后从临时目录开始运行。本质上这仅仅是把最初的publish文件夹打包成一个zip压缩包,老实说,这里我略有研究,其他就不多说了,能运行就行。

温馨提示:运行命令前记得清理publish目录,或删除掉bin文件夹,这并不会破坏你的项目,但可以清理掉一些旧的dll文件夹,这样打包出来的exe文件才是最好的。

文件大小及启动时间

眼尖的同学应该已经注意到截图上的文件大小了,已超过70MB,这对于一个什么都没做,只打印了个Hello World的程序来说,属实有点夸张。当然,这在 .NET Core 3.0 Preview 6及以上的版本里,已使用IL Linker等技术解决了此问题,具体可以点击该链接了解更多详情

另外一个问题,你可能注意到了第一次程序启动时有点慢,这是因为首次运行需要解压所有依赖项至临时目录,这将花费一些时间,也不是太长(5秒钟左右),虽不久但能明显感觉到慢,幸运的是,再启动就没有这个问题了,因为不再需要解压至临时目录,秒启不在话下。

原文 https://dotnetcoretutorials.com/2019/06/20/publishing-a-single-exe-file-in-net-core-3-0/