大家都知道,在 dotnet 发布时,将会在输出的 publish 文件夹包含所需的依赖。在 .NET Core 开始,引入了 AppHost 的概念,即使是单个程序集,也需要独立的 Exe 可执行文件带上实际包含 Main 函数的 dll 文件。特别是进行独立发布的时候,输出文件夹上有超级多个文件,看起来不清真。本文来告诉大家如何使用 PublishFolderCleaner 工具让发布文件夹只留一个 Exe 和一个 Lib 文件夹
使用方法十分简单,只需要安装 dotnetCampus.PublishFolderCleaner 库即可。编辑入口项目的 csproj 文件,添加如下代码
<ItemGroup>
<PackageReference Include="dotnetCampus.PublishFolderCleaner" Version="3.0.3" />
</ItemGroup>
接下来就和之前一样发布即可,不影响原有的发布步骤
发布完成之后,打开发布文件夹,此时可以发现原本乱糟糟的文件夹被替换为只有一个 exe 可执行文件和一个 lib 文件夹。双击 exe 可执行文件即可获得和之前一样的效果
打开 Lib 文件夹,可以看到此文件夹里面就是原本放在发布文件夹里面的除了入口 exe 之外的其他文件
以上的 PublishFolderCleaner 工具的作用就是将发布文件夹里面的所有文件,除了入口 exe 之外的文件,都放入到 lib 文件夹里面,然后修改入口 exe 文件的逻辑,让入口 exe 可以从 lib 文件夹里面读取入口 dll 文件,从而实现此功能
我创建了一个基于 .NET 5 的 WPF 应用,给此应用加上 dotnetCampus.PublishFolderCleaner 的 NuGet 包
接着使用命令行进行发布,发布命令如下
dotnet publish -r win-x64 -c release --self-contained
接着进入到 bin\Release\net5.0-windows\win-x64\publish\
文件夹,可以看到此文件夹只有存放一个 exe 和一个 lib 文件夹,如下
| WhihuqeabaLeelurlallball.exe
|
\---lib
| clrcompression.dll
| clretwrc.dll
| clrjit.dll
| coreclr.dll
| createdump.exe
| WhihuqeabaLeelurlallball.deps.json
| WhihuqeabaLeelurlallball.dll
| WhihuqeabaLeelurlallball.pdb
| WhihuqeabaLeelurlallball.runtimeconfig.json
| WindowsBase.dll
| WindowsFormsIntegration.dll
| wpfgfx_cor3.dll
| // 忽略很多文件
+---zh-Hans
| Microsoft.VisualBasic.Forms.resources.dll
| PresentationCore.resources.dll
| // 忽略很多文件
|
\---zh-Hant
Microsoft.VisualBasic.Forms.resources.dll
// 忽略很多文件
可以通过如下方式获取本文的源代码,先创建一个空文件夹,接着使用命令行 cd 命令进入此空文件夹,在命令行里面输入以下代码,即可获取到本文的代码
git init
git remote add origin https://gitee.com/lindexi/lindexi_gd.git
git pull origin 24c0c22f4a0bb292893ac09aba2f14b3b84a2d6e
以上使用的是 gitee 的源,如果 gitee 不能访问,请替换为 github 的源
git remote remove origin
git remote add origin https://github.com/lindexi/lindexi_gd.git
获取代码之后,进入 WhihuqeabaLeelurlallball 文件夹
可以通过这个简单的例子试试效果
本文使用的 PublishFolderCleaner 工具,在 GitHub 上完全开源,属于我所在团队构建工具链的工具,请看 https://github.com/dotnet-campus/dotnetcampus.DotNETBuildSDK
核心机制就是添加构建调度步骤,在发布之后执行移动文件和修改入口 exe 两个步骤
其中添加构建调度的逻辑代码如下
<Project>
<Target Name="MoveThePublishFolderToLibFolder" AfterTargets="Publish">
<PropertyGroup>
<PublishFolderCleanerCommandArgs>dotnet "$(MSBuildThisFileDirectory)..\tools\net5.0\PublishFolderCleaner.dll" -p "$(PublishDir) " -a "$(AssemblyName)"</PublishFolderCleanerCommandArgs>
</PropertyGroup>
<Exec Command="$(PublishFolderCleanerCommandArgs)"></Exec>
</Target>
</Project>
也就是在发布完成之后,通过 dotnet 命令调用 PublishFolderCleaner 工具,如上面代码可以看到这是一个 .NET 5 的工具,要求当前开发者的开发环境里面安装有 .NET 5 才能执行此工具
在 PublishFolderCleaner 工具里面完成如上两个步骤,将原有的放在发布文件夹里面的文件全部放入到里层的 lib 文件夹,再通过修改入口 exe 可执行文件,也就是 AppHost 文件,让入口 exe 从原本的相同文件夹读取入口 dll 替换为从 lib 文件夹里面读取入口 dll 文件
关于修改 AppHost 文件的知识,请参阅 dotnet core 应用是如何跑起来的 通过AppHost理解运行过程 和 dotnet 桌面端基于 AppHost 的配置式自动切换更新后的应用程序路径
本文会经常更新,请阅读原文: https://blog.lindexi.com/post/PublishFolderCleaner-%E8%AE%A9%E4%BD%A0%E7%9A%84-dotnet-%E5%BA%94%E7%94%A8%E5%8F%91%E5%B8%83%E6%96%87%E4%BB%B6%E5%A4%B9%E6%9B%B4%E5%8A%A0%E6%95%B4%E6%B4%81.html ,以避免陈旧错误知识的误导,同时有更好的阅读体验。
如果你想持续阅读我的最新博客,请点击 RSS 订阅,推荐使用RSS Stalker订阅博客,或者前往 CSDN 关注我的主页
本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可。欢迎转载、使用、重新发布,但务必保留文章署名林德熙(包含链接: https://blog.lindexi.com ),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。如有任何疑问,请 与我联系 。
无盈利,不卖课,做纯粹的技术博客