.NET 5 で作ったWindowsアプリをpublishするメモ

なかなか迷ったのでメモ書き。

TL;DR:

  • .NET 5 及び .NET Core では Any CPU な exe を作れない
  • SelfContained を true にするとランタイムのインストールが不要になるがかなりサイズが膨らむ
  • PublishSingleFile は true がおすすめ

さようなら Any CPU exe

.NET 5 及び .NET Core では Any CPU なexeが作れない。なぜかというとexeは実際にはdotnet.exe(+PublishSingleFileがtrueの場合はアプリのファイルたち)で、dotnet.exeは Any CPU ではないから。Issueはこれ。.NET Core 時代の物だが、.NET 5 になっても状況は変わっていない様子。

github.com

StarlightResizeの場合はそもそもデレステ自体が64bitアプリだったので64bitバイナリしか配っていないが、Any CPU である価値があるアプリの場合は当分 .NET Framework 4.x のままにしたほうがいいかも。

それはそうと今から Windows on ARM をやっていくぞ、ARMネイティブアプリを増やしていくぞという時になんで Any CPU exe をやめるんだ?なんだかちぐはぐな感じがする。

SelfContained について

SelfContained をtrueにするとランタイムがアプリに埋め込まれるが、これがまたでかい (140MBくらい)。これを丸々埋め込むんだったらひょっとすると React Native のほうがマシかもしれないと思うくらいでかい。PublishTrimmed=true, TrimMode=link にしても Windows Forms アプリの場合 50MB くらいはある (しかも最適化に数分待たされる)。

素直に SelfContained は false にしてユーザーに .NET 5 Desktop Runtime を入れさせよう。

PublishSingleFile について

これが無効の場合は exe + dll + 謎のjson2つ(なんちゃら.deps.jsonってやつとなんちゃら.runtimeconfig.jsonってやつ) + α みたいなファイル構成になるが、これを有効にすると全て1つのexeになる。

これは余談だが、PublishSingleFileが無効の時はこの謎のjsonが(うっかり削除してしまうなどして)実行時に見つからないと「To run this application, you must install .NET. Would you like to download it now?」というトンチンカンなエラーメッセージが(たとえ .NET Runtime をインストールしていても)表示されるためにユーザーが混乱する。俺はした。

なので PublishSingleFile は true にすることを強くおすすめしたい。俺みたいなことにならないように。

ところでこの PublishSingleFile を有効にしたファイルは更新が止まってしまった dnSpy では読めないので、PublishSingleFile を有効にしてビルドしたexeファイルの中を見たいような時は ILSpy を使う必要がある。ついでに埋め込まれている謎のjsonの中身も読める。

f:id:rinsuki:20210906064742p:plain