非パッケージのWinUI3アプリを、WindowsAppSDKが入っていないPCでも動くようにする

もくじ
https://tera1707.com/entry/2022/02/06/144447#WinUI3

やりたいこと

先日、WinUI3製のアクリル見た目を調整するアプリを作った。

tera1707.com

これを、まっさらインストールしたてのWindows11で動かすと、下記のような、WindowsAppRuntimeが足りない旨エラーが出てしまった。

ネットにつながるPCなら、ここで「はい」を押すと、下記のダウンロードページに飛ぶのだが、

https://docs.microsoft.com/en-us/windows/apps/windows-app-sdk/downloads

ダウンロードせずに、作ったアプリに動くもの全部を入れて、まっさらWindowsでも動くようにしたい。

前提

  • Windows11 Home 21H2 22000.795
  • VisualStudio2022 Community 17.1.4
  • WinUI3.0
  • Windows App SDK 1.1
  • 2022年7月の時点の調査

やりかた

アプリのプロジェクトの設定に、下記を入れる。

<WindowsAppSDKSelfContained>true</WindowsAppSDKSelfContained>

これをcsprojに書くと、必要なランタイム類がビルドの出力先に一緒に入ってくれた。
また、まっさらWindows11で実行したときに、エラーなく動いてくれるようになった。


MSの公式ページがいうところの

  • フレームワーク依存」
    ⇒今回引っかかったような、動くかどうかがそのPCに必要なものがインストールされてるかどうかに依存するということ
  • 自己完結型
    ⇒そのPCに必要なものがインストールされていなくても動作可能

ということっぽい。

実験

<WindowsAppSDKSelfContained>true</WindowsAppSDKSelfContained>のあり/なしで、出力されるものがどうかわるかを実験した。

WindowsAppSDKSelfContained なし と あり で比較

ファイル数が多いので全部をここに書けないが、下記のようなイメージで、ランタイム関連のファイルのありなしで違いが出ていた。

左:WindowsAppSDKSelfContained なし 右:WindowsAppSDKSelfContained あり

Self-Contained なし と あり で比較

これと似た設定項目で、

<SelfContained>true</SelfContained>

というのがある。→以前調べた記事。

以前調べたときは、SelfContainedをtrueにするしないで、ビルド時の出力物が変わってたのだが、なぜか今回試した限りでは、

<SelfContained>true</SelfContained>
<WindowsAppSDKSelfContained>true</WindowsAppSDKSelfContained>

<WindowsAppSDKSelfContained>true</WindowsAppSDKSelfContained>

は、出力される内容が同じだった。

さらに、

<SelfContained>true</SelfContained>

※SelfContained と WindowsAppSDKSelfContained の両方無し

は、同じ出力物だった。

以前調べた結果とどうして違うのかは不明。
(以前:.NET6のコード、 今回:.NET6+WinUI3、の違い??)

参考までに、今回実験に使ったcsprojを上げておく。

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
      <OutputType>WinExe</OutputType>
      <TargetFramework>net6.0-windows10.0.19041.0</TargetFramework>
      <TargetPlatformMinVersion>10.0.17763.0</TargetPlatformMinVersion>
      <RootNamespace>WinUI3Blur</RootNamespace>
      <ApplicationManifest>app.manifest</ApplicationManifest>
      <Platforms>x64</Platforms>
      <RuntimeIdentifiers>win10-x64</RuntimeIdentifiers>
      <RuntimeIdentifier>win10-x64</RuntimeIdentifier>
      <UseWinUI>true</UseWinUI>
      <WindowsPackageType>None</WindowsPackageType>
      <SelfContained>false</SelfContained>
      <WindowsAppSDKSelfContained>true</WindowsAppSDKSelfContained>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.WindowsAppSDK" Version="1.1.2" />
    <PackageReference Include="Microsoft.Windows.SDK.BuildTools" Version="10.0.22621.1" />
    <Manifest Include="$(ApplicationManifest)" />
  </ItemGroup>
</Project>

参考:dotnet publish には、WindowsAppSDK1.1時点では対応してない

個人的に、.NET6で実装するときには、VisualStudioのGUIでビルドをしなくてもいいようにバッチにdotnet publishでビルドできるようにしておきたいのだが、WinUI3(というか、WindowsAppSDK)が、1.1の時点ではまだdotnet publishに対応してないらしい。

以前、dotnet publishのやり方を調べた記事はこちら。

https://docs.microsoft.com/en-us/windows/apps/package-and-deploy/self-contained-deploy/deploy-self-contained-apps

仕方ないので、今回はMSBuildを実行することで対応した。

MSBuildのやり方を調べた記事はこちら。

参考:WIndows App SDKのアンインストール方法

本件の動作を確認するために、いっぺんSDKをアンインストールしたい。

やり方はこちら参照。

参考

自己完結型のアプリの配置方法

https://docs.microsoft.com/en-us/windows/apps/package-and-deploy/self-contained-deploy/deploy-self-contained-apps

自己完結型のWinUI 3アプリケーションを作成する

https://www.ipentec.com/document/csharp-winui3-create-self-contained-executables-application

参考書

WinUI3

WinUI3でアプリを作ろうと思ったときのとっかかりによかった。 msdocsに書いてある情報を、体系的に、順番に読みたいな、というときによいかも。(ただし英語)
この本で分からなかった、かゆいところに手が届かなかった部分を私は記事にしてる感じ。

C#①

表紙に書いてある通り、教科書として最適。 これからC#を勉強したいけど、ネットだけで勉強するのは効率が悪いから体系的に学べる本が欲しいときや、 ちょっとC#を勉強してコード書けるようになったけど、もう少し広く深く知りたいなというときによいと思う。
私は仕事で触れるコードを軸に、基本ネットで断片的にC#を学んだので、その知識の隙間を埋めて枝葉を広げるためにとても分かりやすかった。

C#②

C#の文法的に色々できるのは分かったが、いざ実装するときに、わかったことを使ってどう実装すればいいのか?と悩んだときに指針になりそうな本。
「プロパティ等の名前の付け方、どうすればいい?」「情報をクラス外部に見せるときに、プロパティにすべき?メソッドにすべき?」「異常だと判定したいとき、どんなときにどんな例外をスローすべき?」などなど、勉強になる部分が山ほどあった。
私のように「コードは書くけどこれであってるのか自信がない、レビューで指摘されるのが嫌だ、実装時の(心の)よりどころが欲しい」という人に最適。