Windows App SDK(Unpackaged)をランタイム同梱（自己完結型）で配布する方法と、そのファイルサイズ例

# 概要

[前の記事](https://qiita.com/spc_ksudoh/items/40d952c9864c5c2d6995)ではWindows App SDK(Unpackaged)のランタイム配布について書きましたが、まだまだマイナーなランタイムなので、同梱して自己完結型で配布したいという場合も有ると思います。そのやり方や、やった場合のファイルサイズについてこの記事にまとめます。

この記事の内容は、全て.NET 8のものです。9以降では変わってくるかもしれません。

# 最初に結論まとめ

WPFもWinUI 3も同じ設定で.NETとWindows App SDKランタイムを同梱できます。どちらもVC++ランタイムは別途インストールする必要がある点に注意です。

WinUI 3はトリムできますがWPFはできないので、WPFはだいぶサイズが大きくなります。

プロジェクト設定は次のようにして、UnpackagedかつWindows App SDKランタイム同梱にします。

```xml

<PropertyGroup>
    <RuntimeIdentifiers>win-x64</RuntimeIdentifiers>
    <WindowsPackageType>None</WindowsPackageType>
    <WindowsAppSDKSelfContained>true</WindowsAppSDKSelfContained>
</PropertyGroup>	  
	  
<ItemGroup>
    <PackageReference Include="Microsoft.WindowsAppSDK" Version="1.7.250401001" />
</ItemGroup>
```

発行では配置モードを自己完結にします。

```xml
<SelfContained>true</SelfContained>
```

# 詳しく

まずWindows App SDKを使う場合は、msixファイルでパッケージして配布するPackagedタイプか、従来のexeなどと同じようにファイルを何らかの手段（msiインストーラなど）で配布するUnpackagedタイプを選択します。Windowsサービスとセットにするなど製品の一部として使う場合はUnpackagedになると思いますが、そちらの情報が少ないので、この記事ではUnpackagedタイプの配布方法について扱います。

## VC++ランタイムは別配布

この記事ではランタイム同梱の自己完結型を作る方法を書きますが、Windows App SDKにはVC++ランタイムも必要になります。[VC++ランタイムは同梱せずに再頒布インストーラで入れる](https://learn.microsoft.com/ja-jp/cpp/windows/latest-supported-vc-redist)のが基本であり、そこはWindows App SDKでも変わりません。以降の説明では触れないので、VC++ランタイムについては別途配布してください。

## Unpackagedの設定

WinUI 3のテンプレートで作成した場合や普通にWindows App SDKだけを組み込むと、Packagedタイプになっていると思います。これをUnpackagedにするには、まずプロジェクトに次の設定を追加する必要があります。これはWPFでもWinUI 3でも同じです。

```xml
<PropertyGroup>
    <RuntimeIdentifiers>win-x64</RuntimeIdentifiers>
    <WindowsPackageType>None</WindowsPackageType>
</PropertyGroup>	  
	  
<ItemGroup>
    <PackageReference Include="Microsoft.WindowsAppSDK" Version="1.7.250401001" />
</ItemGroup>
```

RuntimeIdentifiersは環境に合わせて複数設定できます。上記はx64だけのケースです。

この時点で発行すれば、ランタイムインストール済みの環境で起動できるexeのできあがりです。ランタイムのない環境では、ランタイムのインストールが必要というエラーが出ます。

## ランタイム同梱（自己完結型）の設定

ランタイム同梱の自己完結型で配布するためには、必要な設定が2つあります。

まずプロジェクトに次の設定を加えてWindowsAppSDKを同梱します。

```xml
<PropertyGroup>
    <WindowsAppSDKSelfContained>true</WindowsAppSDKSelfContained>
</PropertyGroup>
```

次に、発行（Publish）で配置モードを自己完結にする事で、.NETを同梱します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3616143/b0d23ea0-560e-46a9-b204-f6ea18d9d8a5.png)

pubxmlファイルでは次の設定です。

```xml
<SelfContained>true</SelfContained>
```

ここまで設定してから発行すると、ランタイムの無い環境でも実行できるexeが出来上がります。

### WinUI 3はx64,Arm64等を間違えないように

WinUI 3のテンプレートでプロジェクトを作ると、最初から3つの発行設定が作成されていて、デフォルトではArm64が選択されています。多くのケースではx64で使うと思いますが、このままArm64向けの設定で発行してもx64では動作しないので、x64で動かそうとしている場合は選択を間違えないように注意です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3616143/3c5cdd26-d996-47a7-8265-d2b55cb38bca.png)
↓
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3616143/3b00bdf5-ef65-4fa7-822e-b9089b304dfa.png)

# サイズを減らす方法

## WinUI 3

WinUI 3では不要なライブラリをトリムすることで、サイズを小さくすることができます。どの程度の効果があるかは使っているライブラリにもよりますが、次の章で一例を示します。

発行設定で、次のようにチェックをONにすればOKです。なぜかUIからチェックを入れるとチェックがグレーアウトして外せなくなるようですが、その場合はpubxmlファイルから編集すればOKです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3616143/a47af553-e36d-4eda-a927-830dbbae36fe.png)

pubxmlファイルでは次の設定です。

```xml
<PublishTrimmed>true</PublishTrimmed>
```

## WPF

残念ながら、WPFではサイズを減らす手段はなさそうです。

# 自己完結型のサイズ

自己完結型は当然ファイルサイズが大きくなりますが、どの程度大きくなるかによって実用で使えるかが変わってくると思います。空っぽの画面でどの程度のサイズになるか、試してみました。

TargetFrameworkは全て、「net8.0-windows10.0.19041.0」を使用しています。この「windows～」が入ることで約25MBの「Microsoft.Windows.SDK.NET.dll」が増えるので、ランタイム同梱無しでも30MB程度にはなります。そこから、自己完結型にすることでどの程度サイズが増えるかがポイントです。

次の結果となりました。トリムの効果はかなり大きいようです。トリム非対応の分だけWPFはだいぶ大きくなってしまうので、サイズを気にするのならWin UI3への移行を考えた方が良さそうです。

## WinUI 3

|条件|サイズ|
|---|---|
|同梱無し|35.8MB|
|全て同梱（トリムあり）|77.1MB|

### 内訳の比較（参考）

|条件|サイズ|
|---|---|
|.NETだけ同梱|106MB|
|.NETだけ同梱（トリムあり）|20.2MB|
|全て同梱（トリムあり）|77.1MB|

## WPF

|条件|サイズ|
|---|---|
|同梱無し|35.5MB|
|全て同梱|232MB|


### 内訳の比較（参考）

|条件|サイズ|
|---|---|
|.NETだけ同梱|195MB|
|.NETだけ同梱（jaのみ※1）|181MB|
|全て同梱|232MB|

※1 デフォルト設定だと全てのランゲージファイルが含まれるため、これをja（日本語）だけに限定した場合

# まとめ

Windows App SDKのランタイム同梱は、直観的にUIで設定という感じではありませんが、やり方が分かれば容易に出来ました。ただしだいぶサイズが大きくなるので、サイズを気にする場合はWPFにWindows App SDKを組み込むよりも、WinUI 3にした方が良さそうです。