🍣

WPF使いのためのWinUI 3:Template Studioで生成してUnpackagedでデバッグ実行できるようにする手順

に公開

概要

WPFは使っているが、UWPはスルーしてきた。WinUI 3に挑戦したい。私はそういう状況ですが、同じ人は割と多いと思います。そういう人向けに、WPFと違うところを中心にWinUI 3を始めるための情報を書いていこうと思います。

WinUI 3のプロジェクトを作る上でもWPFと同じく、最初からMVVMが構成されているTemplate Studioは使いやすいです。

https://marketplace.visualstudio.com/items?itemName=TemplateStudio.TemplateStudioForWinUICs

しかし、テンプレートから作成した時点のコードでは、.NET 8でのUnpackagedのデバッグ実行すらできません。最低限としてそこまでたどりつくまでに必要なことを紹介します。

最初に結論まとめ

次の変更をすればOKです。

  1. プロジェクトファイル・発行用pubxmlファイルの「net7.0-~」の数字を新しい.NETに変更
  2. architectureの記法を新しいものにするため、プロジェクトファイルと発行用の.pubxmlファイルの、win10-x64などの記載から10を取ってwin-x64のように変更
  3. NuGetの参照を最新版に変更。特にWindowsAppSDKはインストールされているSDKと同じバージョンまで上げる必要あり
  4. Unpackagedで実行されている場合にPackageType=Noneで動くように、プロジェクトを設定

次のコミットに、必要な変更が全てまとまっています。

https://github.com/suusanex/sample_azure_ai_foundry_local_chat/commit/6840dca261501f0908c6ed38f9ce4b9e5f2b9203

説明

Template Studioでのプロジェクト作成

WinUI 3のTemplate Studioを入れると、「WinUI の Template Studio」というテンプレートが選択できます。

image.png

このままウィザードで選択していけば生成できます。そのまま作成しても良いですが、最もシンプルな構成にしたい場合は最初の画面で「空白」を選びます。

image.png

WPFのTemplate Studioと同じく、ちゃんとGeneric Host・Community Toolkitが組み込まれてMVVM構成になったプロジェクトが出来上がります。これだけでも素のテンプレートよりだいぶ使いやすいですね。

WPFにはなかった要素として、PackagedとUnpackagedがあります。Unpackagedとは、いわゆる従来のWin32アプリと同じで、ストア配布ではなくexe&dllの配布で実行できる形態のことです。WPFと同じイメージで使おうとする場合、まずUnpackagedで使ってみたいというケースが多いと思います。

これも、最初から選択できるように構成されています。デフォルトはPackagedなので、Unpackagedで使いたい場合はここを変更する必要があります。

image.png

動くようにする1:.NET 7から8(もしくは9)へ

さて、さっそくビルドして動かしてみたいところですが・・・Template Studioが更新されていないようで、出力されるのは.NET 7のプロジェクトです。古い!なので、新しい.NETでビルドできるようにする必要があります。

次の変更が必要です。

.NETのバージョン変更

これは単純にバージョンを上げるだけです。プロジェクトファイルを開くと、次のような項目が有ります。

<TargetFramework>net7.0-windows10.0.19041.0</TargetFramework>

これを希望の.NETに変えればOKです。

<TargetFramework>net8.0-windows10.0.19041.0</TargetFramework>

Windowsの対象バージョンも10なので、もうWin10を考慮しなくて良い用途ならばついでに10.0.22000.0(Win11)などに上げると良いと思います。

<TargetFramework>net9.0-windows10.0.22000.0</TargetFramework>

プロジェクトが2つ生成されているので、両方とも変更する必要がある点に注意です。

「作成したプロジェクト名」と「作成したプロジェクト名.Core」の2つですが、後者はモジュールを分ける必要が無いのであれば、ここでプロジェクトごと削除してしまっても良いと思います。(DIコンテナ登録部分で登録しているCoreのクラスと、”Core”が付く名前空間のusingの削除が必要になるので、注意)

アーキテクチャの記法変更

x64などのアーキテクチャを指定する記法が変わっているため、そのままではビルドが通りません。これも機械的な変更でOKです。プロジェクトファイルの変更ですが、発行用の.pubxmlファイルも用意されているのでそちらも合わせて変更する必要があります。

プロジェクトファイルの次の部分を

<RuntimeIdentifiers>win10-x86;win10-x64;win10-arm64</RuntimeIdentifiers>

次のように変更します。つまり「10」を外すだけです。

<RuntimeIdentifiers>win-x86;win-x64;win-arm64</RuntimeIdentifiers>

プロジェクトのProperties\PublishProfilesフォルダに、.pubxmlファイルが3つ入っています。こちらも同様に「10」を外す形で変更します。1つだけ例示すると

<RuntimeIdentifier>win10-x64</RuntimeIdentifier>

を次のように変更します。

<RuntimeIdentifier>win-x64</RuntimeIdentifier>

これで、最新.NETでのビルドが通るようになります。

動くようにする2:NuGetパッケージのバージョンを最新に

参照しているNuGetパッケージのバージョンも古いので、最新に上げていきましょう。特にWindowsAppSDKのバージョンが古いと、最新版SDKをインストールしていてもバージョン違いで動作しません。この記事を書くために作った時のバージョンでは、次のように変わります。

元のバージョン:

    <PackageReference Include="CommunityToolkit.Mvvm" Version="8.1.0" />
    <PackageReference Include="Microsoft.Extensions.Hosting" Version="6.0.1" />
    <PackageReference Include="Microsoft.WindowsAppSDK" Version="1.4.231008000" />
    <PackageReference Include="Microsoft.Xaml.Behaviors.WinUI.Managed" Version="2.0.9" />
    <PackageReference Include="WinUIEx" Version="2.3.2" />

最新版:

    <PackageReference Include="CommunityToolkit.Mvvm" Version="8.4.0" />
    <PackageReference Include="Microsoft.Extensions.Hosting" Version="9.0.6" />
    <PackageReference Include="Microsoft.WindowsAppSDK" Version="1.7.250606001" />
    <PackageReference Include="Microsoft.Xaml.Behaviors.WinUI.Managed" Version="3.0.0" />
    <PackageReference Include="WinUIEx" Version="2.6.0" />

動くようにする3:Unpackagedで実行するための設定

ビルドが通るようになったのでさっそくUnpackagedで実行すると、妙な例外が出ます。

System.DllNotFoundException: 'Unable to load DLL 'Microsoft.ui.xaml.dll' or one of its dependencies: 指定されたモジュールが見つかりません。 (0x8007007E)'

例外からは分かりづらいですが、これはUnpackaged用のプロジェクト設定になっていないことが原因です。

プロジェクトに次の設定を足しましょう。


	<PropertyGroup Condition="'$(Packaged)' != 'true'">
		<WindowsPackageType>None</WindowsPackageType>
	</PropertyGroup>

必要なのはWindowsPackageTypeをNoneにする事だけですが、ここでは「Packagedではない場合にだけ」という条件を付けることで、Packagedの構成と両立できるようにしています。

動きました

Unpackagedでデバッグ実行できました!

image.png

まとめ

WinUI 3にチャレンジしようにも、まずは素のデバッグ実行が成功してくれないと始める気にもならないと思います。この記事の手順でそこにたどり着けるので、まずはスタートラインに立ちましょう!

Discussion