強迫症福利--收起.NET程式的dll來

波多爾斯基發表於2019-05-09

作為上床後需要下床檢查好幾次門關了沒有的資深強迫症患者,有一個及其搞我的問題,就是dll問題。

曾幾何時,在沒有nuget的年代,當有依賴項需要引用的時候,只能通過檔案引用來管理引用問題,版本問題,更新問題層出不窮,很是難受。

後來出來nuget,喜大普奔,總算解決了引用的問題。開心之餘,依然還有一個很膈應人的問題:生成資料夾滿地的dll,找個exe眼睛很難受。

講道理這個也不是什麼大問題,但是就是心癢癢,就特別想把這些dll收到一個單獨資料夾裡面,外面就留exe和配置等檔案。然後就找這個東西:PrettyBin。

PrettyBin

PrettyBin是一個開源的nuget包:https://github.com/slmjy/PrettyBin,使用它可以將.NET Framework程式引用的檔案收到lib資料夾裡面,使用起來也非常方便,老樣子,直接nuget安裝。

Install-Package PrettyBin

提示重新載入專案,點選確定,就完事了。
安裝之前,輸出是這樣的:
強迫症福利--收起.NET程式的dll來

安裝之後,輸出是這樣的:
強迫症福利--收起.NET程式的dll來

dll之類的檔案都進lib資料夾了,感覺世界都乾淨了很多。

補充

  1. 細心的童鞋應該能夠發現,我寫的是.NET Framework的程式引用,.NET Core,.NET Standard呢?
    答案是:.NET Core啥的東西生成的就是dll,都一樣就沒必要了。

  2. 安裝prettybin之後,再安裝新的包會怎麼樣?受不受影響?
    依然有用,不受影響。

  3. 對於新的nuget管理形式PackageReference效果如何怎麼樣?
    這個有說法的,需要先了解這個包工作的原理。

原理解析

首先看看安裝的時候,nuget包管理器彈出的提示:

正在執行指令碼檔案“ConsoleApp4\packages\PrettyBin.1.1.0\tools\init.ps1”
Init BinPrettify
正在執行指令碼檔案“ConsoleApp4\packages\PrettyBin.1.1.0\tools\install.ps1”
Install PrettifyBin; 
http://schemas.microsoft.com/developer/msbuild/2003
No Target AfterBuild Node. Creating
No ItemGroup whith MoveToLibFolder tag. Creating
No Move tag in AfterBuild Target. Creating
Edititing App.config
runtimeNode items
No probing Node. Creating
已將“PrettyBin 1.1.0”成功安裝到 ConsoleApp4

可以看到,這裡首先執行的是給專案檔案新增`msbuild內容,增加了AfterBuild節點,MoveToLibFolder節點和Move節點。

<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Target Name="AfterBuild">
<ItemGroup>
    <MoveToLibFolder Include="$(OutputPath)*.dll ; $(OutputPath)*.pdb ; $(OutputPath)*.xml" />
</ItemGroup>
<Move SourceFiles="@(MoveToLibFolder)" DestinationFolder="$(OutputPath)lib" OverwriteReadOnlyFiles="true" />
</Target>

msbuild可以設定生成後的操作,成功生成之後,將目錄下面的dll檔案,pdb檔案和xml都轉到了lib資料夾。
然後修改了app.config檔案,在runtime底下增加了一個probing節點。

<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
    <probing privatePath="lib;libs" xmlns="" />
</assemblyBinding>
</runtime>

probing節點提供.NET程式集查詢的選項,privatepath指定路徑,詳細資料可以檢視MSDN:https://support.microsoft.com/en-us/help/837908/how-to-load-an-assembly-at-runtime-that-is-located-in-a-folder-that-is
補充資料:關於指定程式集位置

所以,prettybin是通過執行powershell指令碼設定生成成功後轉移檔案,並將程式集查詢路徑調整為lib資料夾。

根據https://docs.microsoft.com/zh-cn/nuget/reference/migrate-packages-config-to-package-reference,PackageReference方式nuget是不支援install.ps1指令碼的。所以並不能支援prettybin。

新建.NET Framework程式是預設是通過傳統的package.config檔案進行包管理的,新建.NET Core和.NET Standard都是預設使用PackageReference包管理。

結論

  1. 如果需要使用PrettyBin,那麼直接預設配置.NET FRAMEWORK專案的nuget管理方式,完美支援。
  2. 如果需要升級新的包管理方式,可以在安裝了PrettyBin之後升級專案,依然支援。
  3. 升級了PackageReference之後,安裝PrettyBin無效。

P.S. 補充不使用prettybin,也不呼叫AFTERBUILD的一種實現:https://www.broculos.net/2014/03/visual-studio-build-dlls-to-separate.html#.WWiTjJFJLy8

相關文章