DsktopBrigde (DACを含む) サンプルについて

今回は、Desktop App Converter のチュートリアル的なサンプルであり、DesktopBridge Sample を紹介します。具体的には、実際のコードを見て頂くとして、この記事ではどのようなサンプルが提供されていて、どのような構造になっているかを解説します。

最初の入門として見るのは、HelloWorldSample か JourneyAcrossTheBridge のサンプルになります。

HelloWorldSample

cs フォルダと CentennialPackage フォルダが含まれており、cs フォルダが C# のコンソール アプリケーションになっており、CentennialPackage フォルダは、手作業でAppxを作成するための Appx レイアウト フォルダになっています。このサンプルでは、Desktop App Converter を使用することなく、デスクトップ アプリを Appx パッケージにすることを学習するためのものになっています。

JourneyAccrossTheBridge

このサンプルには、ステップ1からステップ5までの5種類が含まれています。学習の流れで説明すると、ステップ1 から ステップ 3が、Windows Forms のデスクトップ アプリを Appx 化 (ステップ1) して、タイル更新を追加(ステップ2)、バックグラウンド タスクを追加(ステップ3) と順番に既存のデスクトップ コードを機能拡張する流れになっています。

ステップ 4 以降は、それまでの流れではなく、UWP のアプリから デスクトップのコードを アプリ サービスとして使用し(ステップ4)、完全な UWP アプリへの移行(ステップ 5)となっています。

ステップ1

学習することは、HelloWorldSample と同じです。異なるのは、コンソール アプリではなく、Windows Forms を使用した GUI のアプリという点であり、使用する Visual Studio が 2015 ではなく、2017(プレビュー)になっており、Desktop to UWP packaging Project を使用するようになっていることです。Desktop to UWP Project で作成したプロジェクトは、Appxレイアウトのフォルダを指定し、変換対象のプロジェクトをソリューションに追加することで、Appx の更新やデバッグが容易になるという特徴があります。Desktop to UWP Project の使い方は、変換済みの UWP アプリを展開してデバッグするに記述されている「F5デバッグ」で詳しく説明しています。

ステップ2

タイル更新を追加するために、Windows.wnimd への参照を追加してから、コンボボックスのSelectionChanged イベント ハンドラ内に TileUpdateManager クラスと TileNotification クラスを使用してタイル通知を行うコードを追加しています。

ステップ3

ステップ2 へバックグラウンド タスクを追加するために、BackgroundTasks プロジェクトを Windows ランタイム コンポーネント プロジェクトとして追加しています。このバックグラウンド タスクは、アプリケーション設定の「Status」キーに設定された文字列を使って、トースト通知を行います。

AppxManifest へバックグラウンド タスクを追加するには、以下の3種類の作業が必要になります。

  • Extension 要素で UWP アプリと同様に windows.backgroundTasks の設定を行います。
  • Extension 要素で windows.activatableClass.inProcessServer の設定を行います。
    この理由は、デスクトップのアプリなので、アプリの仕組みを自動的に使えないためです。
  • 作成した BackgroundTasks.winmd と BackgroundTasks.pri を Appx レイアウトへコピーしておきます。

Windows Forms のアプリケーションでは、以下の作業を行っています。

  • Program.cs で、バックグラウンド タスクの登録を行います。コードは、UWP アプリで使用するものと同じです。
  • Form1.cs で、Form1_Load イベント ハンドラでアプリケーション設定の [Status] キーへ文字列を設定します。

こうすることで、バックグラウンド タスクが Time トリガーによって 15 分間隔でトースト通知を表示するようになります。

ステップ4

既に説明したように、ここでステップ 3までとは異なる構造へと変わります。具体的には、MyDesktopApp プロジェクト (デスクトップ のアプリ)、BackgroundTasks プロジェクト (これは、ステップ3のものと同じです)、最後に MyUWPApp プロジェクト(純粋な UWP アプリ)の 3 プロジェクトで構成されていて、ステップ 3まで存在していた Desktop to UWP Project は無くなっています。この理由は、MyUWPApp という UWP アプリで配置などを行うからです。

MyDesktopApp プロジェクトの特徴は、次のようになります。

  • C# のコンソール アプリケーションです。
  • Windows.winmd への参照設定を行っています。
  • レジストリに設定している CurrentState を アプリケーション設定の [Status] キーへ保存します。
  • 新しいスレッドで AppService をホストするコードを記述しています。AppService で CurrentState を ValueSet をクライアントへ返します。

MyUwpApp プロジェクトの特徴は、次のようになります。

  • ターゲット プラットフォームを 10.0.14393.0 に固定します。
  • BackgroundTasks プロジェクトへ参照を設定します。
  • Windows Desktop Extension 10.0.14393 拡張SDK への参照を設定します。
  • ポスト ビルドで、MyDesktopApp の出力である exe と pdb を$(OutDir)AppX フォルダーへコピーします。
  • App.xaml.cs の OnBackgroundActivated イベント ハンドラで、AppService の処理を記述し、メッセージを受信したら StatusUpdated イベントを呼び出します。
  • MainPage.xaml.cs で、StatusUpdate イベントのハンドラを記述し、受信したメッセージでコンボボックスを選択するコードを記述しています。
    OnNavigatedTo イベント ハンドラで、バックグラウンド タスクの登録をし、FullTrustProcessLauncher クラスを使って MyDesktopApp を起動します。
    コンボボックスの SelectionChanged イベント ハンドラで、MyDesktopApp のApp Service へメッセージを送信し、受信したデータでタイル更新をします。
  • Package.appxmanifestには、次のような変更を加えています。
    デバイス ファミリ を Windows.Desktop に固定。
    ネームスペースに、rescap と desktop を追加。
    Extension にバックグラウンド タスクと windows.appServiceの定義を追加し、desktop:Extension 要素で windows.fullTrsustProcess として MyDesktopApp.exe を追加し、rescap:Capability runFullTrust を追加します。

このような構造になっています。ここでポイントは、デスクトップ アプリが AppService をホストしている点と UWP アプリが デスクトップ アプリの AppService を起動するために、FullTrustProcessLauncher クラスを使用している点です。通常の UWP アプリ同士であれば、AppService 側は自動的に起動されますが、デスクトップ アプリでAppService をホストするケースでは、自動的に起動できないので、UWP アプリ 側で起動する必要があるということになります。このための設定が、desktop:Extension の windows.FullTrustProcessになり、この記述は Appx内に同梱した完全信頼の実行ファイルを 1 つだけ記述することができます。

ステップ5

ステップ 4までのソリューションを完全な UWP アプリ化するために、MyUWPAppプロジェクトとBackgroundTasks プロジェクトの 2つだけに統合します。

BackgroundTasksSample

JourneyAccrossTheBridge のステップ 3 と同じになります。

AppServiceBridgeSample

C# と C++ を使用したサンプルがありますが、考え方は JourneyAccrossTheBridge のステップ 4 と同じになります。

NorthwindSample

C# のサンプルで AppService を使用しますので、JourneyAccrossTheBridge のステップ 3と同様の考え方でなりたっていますが、Northwindという名前から予測できるように SQL Compact を使ったデータベースへのアクセスをラップした C# のデスクトップ アプリを使用しています。

StoreSample

ストアのAPIを使用する C# のWPF アプリケーションで、Desktop to UWP packaging Project を使用しています。

このサンプルを通して DAC で変換したアプリを拡張する時に注意点は、以下のようなことになります。

  • Windows メタデータへの参照設定が必要
    C++ の場合は、Windows ランタイムを使用できる Windows SDK を使用する必要がある
  • UWP アプリから、Appx 内のデスクトップ実行ファイルを起動するには、FullTrustProcessLauncher クラスを使用する。
    同梱できるデスクトップ実行ファイルは 1つだけという制限がある。
  • 拡張するには、AppService などがやりやすい。
  • タイルやトースト通知を使用する場合は、AppUserModelId が必須(UWP アプリは自動的に付与されます)。

DAC で変換したAppxの価値を高めるためにも、利用シーンに応じた拡張を考えることが重要になってくることでしょう。