.NETプロジェクトの開発において、プロジェクトの複雑さが増すにつれて、依存するdllファイルも徐々に増えていきます。その結果、出力ディレクトリが乱雑になり、管理やデプロイが不便になることがよくあります。NetBeauty2オープンソースプロジェクトはまさにこの問題を解決するために生まれました。これは、開発者が.NETプロジェクトを独立して公開する際に、.NETランタイムと依存するdllファイルを指定のディレクトリに移動し、出力ディレクトリをよりクリーンで整然としたものにするのに役立ちます。
1. NetBeauty2の概要
NetBeauty2は、オープンソースの.NET依存ライブラリ整理ツールです。その主な役割は、.NETプロジェクトの独立公開時に出力ディレクトリを整理・最適化することです。NetBeauty2を使用することで、開発者は.NETランタイムと依存するdllファイルを簡単に指定のディレクトリに移動でき、プロジェクトの出力ディレクトリをより明確で管理しやすくできます。
プロジェクトリポジトリ:https://github.com/nulastudio/NetBeauty2
下の図は最適化後の出力ディレクトリです(.NETランタイムと参照依存ライブラリが libraries ディレクトリに移動されています。ディレクトリ名は設定可能です):

下の図は極限まで最適化した後の出力ディレクトリです(--hiddens オプションの使用を参照):

次に、未使用時の出力ディレクトリと比較してみましょう(驚くべきことに、.NETランタイムと関連依存ライブラリがすべてルート出力ディレクトリに配置されています。.NET Frameworkでは privatePath を設定できますが、.NET Coreではそれほど簡単ではありません):

2. サポート状況
| NetBeauty 2 | NetCoreBeauty | |
|---|---|---|
| サポートフレームワーク | .NET Framework .NET Core 3.0+ |
.NET Core 2.0+ |
| サポートデプロイモード | Framework-dependent deployment (FDD) Self-contained deployment (SCD) Framework-dependent executables (FDE) |
Self-contained deployment (SCD) |
| サポートOS | All | win-x64 win-x86 win-arm64(.NET 6+) linux-x64 linux-arm linux-arm64 osx-x64 osx-arm64(.NET 6+) |
| パッチ適用HostFXRの必要性 | いいえ (パッチ使用時ははい) | はい |
| 最小構成 | ~20 ファイル ~8 ファイル(パッチ使用時) | ~8 ファイル |
| 仕組み | STARTUP_HOOKS AssemblyLoadContext.Resolving AssemblyLoadContext.ResolvingUnmanagedDll + パッチ適用済み libhostfxr(パッチ使用時) additionalProbingPaths(パッチ使用時) |
パッチ適用済み libhostfxr additionalProbingPaths |
| 共有ランタイム | はい | 可能(patched libhostfxr のみ使用時) |
3. 使用方法
3.1. 準備
.NET Coreプロジェクト(公開するメインプロジェクト)にNuGetパッケージを追加します:
dotnet add package nulastudio.NetBeauty
プロジェクトファイル(.csproj)を編集します:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp3.0</TargetFramework>
</PropertyGroup>
<PropertyGroup>
<BeautySharedRuntimeMode>False</BeautySharedRuntimeMode>
<!-- サブディレクトリに整理する(デフォルトはlibs)、スペースを含む場合は引用符で囲む -->
<BeautyLibsDir Condition="$(BeautySharedRuntimeMode) == 'True'">../libraries</BeautyLibsDir>
<BeautyLibsDir Condition="$(BeautySharedRuntimeMode) != 'True'">./libraries</BeautyLibsDir>
<!-- 移動したくない、または移動できないdll -->
<!-- <BeautyExcludes>dll1.dll;lib*;...</BeautyExcludes> -->
<!-- エンドユーザーが不要なdllを非表示にする -->
<!-- <BeautyHiddens>hostfxr;hostpolicy;*.deps.json;*.runtimeconfig*.json</BeautyHiddens> -->
<!-- 無効にする場合はTrueに設定 -->
<DisableBeauty>False</DisableBeauty>
<!-- ビルド時にも整理する場合はFalseに設定 -->
<BeautyOnPublishOnly>False</BeautyOnPublishOnly>
<!-- このオプションは変更しない -->
<BeautyNoRuntimeInfo>False</BeautyNoRuntimeInfo>
<!-- サードパーティのデバッガ(dnSpyなど)によるデバッグを許可する場合はTrue -->
<BeautyEnableDebugging>False</BeautyEnableDebugging>
<!-- パッチを使用するとファイル数を減らせる -->
<!-- 無効にする場合はFalse -->
<!-- SCDモードのみの機能 -->
<BeautyUsePatch>True</BeautyUsePatch>
<!-- App Entry Dll = BeautyDir + BeautyAppHostDir + BeautyAppHostEntry -->
<!-- 詳細は https://github.com/nulastudio/NetBeauty2#customize-apphost を参照 -->
<!-- AppHostDirを基準とした相対パス -->
<!-- .NET Core 非シングルファイルのみ -->
<!-- <BeautyAppHostEntry>bin/MyApp.dll</BeautyAppHostEntry> -->
<!-- BeautyDirを基準とした相対パス -->
<!-- .NET Core 非シングルファイルのみ -->
<!-- <BeautyAppHostDir>..</BeautyAppHostDir> -->
<!-- <BeautyAfterTasks></BeautyAfterTasks> -->
<!-- 有効な値: Error|Detail|Info -->
<BeautyLogLevel>Info</BeautyLogLevel>
<!-- GitHubに接続できない場合、リポジトリミラーを設定 -->
<!-- <BeautyGitCDN>https://gitee.com/liesauer/HostFXRPatcher</BeautyGitCDN> -->
<!-- <BeautyGitTree>master</BeautyGitTree> -->
</PropertyGroup>
<ItemGroup>
<PackageReference Include="nulastudio.NetBeauty" Version="2.1.4.4" />
</ItemGroup>
</Project>
dotnet build または dotnet publish を実行すると、出力の最適化が自動的に行われます。
3.2. アプリケーションがすでに公開されている場合
アプリケーションがすでに公開されている場合は、次のように使用できます(サイト管理者は未テスト。公開後の補完手段として):
Usage:
nbeauty2 [--loglevel=(Error|Detail|Info)] [--srmode] [--enabledebug] [--usepatch] [--hiddens=hiddenFiles] [--noruntimeinfo] [--roll-forward=<rollForward>] [--apphostentry=<appHostEntry>] [--apphostdir=<appHostDir>] <beautyDir> [<libsDir> [<excludes>]]
例:
ncbeauty2 --usepatch --loglevel Detail --hiddens "hostfxr;hostpolicy;*.deps.json;*.runtimeconfig*.json" /path/to/publishDir libraries "dll1.dll;lib*;..."
3.3. .NET Core グローバルツールとして設定
dotnet tool install --global nulastudio.nbeauty
インストール後、プログラム公開時に自動的に適用されます。
4. さまざまなプロジェクトの使用例
リポジトリ(https://github.com/nulastudio/NetBeauty2)をクローンすると、さまざまなテンプレートプロジェクトの使用例があります:

| テストプロジェクト名 | 説明 |
|---|---|
| WPFTest | WPFプロジェクト(Winformも同様)、デフォルト.NET 5 |
| WebAppTest | RazorPagesプロジェクト、デフォルト.NET 6 |
| NetFxTest | .NET Framework WPFプロジェクト(.NET 4.x、Winformも同様) |
| ChromelyTest | Chromelyを参照する.NETプロジェクト |
| AvaloniaTest | Avalonia UIプロジェクト、デフォルト.NET 5 |
豆知識1
Chromely NuGetパッケージは、クロスプラットフォームのデスクトップアプリケーションを作成するためのライブラリで、Chromiumベースのブラウザコントロールを提供します。Chromelyを使用すると、開発者はWeb技術(HTML、CSS、JavaScriptなど)を使用してデスクトップアプリケーションのユーザーインターフェースを構築し、同時にローカルシステムリソースにアクセスできます。
Chromely NuGetパッケージは、完全なAPIとツールセットを提供しており、開発者はコードを大幅に書き換えたり変更したりすることなく、Webアプリケーションをデスクトップアプリケーションに簡単に変換できます。また、さまざまなプラグインや拡張機能をサポートしており、開発者は必要に応じて追加機能を追加したり、既存の機能をカスタマイズできます。
さらに、ChromelyはC#、.NET Core、ASP.NET Coreなどの複数のプログラミング言語とフレームワークをサポートしており、開発者は最も使い慣れたテクノロジースタックを選択してアプリケーションを構築できます。
豆知識2
Avalonia UIはクロスプラットフォームの.NET UIフレームワークで、開発者はXAMLとC#言語を使用して、Windows、Linux、macOS、iOS、Android、WebAssemblyなど、複数のプラットフォームで実行できるアプリケーションを作成できます。Avalonia UIは、美しくモダンなグラフィカルユーザーインターフェース(GUI)を構築するのに役立ちます。.NET Standard 2.0をサポートするすべてのプラットフォームと互換性があり、単一のコードベースから複数のオペレーティングシステム向けのネイティブアプリケーションを作成できます。Avalonia UIを使用することで、開発者は.NETエコシステムの強力な機能を最大限に活用し、クロスプラットフォームの互換性を実現し、開発コストを削減し、開発効率を向上させることができます。
おすすめのオープンソースコントロールライブラリ:irihitech/Semi.Avalonia、irihitech/Ursa.Avalonia
5. まとめ
林德熙(lindexi)氏が同様のパッケージ NuGet Gallery | dotnetCampus.PublishFolderCleaner 3.11.1 を紹介していますが、このライブラリはWindows公開のみサポートとのことです。両者を比較してご利用ください。元の記事:PublishFolderCleaner 让你的 dotnet 应用发布文件夹更加整洁 - lindexi - 博客园 (cnblogs.com)。本記事で紹介した NetBeauty2 のオープンソースアドレスを再度記載します:
プロジェクトリポジトリ:https://github.com/nulastudio/NetBeauty2
参考: