WPFアプリ（.Net Framework）でUWPのAPIを使う

##はじめに
この記事ではタイトルの通りWPFアプリ（.Net Framework）でUWPのAPIを使う方法を紹介します。
UWPのAPIにはWPFアプリでは苦労するようなことも簡単に行うことができるAPIが揃っているため、UWPのAPIを使うと非常に便利です。
UWPのAPIを使う方法は[こちら](https://docs.microsoft.com/ja-jp/windows/apps/desktop/modernize/desktop-to-uwp-enhance)に記載がある以下の2パターンを紹介します。

- NuGetで追加
- 手動で参照を追加

利用可能なUWPのAPIは以下を参照してください。

- [パッケージ デスクトップ アプリで利用可能な UWP API (デスクトップ ブリッジ) - Windows apps | Microsoft Docs](https://docs.microsoft.com/ja-jp/windows/apps/desktop/modernize/desktop-to-uwp-supported-api)

動作を確認した環境は以下の通りです。

- Windows 10 Pro (1903)
- Visual Studio Community 2019
- WPF アプリ (.Net Framework)

## NuGetで追加
1. Visual Studioの [ツール] - [NuGetパッケージマネージャー] - [パッケージマネージャー設定] を開きます。
2. [パッケージの管理] にある [既定のパッケージ管理形式] を「PackageReference」に変更します。
3. Visual StudioでUWPのAPIを使用したいプロジェクトを開きます。
4. [NuGetパッケージの管理] を開きます。
5. 検索ボックスの右側にある [プレリリースを含める] にチェックを入れます。
6. 検索ボックスに「Microsoft.Windows.SDK.Contracts」と入力して検索します。
7. 「Microsoft.Windows.SDK.Contracts」を選択し、ターゲットのWindows 10のバージョンを選択して、インストールします。

|Windows 10|Microsoft.Windows.SDK.Contracts|
|:--|:--|
|version 1903|10.0.18362.xxxx-preview|
|version 1809|10.0.17763.xxxx-preview|
|version 1803|10.0.17134.xxxx-preview|

この方法ですが、[NuGetパッケージの管理] で「Microsoft.Windows.SDK.Contracts」を検索しても表示されなくてはまりました。
NuGetギャラリーで「[Microsoft.Windows.SDK.Contracts](https://www.nuget.org/packages/Microsoft.Windows.SDK.Contracts)」を見ると「preview」と記載があったため、[プレリリースを含める] にチェックが必要であることがわかりました。

## 手動で参照を追加
1. Visual StudioでUWPのAPIを使用したいプロジェクトを開きます。
2. [参照の追加] を開きます。
3. [参照(B)] ボタンを選択し、ファイル選択ダイアログを表示します。
4. 下表のファイルを選択して追加します。

    |ファイル|Location|
    |:--|:--|
    |System.Runtime.WindowsRuntime|C:\Windows\Microsoft.NET\Framework\v4.0.30319|
    |System.Runtime.WindowsRuntime.UI.Xaml|C:\Windows\Microsoft.NET\Framework\v4.0.30319|
    |System.Runtime.InteropServices.WindowsRuntime|C:\Windows\Microsoft.NET\Framework\v4.0.30319|
    |windows.winmd|C:\Program Files (x86)\Windows Kits\10\UnionMetadata\<sdk version>\Facade|
    |Windows.Foundation.UniversalApiContract.winmd|C:\Program Files (x86)\Windows Kits\10\References\<sdk version>\Windows.Foundation.UniversalApiContract<version>|
    |Windows.Foundation.FoundationContract.winmd|C:\Program Files (x86)\Windows Kits\10\References\<sdk version>\Windows.Foundation.FoundationContract<version>|

5. 選択したファイルが参照タブに表示されるので、チェックを入れます。
6. 各.winmdファイルの [プロパティ] で、 [ローカルにコピー] を [False] に設定します。

### はまったところ
ビルドしたところ以下の warning が発生しました。

```
warning MSB3245: この参照を解決できませんでした。アセンブリ "Windows.Foundation.UniversalApiContract" が見つかりませんでした。アセンブリが間違いなくディスクに存在することを確認してください。 コードにこの参照が必要な場合、コンパイル エラーが発生する可能性があります。
warning MSB3245: この参照を解決できませんでした。アセンブリ "Windows.Foundation.FoundationContract" が見つかりませんでした。アセンブリが間違いなくディスクに存在することを確認してください。 コードにこの参照が必要な場合、コンパイル エラーが発生する可能性があります。
```

参照できていないようですので、この時は以下の手順で参照パスを書き換えてください。

1. 参照を追加したプロジェクトの *.csproj ファイルをエディターで起動します。
2. "Windows.Foundation.UniversalApiContract"と"Windows.Foundation.FoundationContract"を検索し、相対パスを絶対パスに変更します。

```
    <Reference Include="Windows.Foundation.FoundationContract">
      <HintPath>C:\Program Files (x86)\Windows Kits\10\References\10.0.17763.0\Windows.Foundation.FoundationContract\3.0.0.0\Windows.Foundation.FoundationContract.winmd</HintPath>
      <Private>False</Private>
    </Reference>
    <Reference Include="Windows.Foundation.UniversalApiContract">
      <HintPath>C:\Program Files (x86)\Windows Kits\10\References\10.0.17763.0\Windows.Foundation.UniversalApiContract\7.0.0.0\Windows.Foundation.UniversalApiContract.winmd</HintPath>
      <Private>False</Private>
    </Reference>
```

参考サイト：
[c# - Referencing Windows SDK winmd files and VS Team Services build - Oipapio- oipapio.com](https://www.oipapio.com/question-4919291)

## さいごに
今回紹介した方法でUWPのAIPを使うと、Windows.UI.Notifications.Management.UserNotificationListener を用いてWindowsの通知を取得するなど、WPFアプリでは難しかったことが簡単にプログラミングできます。
しかし、この方法でも Windows.Devices.Sensors など使うことができないUWPのAPIもあります。
これらのUWPのAPIを使用する方法は別記事で書こうと思います。