「タイムライン」に登録する
アプリから「タイムライン」に登録する方法は2通りあります。1つは、PC上で動作しているアプリから、前回に紹介したUWPのAPIを使って、ローカルPCに登録する方法。もう一つは、RESTなWebサービスであるMicrosoft Graph APIを使う方法です。後者は、activities APIを使ってクラウドに登録することで、そのユーザーのWindows PCにプッシュ配信されます。この方法は、アプリでMicrosoftアカウントでのユーザー認証を処理しなければならないので面倒ですが、その代わりに、クロスプラットフォームで利用できるというメリットがあります(例えば、Xamarin.Formsで実装すれば、iOS/Android/Windows 10 Mobileから「タイムライン」に登録できるようになります)。
今回の題材はWPFアプリですから、実装が簡単なUWP APIを使いましょう。
WPFのプロジェクトを作る
まず、Visual Studio 2017(15.5以降)でWPFのプロジェクトを作りますが、そのときのターゲットフレームワークは.NET Framework 4.6.2にしてください。これは後ほどデスクトップブリッジを使う都合です(詳細は後述)。
WPFのWebBrowserコントロールについて
今回のサンプルコードは、前回と同様のごく簡単なWebブラウザです。WPF標準のWebBrowserコントロールを使っているので、JavaScriptエラーのポップアップを抑止したり、Webページ表示時の例外を除外したりするために、ちょっとトリッキーなことをやっています(MainWindow.xaml.csのコンストラクタとWebView1_Navigatedメソッドを参照)。また、IEベースですので、最近のWebページは表示が崩れてしまうことが多いです。
Windows 10 1803以降であれば、UWPのWebViewControlクラス(Windows.Web.UI.Interop名前空間)をラップしたWebViewコントロールが利用可能です(本稿執筆時点ではプレビュー版)。上記のようなトリッキーなコードを書かずにすみますし、Edgeベースなので表示もEdgeと同じになります。現時点で利用するには、NuGetから Windows Community ToolkitのMicrosoft.Toolkit.Win32.UI.Controlsパッケージ(本稿執筆時点でv3.0.0-preview)をプロジェクトに導入します。
UWP APIへの参照を追加する
第2回の3ページ目「手動でセットアップする方法」のようにして、UWP APIへの参照をプロジェクトに追加します。「タイムライン」を使うには、SDKバージョンが10.0.16299.0以降のものを選びます。
今回のサンプルコードに追加した参照は、次の2つです。
- System.Runtime.WindowsRuntime.dll
c:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETCore\v4.5\ - Windows.WinMD
c:\Program Files (x86)\Windows Kits\10\UnionMetadata\10.0.16299.0\
参照を追加したら、WinMDファイルは出力ディレクトリーにコピーされないように設定を変更しておいてください。ソリューションエクスプローラーの[参照]にあるWindows.WinMDファイルを選び、その下の[プロパティ]ペインで[ローカルにコピー]を探してTrueからFalseに変えます。
「ユーザーアクティビティ」を登録するメソッド
「ユーザーアクティビティ」を登録するコードそのものは、前回で紹介したUWPアプリのものとまったく同じです。サンプルコードでは、登録するメソッドを収めたTimelineHelperクラスを共有プロジェクト(Shared Project)に置いて、UWPアプリと今回のWPFアプリに同一のコードを含めるようにしています。
画面から「ユーザーアクティビティ」を登録するメソッドを呼び出す
前回は上記のメソッドを無条件に呼び出していました。なぜなら、「タイムライン」APIが実装されたWindows 10 1709(16299)以降でなければインストールできないパッケージにしたからです。今回のWPFアプリは、.NET Framework 4.6.2以降がインストールされているWindowsであれば動作しますから、「タイムライン」APIが利用できるかどうかの判定が必要になります。
そこで、Appクラスに次のコードのようなIsTimelineAvailable静的プロパティを作りました(後ほどデスクトップブリッジのところで条件を追加します)。
// Windows のバージョン // ※ System.Management アセンブリへの参照追加が必要 private static Version _osVersion { get; } = (new Func(() => { using (var mc = new System.Management.ManagementClass("Win32_OperatingSystem")) using (var moc = mc.GetInstances()) foreach (System.Management.ManagementObject mo in moc) { var v = mo["Version"] as string; if (!string.IsNullOrWhiteSpace(v)) return new Version(v); } return new Version("0.0.0.0"); }))(); // 「タイムライン」が利用可能か? // 「タイムライン」 API が使えるのは、Win10 1709 (16299) 以降 public static bool IsTimelineAvailable { get; } = (_osVersion >= new Version("10.0.16299.0"));
画面からは、上のIsTimelineAvailable静的プロパティがtrueのときだけ、「ユーザーアクティビティ」を登録するメソッドを呼び出すようにします(次のコード)。
if (App.IsTimelineAvailable) await TimelineLIb.TimelineHelper.Current.AddToTimelineAsync(url, GetCardType());
以上で、WPFアプリから「タイムライン」に登録できるようになりました。
デスクトップブリッジ専用なら、API利用可否判定は不要
ここでは、「UWPアプリ化」していない生粋のWPFアプリも配布することを想定しています。もしもデスクトップブリッジで「UWPアプリ化」したパッケージだけを配布するなら、このようなバージョンチェックは不要です。「UWPアプリ化」したパッケージは、指定したバージョン以降のWindows 10にしかインストールできませんから。