検索
連載

アプリからストアを開くには?[ユニバーサルWindowsアプリ開発]WinRT/Metro TIPS

WindowsストアアプリとPhoneアプリでは、ストアを開くためのコードも共有可能だが、アプリ開発時にはちょっとした調整が必要になる。本記事ではその方法について取り上げる。

Share
Tweet
LINE
Hatena
WinRT/Metro TIPS
業務アプリInsider/Insider.NET

powered by Insider.NET

「WinRT/Metro TIPS」のインデックス

連載目次

 アプリからストアを開きたいことはないだろうか? 例えば、そのアプリが掲載されているストアのページや、あるいは、そのアプリのレビューを書いてもらうページなどだ。本稿ではそれらの方法をまとめて解説する。

 なお、本稿のサンプルは「Windows Store app samples:MetroTips #80」からダウンロードできる。

事前準備

 ユニバーサルプロジェクトを使ってユニバーサルWindowsアプリを開発するには、以下の開発環境が必要である。本稿では、無償のVisual Studio Express 2013 for Windowsを使っている。

  • SLAT対応のPC*1
  • 2014年4月のアップデート*2適用済みの64bit版Windows 8.1 Pro版以上*3
  • Visual Studio 2013 Update 2*4適用済みのVisual Studio 2013(以降、VS 2013)*5

*1 SLAT対応ハードウェアは、Windows Phone 8.1エミュレーターの実行に必要だ。ただし未対応でも、ソースコードのビルドと実機でのデバッグは可能だ。SLAT対応のチェック方法はMSDNブログの「Windows Phone SDK 8.0 ダウンロードポイント と Second Level Address Translation (SLAT) 対応PCかどうかを判定する方法」を参照。なお、SLAT対応ハードウェアであっても、VM上ではエミュレーターが動作しないことがあるのでご注意願いたい。

*2 事前には「Windows 8.1 Update 1」と呼ばれていたアップデート。スタート画面の右上に検索ボタンが(環境によっては電源ボタンも)表示されるようになるので、適用済みかどうかは簡単に見分けられる。ちなみに公式呼称は「the Windows RT 8.1, Windows 8.1, and Windows Server 2012 R2 update that is dated April, 2014」というようである。

*3 Windows Phone 8.1エミュレーターを使用しないのであれば、32bit版のWindows 8.1でもよい。

*4 マイクロソフトのダウンロードページから誰でも入手できる。

*5 本稿に掲載したコードを試すだけなら、無償のExpressエディションで構わない。Visual Studio Express 2013 Update 2 for Windows(製品版)はマイクロソフトのページから無償で入手できる。Expressエディションはターゲットプラットフォームごとに製品が分かれていて紛らわしいが、Windowsストアアプリの開発には「for Windows」を使う(「for Windows Desktop」はデスクトップで動作するアプリ用)。


用語

 本稿では、紛らわしくない限り次の略称を用いる。

  • Windows:Windows 8.1とWindows RT 8.1(2014年4月のアップデートを適用済みのもの)
  • Phone:Windows Phone 8.1

サンプルコードについて

 Visual Studio 2013 Update 2では、残念なことにVB用のユニバーサルプロジェクトのテンプレートは含まれていない*6。そのため、本稿で紹介するコードはC#のユニバーサルプロジェクトだけとさせていただく。別途公開しているサンプルコードには、PCLを使った形のVBのコードも含めてある*7

*6 VB用のユニバーサルプロジェクトは、来年にリリースされるといわれているVisual Studio「14」からの提供となるようだ。「Visual Studio UserVoice」(英語)のリクエストに対する、6月18日付の「Visual Studio team (Product Team, Microsoft)」からの回答による。

*7 Visual Studio 2013 Update 2のVBでユニバーサルWindowsアプリを作る場合のお勧めは、「The Visual Basic Team」のブログ記事(英語)によれば、PCLを使う方法のようである。PCLに置いたものは、コードだけでなくXAML(画面)やリソースディクショナリなども共通に利用できる。そこで別途公開のサンプルコードでも、VBはWindows用/Phone用/共通コード(PCL)の3プロジェクト構成とした。ユニバーサルプロジェクトで作らなくてもユニバーサルWindowsアプリはリリースできるのである(「WinRT/Metro TIPS:ユニバーサルプロジェクトで開発するには?」参照)。


ストアを開く2通りの方法

 アプリからストアを開くには、Webページを経由する方法と、直接ストアのアプリを開く方法がある。以下では、それぞれについて解説していく。

 ただし、Phoneから直接ストアのアプリを開く方法はアンドキュメンテッドである。MSDNなどのマイクロソフトの公式文書には掲載されていない方法であり、予告なく変更される可能性がある。その点を理解した上で利用していただきたい。

Webページを経由してストアを開くには?

 CurrentAppクラス(Windows.ApplicationModel.Store名前空間)のLinkUriプロパティで、そのアプリが掲載されているストアのWebページのURIが取得できる。あとはLauncherクラス(Windows.System名前空間)のLaunchUriAsyncメソッドを呼び出せばよい。

 すなわち、基本的には次に示すコードのようになる。

var storeUri = Windows.ApplicationModel.Store.CurrentApp.LinkUri;
await Windows.System.Launcher.LaunchUriAsync(storeUri);

Webページを経由してストアを開く基本的なコード(C#)

 ただし、これだけでは開発時には都合が悪い。開発中のアプリ自体がストアで公開されるまでは、Windowsでは例外が出るし、PhoneではWebブラウザーは立ち上がるものの該当アプリが存在しないためにストアへリダイレクトされないのだ。

開発時にWindowsで確認するには?

 開発時のWindowsのコードでは、CurrentAppクラスに代えてCurrentAppSimulatorクラス(同じくWindows.ApplicationModel.Store名前空間)を使う。そして、すでに公開済みの他のアプリの情報を設定ファイルに指定すればテストできる。

 CurrentAppクラスとCurrentAppSimulatorクラスについて、また、設定に使う「WindowsStoreProxy.xml」ファイルの場所などについては、「連載:Windowsストア・アプリ開発入門:第11回 アプリに広告を出す(前編:基礎知識編)」の2ページ目をご覧いただきたい。

 CurrentAppSimulatorクラスのLinkUriプロパティを呼び出した際に自動生成される「WindowsStoreProxy.xml」ファイルの冒頭部分は、次のコードのようになっている。

<?xml version="1.0" encoding="utf-16" ?>
<CurrentApp>
  <ListingInformation>
    <App>
      <AppId>00000000-0000-0000-0000-000000000000</AppId>
      <LinkUri>http://apps.microsoft.com/webpdp/app/00000000-0000-0000-0000-000000000000</LinkUri>
      ……省略……

Windowsの「WindowsStoreProxy.xml」ファイルの冒頭部分(XML)
このファイルは、CurrentAppSimulatorクラスの機能を最初に呼び出したときに自動生成される。一度生成された後は、自動的に書き換えられることはない。

 上のコードの<AppId>要素と、<LinkUri>要素のURL末尾(AppIdと同じ部分)を、すでに公開されているアプリのものに変更する。AppIdを調べるには、ストアのWebページのURLの末尾を見るとよい。例えば、筆者が公開している「クラウディアさんタイマー」(Windows版)のAppIdを使って、設定ファイルを次のように書き換える。すると、CurrentAppSimulatorクラスのLinkUriプロパティは、「クラウディアさんタイマー」のWebページのURIを返すようになる。

<?xml version="1.0" encoding="utf-16" ?>
<CurrentApp>
  <ListingInformation>
    <App>
      <AppId>a6c89a77-1440-432b-afd5-1bc9ab001204</AppId>
      <LinkUri>http://apps.microsoft.com/webpdp/app/a6c89a77-1440-432b-afd5-1bc9ab001204</LinkUri>
      ……省略……

Windowsの「WindowsStoreProxy.xml」ファイルのAppIdを書き換える(XML)
AppIdとLinkUri中のAppIdに相当する部分を、すでに公開されているアプリのものに置き換えた(太字の部分)。

開発時にPhoneで確認するには?

 Phoneでは、開発時にもCurrentAppクラスを利用できる。開発時にCurrentAppクラスのLinkUriプロパティが返す値は、「Package.appxmanifest」ファイルで設定できる。

 設定を変えるには、テキストエディターなどを使って「Package.appxmanifest」ファイルを直接編集する。VS 2013で行う場合は、ソリューションエクスプローラーで「Package.appxmanifest」ファイルを右クリックして[ファイルを開くアプリケーションの選択]を選び、表示されたダイアログで[XML (テキスト) エディター]を選んで[OK]ボタンをクリックする。

 「Package.appxmanifest」ファイルの冒頭付近に<mp:PhoneIdentity>要素がある(次のコード)。そのPhoneProductId属性が、WindowsのAppIdに該当する。

<?xml version="1.0" encoding="utf-8"?>
<Package xmlns="http://schemas.microsoft.com/appx/2010/manifest"
         xmlns:m2="http://schemas.microsoft.com/appx/2013/manifest"
         xmlns:m3="http://schemas.microsoft.com/appx/2014/manifest"
         xmlns:mp="http://schemas.microsoft.com/appx/2014/phone/manifest">
  <Identity Name="BluewaterSoft.WinRTMetroTIPS080.CS"
            Publisher="CN=biac" Version="1.0.0.0" />
  <mp:PhoneIdentity PhoneProductId="d07e2e27-e504-4515-a529-ba92a6295040"
                    PhonePublisherId="00000000-0000-0000-0000-000000000000" />


Phoneの「Package.appxmanifest」ファイルの冒頭部分(XML)
読みやすいように改行を入れてある。
<mp:PhoneIdentity>要素のPhoneProductId属性が、WindowsのAppIdに該当する。プロジェクトごとに一意の値がデフォルトでセットされている(ストアでの公開時には変更される)。

 Phoneでも、すでに公開されているアプリのAppIdを調べるには、ストアのWebページのURLの末尾を見るとよい。前述の「クラウディアさんタイマー」(ただしPhone版)のAppIdを使って、設定ファイルを次のように書き換える。すると、CurrentAppクラスのLinkUriプロパティは、「クラウディアさんタイマー」のWebページのURIを返すようになる。

<?xml version="1.0" encoding="utf-8"?>
<Package xmlns="http://schemas.microsoft.com/appx/2010/manifest"
         xmlns:m2="http://schemas.microsoft.com/appx/2013/manifest"
         xmlns:m3="http://schemas.microsoft.com/appx/2014/manifest"
         xmlns:mp="http://schemas.microsoft.com/appx/2014/phone/manifest">
  <Identity Name="BluewaterSoft.WinRTMetroTIPS080.CS"
            Publisher="CN=biac" Version="1.0.0.0" />
  <mp:PhoneIdentity PhoneProductId="bce60b5e-d783-40b9-953d-975895f4397a"
                    PhonePublisherId="00000000-0000-0000-0000-000000000000" />


Phoneの「Package.appxmanifest」ファイルのAppIdを書き換える(XML)
読みやすいように改行を入れてある。
PhoneProductId(=AppId)を、すでに公開されているアプリのものに置き換えた(太字の部分)。

ユニバーサル対応のコードにまとめる

 以上をまとめて、Webページを経由してストアを開くコードを共有プロジェクトに配置するメソッドにすると、次のコードのようになる。

public static async System.Threading.Tasks.Task OpenWebPageAsync()
{
#if WINDOWS_APP
  // Windowsストアアプリの場合
#if DEBUG
  // 開発時はCurrentAppSimulatorを使用する
  var storeUri = Windows.ApplicationModel.Store.CurrentAppSimulator.LinkUri;
#else
  // ストアで公開されたときは、正式なCurrentAppが利用できる
  var storeUri = Windows.ApplicationModel.Store.CurrentApp.LinkUri;
#endif
#endif

#if WINDOWS_PHONE_APP
  // Phoneアプリの場合
  // 常にCurrentAppが利用できる(ただし、開発時とストアで公開された時で異なる)
  var storeUri = Windows.ApplicationModel.Store.CurrentApp.LinkUri;
#endif

  await Windows.System.Launcher.LaunchUriAsync(storeUri);
}

Webページを経由してストアを開くメソッド(C#)
ユニバーサルプロジェクトの共有プロジェクトに配置する(公開しているサンプルソースでは共有プロジェクトにAppStore.csファイルを作成し、AppStoreクラスのメソッドとして定義している)。
Windowsアプリとしてビルドするとき、デバッグビルドではCurrentAppSimulatorクラスを使用し、リリースビルドではCurrentAppクラスを使う。
Phoneアプリとしてビルドする場合は、常にCurrentAppクラスを使う。
どちらも、開発中は前述した設定ファイルの調整が必要だ。
なお、動作の確認ができて、この部分はもうテストしなくてもよいという状況になったら、CurrentAppクラスを使うコードに一本化して「#if」ディレクティブのないすっきりしたコードにしてしまっても構わない。

 これで開発中に(他のアプリのページではあるが)Webページ経由でストアが開くようになる。前述した設定ファイルの変更を忘れずに!

実行結果

 上記のメソッドを、ボタンのクリックイベントなどで呼び出すようにする。そしてデバッグ実行してみると、次の画像のような結果になる。

WindowsアプリでWebページを経由してストアを開く(Windows)
WindowsアプリでWebページを経由してストアを開く(Windows)
WindowsアプリでWebページを経由してストアを開く(Windows)
WindowsアプリでWebページを経由してストアを開く(Windows)
上:画面にある2つのボタンのうち、上のボタンのクリックイベントで前述のメソッドを呼び出すようにした。
中:Windowsでは画面が分割されて、いったんWebブラウザーが立ち上がる。
下:Webブラウザーから、自動的にストアのページに切り替わる。

PhoneアプリでWebページを経由してストアを開く(Phoneエミュレーター)
PhoneアプリでWebページを経由してストアを開く(Phoneエミュレーター)
PhoneアプリでWebページを経由してストアを開く(Phoneエミュレーター)
PhoneアプリでWebページを経由してストアを開く(Phoneエミュレーター)
上:画面にある2つのボタンのうち、上のボタンのクリックイベントで前述のメソッドを呼び出すようにした。
中:Phoneでは画面が切り替わって、いったんWebブラウザーが立ち上がる。
下:Webブラウザーから、自動的にストアのページに切り替わる。

直接ストアを開くには?

 「ms-windows-store:」プロトコルを使えばよい。ただし、WindowsとPhoneでパラメーターが異なる。

 次の表に「ms-windows-store:」プロトコルをまとめておく。なお、前述したようにPhoneの方はアンドキュメンテッドであり、予告なく変更される可能性がある。

書式 説明
ms-windows-store:PDP?PFN=[Package Family Name] アプリの内容ページを開く
[Package Family Name]には、ストアと関連付けした後のPackage.appxmanifestの[パッケージ化]タブの[パッケージ ファミリ名]を記述する
ms-windows-store:Review?PFN=[Package Family Name] アプリの「レビューを書く」ページを開く
[Package Family Name]は上記と同様
ms-windows-store:Publisher?name=[your publisher display name] 発行者から発行された全てのアプリを表示するページを開く
[your publisher display name]には、ストアと関連付けした後のPackage.appxmanifestの[パッケージ化]タブの[発行者表示名]を記述する
ms-windows-store:Search?query=[query] 検索クエリを実行し、ストアの検索結果ページを表示する
[query]には検索文字列を記述する(日本語やスペースなどでもURLエンコードは不要)
ms-windows-store:Updates ストアの更新ページを開く
Windowsの「ms-windows-store:」プロトコル
MSDNの「アプリへのリンク」より。

書式 説明
ms-windows-store:navigate?appid=[AppId] アプリの概要ページを開く
[AppId]には前述(「開発時にPhoneで確認するには?」の項を参照)のAppIdを記述する
ms-windows-store:reviewapp?appid=[AppId] アプリの「評価とレビュー」ページを開く
[AppId]は上記と同様
ms-windows-store:search?keyword=[query]&contenttype=app 検索クエリを実行し、ストアの検索結果ページを表示する
[query]には検索文字列を記述する(日本語やスペースなどでもURLエンコードは不要)
Phoneの「ms-windows-store:」プロトコル
これはアンドキュメンテッドである(本稿執筆時点)。

 以降では、直接ストアを開く例として、レビューのページを開くプロトコルを試してみよう。

Windowsでレビューページを開くには?

 Windowsストアのレビューページを開くには、前掲の表を見ると[Package Family Name]が必要である。これは、Packageクラス(Windows.ApplicationModel名前空間)のCurrent.Id.FamilyNameプロパティで取得できる。ただし、まだストアで公開していないアプリの開発中には、公開済みのアプリの[Package Family Name]に置き換えてテストする。次のコードのようになる。

  var appName = Windows.ApplicationModel.Package.Current.Id.FamilyName;
#if DEBUG
  // ストア未公開のときは、他のアプリのFamilyNameを仮に使ってテストする
  appName = "BluewaterSoft.7013A988D958_48977ph8920gm";
#endif
  var url = "ms-windows-store:Review?PFN=" + Uri.EscapeDataString(appName);
  await Windows.System.Launcher.LaunchUriAsync(new Uri(url));

Windowsでレビューページを開くコード(C#)
「#if DEBUG」内で設定しているFamilyNameは、前出の「クラウディアさんタイマー」のものである。

Phoneでレビューページを開くには?

 Phoneでストアのレビューページを開くには、AppIdが必要である。これは、CurrentAppクラス(Windows.ApplicationModel.Store名前空間)のAppIdプロパティで取得できる。次のコードのようになる。

var appId = Windows.ApplicationModel.Store.CurrentApp.AppId.ToString();
var url = "ms-windows-store:reviewapp?appid=" + Uri.EscapeDataString(appId);
await Windows.System.Launcher.LaunchUriAsync(new Uri(url));

Phoneでレビューページを開くコード(C#)

 開発中に上のコードで得られるAppIdは、前述した「Package.appxmanifest」ファイルの<mp:PhoneIdentity>要素のPhoneProductId属性に設定した値である(「開発時にPhoneで確認するには?」の項を参照)。テストするときは、忘れずに設定しよう。

ユニバーサル対応のコードにまとめる

 以上をまとめて、ストアのレビューページを直接開くコードを共有プロジェクトに配置するメソッドにすると、次のコードのようになる。

public static async System.Threading.Tasks.Task OpenReviewPageAsync()
{
#if WINDOWS_APP
  // Windowsストアアプリの場合
  var appName = Windows.ApplicationModel.Package.Current.Id.FamilyName;
#if DEBUG
  // ストア未公開のときは、他のアプリのFamilyNameを仮に使ってテストする
  appName = "BluewaterSoft.7013A988D958_48977ph8920gm";
#endif
  var url = "ms-windows-store:Review?PFN=" + Uri.EscapeDataString(appName);
#endif

#if WINDOWS_PHONE_APP
  // Phoneアプリの場合
  var appId = Windows.ApplicationModel.Store.CurrentApp.AppId.ToString();
  var url = "ms-windows-store:reviewapp?appid=" + Uri.EscapeDataString(appId);
#endif

  await Windows.System.Launcher.LaunchUriAsync(new Uri(url));
}

ストアのレビューページを直接開くメソッド(C#)
ユニバーサルプロジェクトの共有プロジェクトに配置する(公開しているサンプルソースでは、これも共有プロジェクトに含めたAppStoreクラスのメソッドとして定義している)。
Phoneでの開発中は、前述した設定ファイルの調整が必要だ。

実行結果

 上記のメソッドを、ボタンのクリックイベントなどで呼び出すようにする。そしてデバッグ実行してみると、次の画像のような結果になる。

Windowsアプリでストアのレビューページを直接開いたところ(Windows)
Windowsアプリでストアのレビューページを直接開いたところ(Windows)
画面にある2つのボタンのうち、下のボタンのクリックイベントで前述のメソッドを呼び出すようにした。Windowsでは画面が分割されて、ストアのレビューページが表示される。
なお、レビューが書き込める状態になっているのは、すでにこのアプリ(=「クラウディアさんタイマー」)がインストールされているからである。インストールしていないアプリに対してレビューを書き込めるわけではない。ここで行っているのは、(ダミーの)レビューページが表示されるかどうかの確認である。

Windowsアプリでストアのレビューページを直接開いたところ(Phoneエミュレーター)
Windowsアプリでストアのレビューページを直接開いたところ(Phoneエミュレーター)
Phoneでは画面が切り替わって、ストアのレビューページが表示される。
なお、レビューを書き込める状態になっていないのは、このアプリがインストールされていないからである。

まとめ

 WindowsでもPhoneでも、アプリからストアを開くことが可能だ。Webページを経由して開くこともできるし、直接開くこともできる(Phoneで直接開く方法はアンドキュメンテッド)。しかし、そのコードや開発中のテスト方法などは、WindowsとPhoneとで微妙に異なる。ユニバーサルプロジェクトでは、それらのコードをまとめて共有プロジェクトに置ける。

「WinRT/Metro TIPS」のインデックス

WinRT/Metro TIPS

Copyright© Digital Advantage Corp. All Rights Reserved.

ページトップに戻る