Java経験者がWindows App SDK(C#)で実装したアプリをMicrosoft Storeに公開するまでに得た気づき

# 概要
日頃、Javaに触れている筆者が、Windows App SDK(C#)でアプリを作成し、Microsoft Storeに公開した一連の中で得た気づきを共有できたらと考えています...

# 前提・背景
Java：ある程度読み書きできます...
C#：興味をよせてUWPベースでC#を学習していましたが、アプリ開発は初めてです。

# Windows App SDK(WinUI 3)、UWP、WPF、Win32、Windowsフォーム、.NET、WinRT API、Win32 API、COM...
C#でWindowsアプリを作ろうとしている中で、今一度用語の整理の必要性を感じました。

## 解決
用語を整理し調査の結果、新しい手法に興味があったため、Windows App SDK(WinUI 3)で開発することにしました！

### API・フレームワーク
#### Windows API (Win32 API)
Windowsを操作するAPI。厳密には32bitプロセッサのWin32 APIと64bitプロセッサ向けのWin64 APIが存在するが、慣習的にWin32 APIとまとめて呼ばれることもある。

#### Windows Runtime API(WinRT API)
Windows 8から導入された。もとはWindowsストアアプリ開発目的に使用され、UWPアプリケーションの開発ベースAPIでもある。ただし、UWPとWinRT APIはセットではなく独立していて、Windows App SDKでも使用されている。
一部のWinRT APIは従来のデスクトップアプリケーションから利用することもできる。

#### Windows Runtime API(WinRT API)と、Windows App SDKの関係
Windows App SDKは、その機能のほとんどをWindows Runtime API(WinRT API)を通じて提供しているとのこと。Windows Rutime APIはCOMの進化系ともいわれている模様。

#### .NET Framework
マイクロソフトが開発したアプリケーション開発・実行環境。Win32 APIを用いて実装されている。現在は、後継の.NETへ引き継がれた。

#### .NET
クロスプラットフォームかつオープンソースで実装されている。.NET5以降は、 .NET Frameworkの機能が統合され、後継となっている。

#### COM(コンポーネントオブジェクトモデル)
マイクロソフトが提唱した、ソフトウェアの機能を部品化して外部から呼び出して利用する仕組みを定めた技術仕様の一つ。.NET Frameworkへ移行後は主流ではないとのこと。

### Windowsアプリの実装方法

#### Windows App SDK(WinUI 3)
Windows App SDKと付属するライブラリWinUI 3でWindows10以降を対象としたデスクトップアプリを作成する。現在、活発に開発が行われているとのこと。
過去にはProject Reunionと呼ばれ、UWPとデスクトップアプリで分断されていた環境を統合している。
※WinUI 2は、UWPやデスクトップアプリケーション向けのため、WinUI 3とは区別される。

#### Win32(クラシックデスクトップアプリ)
ハードウェアへの直接アクセスを必要とするようなパフォーマンスが求められる場合の開発に適している。

#### UWP
WindowsRuntime API(WinRT API)とXAMLを使用する。

#### WPF
高度なUIやスタイルのカスタマイズが使える。XAMLと呼ばれるXML形式でUIをマークアップで定義できるようになり、コードからUIを分離し開発効率を向上させた。

#### Windowsフォーム
軽量UIなアプリケーションで、XAMLを利用できない。


# Windows App SDKのWinUI3でPartial Trust権限でアプリ作成するために(FullTrustで作成すると、リリース時に影響する...)
FullTrustのままで開発を進めていたとリリース直前にわかりました。
Microsoft Storeにリリース申請する際にアップロードするバンドルファイルが、作成されず手動で作成したり、手動でバンドルファイル作成しアップロードしても、FullTrust権限が必要な理由を別途申告する必要が生じたため、プロジェクト作成をやり直しました...

## 原因・解決
Windows App SDKでは、アプリ実行時の権限の持ち方の観点から、FullTrustとPartial Trustの2種類があると理解しました。

特に必要がなければ、PartialTrustでリリースしたほうが良いと理解しました。

Visual StudioのWinUI 3用アプリのひな型から作成した時点では、FullTrustの設定となっており、Partial Trustに変更するには手動での操作が必要です。

:::note warn
FullTrustを、後からPartial Trustに変更するためには、Windows App SDKのWinUI3のアプリケーションプロジェクトを作成する際に選択するひな形として、「空白のアプリ、Windows アプリケーションパッケージプロジェクトでパッケージ化(デスクトップのWinUI 3)」を選んでおく必要があります。
:::
:::note alert
似たような名称の「空白のアプリ、パッケージ化(デスクトップのWinUI 3)」を選んでしまうと、FullTrustからPartial Trustに変更する手段が見つけられませんでした...(Web検索で見つけられなかっただけの可能性もあり)
:::

## 変更手順
1.  「空白のアプリ、Windows アプリケーションパッケージプロジェクトでパッケージ化(デスクトップのWinUI 3)」を選択してプロジェクトを作成しているものとします。

2.  ソリューションのプロジェクト一覧から、(Package)とついているプロジェクトを開きます。
3.  依存関係 -> アプリケーション -> 配下の要素を選択
4.  ソリューションエクスプローラーの下部に表示されたプロパティ項目の中の「信頼レベル」がプルダウンになっています。押下し、「部分的な信頼」に値を変更します。

5.  Package.appxmanifestファイルを右クリック -> コードの表示　でXML内容を表示させます。
6.  `<Capabilities>`タグとその中にある`<rescap:Capability Name="runFullTrust">`の部分を `<!-- -->`で囲み コメントアウトします。

# デリゲートの概念がわからない
イベントハンドラに関係していることはイメージできました。

## 解決
デリゲートは、メソッドへの参照を表す型のこと。参照型で、変数へ代入できます。C#のイベントハンドラにも使われていると知りました。C#では、一つのデリゲート型変数に複数のデリゲート(=複数のメソッドへの参照)を割り当てることができ、これを「マルチキャスト」と呼ぶことを知りました！

# LINQの認識
読み方は「リンク」とのことです。

## 解決
`LINQ + ラムダ式 ≒　JavaのStream + ラムダ式`
と認識しました。コレクションの要素を操作する際に便利です！

# XAMLで定義したコントロールに対しての処理を、紐づくコードビハインド(.cs)に書きたいのだが...
どうやってXAML定義したコントロールへの参照を取得すればよいのだろうか...

## 解決
XAMLにレイアウトを定義する際、コントロールの要素にx:Name属性を付与し任意の名称を定義することで、コードビハインド(.cs)にてC#で処理を記述する際に、XAMLで定義した名称で対象のコントロールへの参照が取得でき、処理を記述できました！

# WinUI 3でどんなコントロールが使えるのかわからない...
どこかにまとまって情報がないだろうか。

## 解決
Microsoftが公式に「WinUI 3 Gallery」というアプリを公開しています。このアプリではWinUI 3として使えるコントロールが実際に試せる形で確認することができます。サンプルコードも見ることができて便利です！

# GridView内にNavigationViewを配置したものの...
NavigationViewのコンテンツが縦方向に広がらない
## 解決
`<Grid></Grid>`要素内に、`<RowDefinition>`の定義をしていなかったためと理解しました。

```xml:XAML
<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto" />
        <RowDefinition Height ="*" />
    </Grid.RowDefinitions>
    <NavigationView 属性省略 Grid.Row="0" >
        <NavigationView.MenuItems>
            ナビゲーションのメニュー項目定義　省略
        </NavigationView.MenuItems>
        <Frame 属性省略 Grid.Row="1" />
    </NavigationView>
</Grid>
```
`Height="Auto"`で、要素表示に必要な高さとなります。
`Height="*"`で、表示可能な領域内での割合(他を除いた全領域)と認識し、解決しました！

# エラー : System.ArgumentException: 'Value does not fall within the expected range.' on Content Dialog
ContentDialogが、表示できません...

## 解決
ContentDialogを表示するには、Pageインスタンスの`.XamlRoot`の設定が必須と知りました。必要に応じて参照を保持取得するようにし、解決しました！

# エラー : 非同期操作が正常に開始されませんでした。 (0x80000019)"}System.Runtime.InteropServices.COMException
ContentDialogが、表示できません...

## 解決
ContentDialogから、さらにContentDialogを呼び出そうとすると発生するエラーと認識しました。ContentDialogは一度にウィンドウ内に表示できるのは1つと理解し、解決しました！

# TextBox等のコントロールの`.Focus(FocusState.Programmatic)`を実行しているにもかかわらず、Focusが反映されない。
コードビハインドで設定しているフォーカスが、反映されません...

## 解決
XAMLでのレイアウト定義時点で、コントロールのVisibilityをCollapsedにしていることが原因と理解しました。
XAMLのレイアウト定義時点では、Visibilityを指定しないように変更し、コードビハインドでのLoadedイベント発生時に、初期値で非表示にしたいコントロールのVisibleをCollapsedに指定するように併せて実装を変更したところ、フォーカスが設定されるようになり解決しました！

# エラー：Microsoft.UI.Xaml.Markup.XamlParseException: 'XAML parsing failed.'
XAMLの定義がおかしいものと、何度も確認したが、XAMLはあっている...

## 解決
XAMLの記述ミスだけでなく、Resource.reswファイルの記述ミスも疑うべきだと理解しました。
XAMLにてコントロールの属性に`x:Uid="任意の名称"`を付与しておくと、Resource.reswに同一の名称で定義しておくことで、対象のコントロールの任意のプロパティ値を設定することができます。
この時、Resource.reswファイルにて、x:Uidで紐づくコントロールには存在しないプロパティ属性を記述していたり、GridのColumnやRowの指定インデックスに矛盾があったりしていても発生しうることを認識し、解決しました！

# エラー : System.Runtime.InteropServices.COMException: '要素が見つかりません。 (0x80070490)'
原因不明...

## 解決
`CoreApplication.GetCurrentView().TitleBar`で参照を取得しようとしている個所が原因でした。WinUI 3では、`AppWindow.TitleBar`から参照を取得する必要があると理解し、解決しました！

# クリーンビルドしても、コンパイルエラーが消えない
原因不明...記述したC#ソースコードの文法はあっている。

## 解決
Visual Studioでのアプリ実行時の設定（再生ボタンの左隣付近にあるプルダウンになっている個所）を、DebugからReleaseにしてアプリ実行しなおしたところ、解消しました！

# アプリリリース時にアプリ名の予約を行う際、Visual Studioから行おうとすると「アプリ名を予約しようとしたときに予期しないエラーが発生しました。」と表示され、予約できない。
Microsoft Storeでアプリをリリースするための申請の前準備として、アプリ名がすでに使用されていないかをチェックし、アプリ名を確保する作業として「アプリ名の予約」を行います。

Visual Studioにて、プロジェクト -> 公開 -> アプリパッケージの作成　で進むとダイアログが表示されます。
ダイアログのタイトル「配布方法を選択する」の下に選択肢があります。
「新しいアプリ名でMicrosoft Storeに」を選択し次へ進むと、アプリケーション名の予約画面に遷移します。
しかし、ここで予約を試みると、表題の「アプリ名を予約しようとしたときに予期しないエラーが発生しました。」のエラーメッセージが表示され、予約できませんでした...

## 解決
アプリ名の予約はWebからも行うことができます。Microsoftの公式サイトから「Microsoftパートナーセンター」へアクセスし、アプリとゲーム -> 新しい製品 -> MSIXまたはPWAアプリ を選択すると、「名前を予約してアプリを作成」ダイアログが表示され、予約に成功しました！
「Microsoftパートナーセンター」Web経由で予約成功後に、Visual Studioにて、プロジェクト -> 公開 -> アプリパッケージの作成　で改めて進むと、予約した名称が反映されていることを確認できました！

# リリース申請用パッケージ作成後に、認証キットでの事前チェックをした方が良いとのことで、「パッケージの作成が完了しました」ダイアログの「Windowsアプリ認定キットを起動する」をクリックしたところエラーが発生した...
エラー発生時に、「ツール AppCert.exe が見つかりませんでした。Windows ソフトウェア開発キットの最新のインストールにWindowsアプリ認定キット機能が含まれていることをご確認ください。」とメッセージが表示されました...

## 解決
Windows SDKを未インストールだったことが原因でした。　Visual Studio InstallerでWindows SDKをインストールし解決しました！

# Microsoftパートナーセンターにて、リリース申請の中でアプリパッケージをアップロードした後、「パッケージ受領の検証に関する警告: The following restricted capabilities require approval before you can use them in your app: runFullTrust.」と表示されている...
Web情報ではそのままでOKとあったが、そのままリリース申請を進もうとすると、runFullTrust申請が必要な理由を別途申告する必要があると判明しました。

## 解決
今回は、アプリの機能としてFullTrustの権限は大きすぎたので、PartialTrust権限でリリースするために、プロジェクトをPartialTrust設定 適用可能な形で作成しなおしました。

既存のFullTrustのプロジェクトはいったん残して置き、クラスやパッケージなどの一式をコピー・ペーストで移行するとともに、各種設定ファイルの内容も移行すればOKで、解決しました！

[PartialTrust権限でアプリ作成するために へ戻る](#windows-app-sdkのwinui3でpartial-trust権限でアプリ作成するためにfulltrustで作成するとリリース時に影響する)
あるいは、アプリ上必要であればFullTrustのままで別途申告し申請を進める場合もありそうです...

# ストア申請したはずが、申請状態が解除されている...
certification reportという項目が申請ページに表示されて、Status: Attention neededとなっていて、Report detailsに英文で書かれていました。

## 解決
申請却下されていると理解し、certification reportの内容を確認しました。今回の場合は、指定手順でエラーが発生するとの報告内容で、原因を調査し当該手順でエラーが起きないように改修の上、再度パッケージを生成・アップロードし、再申請を行いました...数日後、申請が通りMicrosoft Storeにアプリ公開となりました！

# むすび
Javaとの違いを認識しながら今後もC#とWindows App SDKとWinUI 3を使ったアプリ開発に触れていきたいと考えています...
最後までお読みくださり、ありがとうございました！