しばやん雑記

Azure とメイドさんが大好きなフリーランスのプログラマーのブログ

Windows Containers 上で動かしている IIS に URL Rewrite や ARR をインストールする

Microsoft が Docker Hub に公開している IIS や ASP.NET のイメージは必要最低限のコンポーネントしかインストールされていないので、このままだといろんなものが足りません。

何がインストールされているかは Dockerfile を見ると書いてあります。

イメージ間の依存関係としては Windows Server Core => IIS => ASP.NET となっています。当然ながら Server Core なのでデスクトップエクスペリエンスがインストールされていません。

Server Core なので、これまで必要なパッケージのインストールで便利に使ってきた Web PI が残念ながら使えません。Server Core を考慮した作りになっていないようです。

Occasionally, though, you might find yourself in a situation where you still prefer to avoid using the WebPI installation option. For example, one such scenario is when installing ARR on the Server Core edition of Windows, where WebPI cannot be used.

Installing ARR manually without WebPI – Erez's IIS Blog

仕方がないので MSI をダウンロードして手動でインストールしてやります。

Dockerfile 内で MSI をダウンロードして、サイレントインストールを行うようにします。IIS モジュールはどれが最新なのかわかりにくいのが欠点ですね。

FROM microsoft/aspnet:4.6.2

ADD https://download.microsoft.com/download/C/9/E/C9E8180D-4E51-40A6-A9BF-776990D8BCA9/rewrite_amd64.msi /install/rewrite_amd64.msi

RUN msiexec.exe /i c:\install\rewrite_amd64.msi /passive & \
    rd /s /q c:\install

この Dockerfile を使ってビルドすると、URL Rewrite Module がインストールされたイメージが完成します。ADD でダウンロード URL を指定できるのは、Invoke-WebRequest の必要がないので便利です。

f:id:shiba-yan:20161125223427p:plain

大体の場合では URL Rewrite があれば足りる気がします。

リバースプロキシを使いたい場合などで、ARR 3 が必要な場合は URL Rewrite Module のインストール後に処理を追加します。Dockerfile は変わらずシンプルなままです。

FROM microsoft/aspnet:4.6.2

ADD https://download.microsoft.com/download/C/9/E/C9E8180D-4E51-40A6-A9BF-776990D8BCA9/rewrite_amd64.msi /install/rewrite_amd64.msi
ADD https://download.microsoft.com/download/E/5/4/E5460BC3-3D6E-42BB-84AF-91EFF1EB14D4/requestRouter_amd64.msi /install/requestRouter_amd64.msi

RUN msiexec.exe /i c:\install\rewrite_amd64.msi /passive & \
    msiexec.exe /i c:\install\requestRouter_amd64.msi /passive & \
    rd /s /q c:\install

RUN %windir%\system32\inetsrv\appcmd.exe set config -section:system.webServer/proxy /enabled:"True" /commit:apphost

原因はよくわかりませんが、MSI でインストールしただけでは proxy が有効にならなかったので appcmd を使って有効化するようにしました。

作成したイメージを起動して、アタッチすると ARR がインストールされているのが確認できます。

f:id:shiba-yan:20161125223259p:plain

最後に作成したイメージを使ってリバースプロキシを立ち上げてみます。動作確認なので、リバースプロキシルールだけを定義した Web.config と Dockerfile を用意しました。

FROM arr3

COPY Web.config /inetpub/wwwroot
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
  <system.webServer>
    <rewrite>
      <rules>
        <rule name="ReverseProxyInboundRule1" stopProcessing="true">
          <match url="(.*)" />
          <conditions>
            <add input="{CACHE_URL}" pattern="^(https?)://" />
          </conditions>
          <action type="Rewrite" url="{C:1}://buchizo.wordpress.com/{R:1}" />
        </rule>
      </rules>
    </rewrite>
  </system.webServer>
</configuration>

これまでと同じように docker build を使ってイメージを作成し、コンテナを起動します。

f:id:shiba-yan:20161125233310p:plain

docker inspect で取得した IP アドレスをブラウザで開いてみると、ちゃんとリバースプロキシとして動作していることが確認できます。イメージを作ってしまえば、後はとても簡単でした。

f:id:shiba-yan:20161125233340p:plain

基本となる ARR 3 がインストールされたイメージは共通で使えるので、同じように必要なコンポーネントをインストールしたイメージを作成しておくと楽ができそうです。

環境を丸ごとイメージとしてポータブルな形で保持できるのは、想像以上に快適な世界でした。

Xbox One S を買ったので 4K HDR の設定と UHD-BD の再生を試してみた

f:id:shiba-yan:20161124205110j:plain

今のところゲームをする予定はないのですが、4K と UHD-BD に対応しているという点に惹かれたので Xbox One S を買いました。一応 UWP の開発にも使えるのでアンロックはします。

折角 4K HDR に対応したテレビを持っていても、コンテンツがストリーミングの 4K しかない状態でしたが、これでやっと UHD-BD で 4K HDR を楽しめそうです。

ということで、シアトルの Best Buy で The Martian の UHD-BD を買っておきました。

日本語字幕は入っていませんが、日本で買う場合の半額ぐらいで買えました。

Xbox One S とテレビを接続して電源を入れたら、4K テレビだと認識されて解像度は切り替わりましたが、HDR は有効にならなかったので少し悩みましたが、テレビの設定が必要だったようです。

HDMI入力端子に接続した機器の映像を高精彩なHDMI 4Kフォーマット*で表示するには、[外部入力設定]の[HDMI信号フォーマット]を設定します。
HDR機能に対応しているかどうかは、お使いのテレビによって異なります。

http://helpguide.sony.net/tv/cjp1/v1/ja/contents/TP0000909440.html

接続した HDMI の設定を変更することで、Xbox One S から 4K HDR フル対応と認識されました。

f:id:shiba-yan:20161124230101p:plain

スクリーンショットの撮り方が分からなかったので、Windows 10 でストリーミングしました。

UHD-BD のディスクを入れると BD プレイヤーアプリのダウンロードが行われて、そこから再生が始まりました。少しドライブの回転音がうるさい気がしましたが、再生中は静かになりました。

f:id:shiba-yan:20161124215936j:plain

買ってまだ 1 年も経っていないサウンドバーは HDR のパススルーに対応していないということだったので、仕方なく ARC で繋ぐだけという形にしておきました。

途中で Xbox One S からの音声が全く再生されないという謎現象に見舞われましたが、テレビを再起動すると問題なく再生されるようになりました。いい加減に Android TV は安定してほしいです。

シアトルで MADOSMA Q601 を T-Mobile LTE で使ってみた

iPhone 7 Plus に機種変しましたが、docomo 版なので SIM ロックフリーになっていないので MADOSMA Q601 に T-Mobile の SIM を刺して使うことにしました。

T-Mobile の LTE バンドは 2,4,12 らしいですが、メインはバンド 4 ということなのでこれに非対応だと辛いです。AWS バンドは国内端末だと期待できないですが、Q601 は対応しています。

実際に SIM を刺して使ってみましたが、デフォルトで入っている APN だと LTE に繋がらない気がしたので、手動で入力してみました。

パスワードなど必要なく fast.t-mobile.com を入力するだけです。

f:id:shiba-yan:20161114095436p:plain:w450

後はよくわかっていないですが、地域を念のため米国にしておきました。

f:id:shiba-yan:20161114111533p:plain:w450

この二つの設定を行った後、端末を再起動すると LTE で繋がるようになりました。Q601 が海外での W-CDMA に対応していないみたいなので、LTE で繋がらないと 2G になるので死活問題です。

f:id:shiba-yan:20161114111544p:plain:w450

ちなみに MADOSMA Q601 は 5GHz 帯の Wi-Fi テザリングに対応しているので、結構快適に使えます。バッテリーも多いのでテザリングで 1 日中使えます。

SeaTac で速度を試してみたところ、下りで 30Mbps ぐらい出たので結構満足出来ます。下手なホテルの Wi-Fi より速いかもしれないです。

f:id:shiba-yan:20161114095302p:plain:w450

速度は速いですが、T-Mobile の LTE は容量制限があるので注意が必要です。今回は 2 週間近く滞在する予定だったので、LTE で 10GB まで使えるプランを契約しました。

$60 で少し高いですが、docomo の海外プランより圧倒的に安いので払いました。

f:id:shiba-yan:20161114095322p:plain:w450

10GB を使い切ってしまうと LTE での通信が出来なくなるみたいなので、Q601 だと強制的に 2G になります。出来ることなら W-CDMA にも対応してほしかったですね。

Surface Dial を発売日に並んで買ってみた話

偶然にも Surface Dial の発売日にシアトルに滞在していたので、Microsoft Store に開店時間前から並んで買ってきました。公式ブログでは今日から発売と書いてあるのに、何故か入荷してないとか言われましたが、何とか 1 個だけ買うことが出来ました。

$99 に税金がかかって大体 $108 ぐらいになりました。カードの PIN 忘れて通らなかった時は焦りました。

英語ペラペラのぼんぷろ先生曰く、入荷が結構少なかったとか何とか。

f:id:shiba-yan:20161110150224j:plain

気を取り直して、早速 Surface Dial を持って行っていた MacBook Pro 上の Windows 10 とペアリングしてみました。自動的にドライバがインストールされて使えるようになります。

f:id:shiba-yan:20161111040512p:plain:w450

ペアリングが完了すると、設定画面にホイールという項目が増えます。ここで Surface Dial の設定が行えるようになってますが、そこまで項目は多くなかったです。

f:id:shiba-yan:20161111040338p:plain

このメニューは Surface Dial を長押しすると表示されます。アクションが発生した時にはブルブルと震えるようになっていて、分かりやすい感じです。

スクロールだけでもかなり快適な感じでしたので、長い文章読む時などに使いたい感じです。

f:id:shiba-yan:20161111081247p:plain:w450

まだ対応アプリは少ないみたいですが、Surface Dial に対応しているアプリはストアのアイコンが変化してわかるようになっているみたいです。違うっぽいです。

Surface Studio のデモでよく使われている Sketchable は Surface Dial 対応になっていました。

f:id:shiba-yan:20161111050149p:plain:w450

Surface Studio ではないので画面に置いたりできないですが、普通に利き腕の反対側に置いておくとくるくる回して使うのが楽だったので、アプリが増えると楽しくなりそうです。

Surface Dial interactions

ちゃんと API のドキュメントが用意されているので、動画を見ている時にシークバーを動かすアプリとかを作ってみたいですね。マウスやトラックパッドで操作するのは難しすぎるので。

Docker で Windows Containers を使った時にコンテナホストから localhost でコンテナが見えない件

前に Windows Containers を使って IIS を立ち上げた時、コンテナホストから localhost でコンテナで動作しているはずの IIS を確認しようとしても出来なかったのですが、理由が分かったので書きます。

ちなみに Docker と Windows Containers については前のエントリを見てください。

世界の RD ことぶちぞうさんからは「お前の設定が悪い」みたいなことを Twitter で言われましたが、実際のところ内部で使われている WinNAT の制限で見れないだけでした。

あとから追記された感はありますが、ちゃんと IIS の Docker Hub に書いてありました。

With the current release, you can't use http://localhost to browse your site from the container host. This is because of a known behavior in WinNAT, and will be resolved in future. Until that is addressed, you need to use the IP address of the container.

https://hub.docker.com/r/microsoft/iis/

WinNAT については以下の記事にまとまっていました。コンテナ対応のために色々と追加されてますね。

Windows NAT (WinNAT) — Capabilities and limitations | Virtualization Blog

結局のところ、今は localhost を使ってアクセスは出来ないので、代わりにコンテナに割り当てられている IP アドレスを直接指定する必要があるみたいです。実際に Docker を使って試してみました。

まずは Docker を使って IIS を起動します。本来なら localhost:80 がコンテナにフォワーディングされるはずですが、今は対応していないということです。

docker run -d -p 80:80 microsoft/iis

念のためアクセスしておくと、コンテナホストにそのまま繋がっているような感じです。

f:id:shiba-yan:20161031193012p:plain

ここで docker inspect を使ってコンテナの IP アドレスを取得するコマンドを実行します。

docker inspect -f "{{ .NetworkSettings.Networks.nat.IPAddress }}" CONTAINER_ID

実行すると IP アドレスが返ってきます。割り当てられる IP アドレスの範囲は docker network inspect コマンドを叩くことで確認することが出来ます。

f:id:shiba-yan:20161031192917p:plain

取得した IP アドレスを使うと、ちゃんと IIS のいつものページが表示されました。

ちゃんとコンテナホストからアクセスできることが確認できましたが、正直めんどくさいですね。

f:id:shiba-yan:20161031193045p:plain

起動ごとに IP アドレスは新しく振り直されるようなので、そのままだと毎回変わってしまって非常に扱いにくいですが、--ip オプションで IP アドレスを渡すことで一応固定は出来るみたいです。

docker run -d -p 80:80 --ip=172.29.72.198 microsoft/iis

指定できる IP アドレスはサブネット内じゃないとエラーになるので、予め docker network inspect を叩いて、サブネットを確認しておきましょう。

f:id:shiba-yan:20161031200537p:plain

デフォルトで nat というネットワークが作成されているので、このネットワークのサブネットを確認するだけです。どっちにしろめんどくさいので、早く WinNAT が対応されるように祈り続けたいと思います。

Windows Server 2016 の Docker から Hyper-V Containers を利用する

前のエントリでは Windows Containers を使いましたが、Hyper-V Containers も Docker から使えるらしいので実際に試しました。Docker と Windows Containers を試した環境をそのまま使ってます。

検索してみると Cmdlet を使って Hyper-V Containers を管理する方法ばかり出てきますが、ちゃんと Docker を使った管理にも対応していました。

Windows Containers と Hyper-V Containers には互換性があるみたいなので、docker pull で取ってきたイメージを起動する時に引数を追加するだけで、Hyper-V Containers で起動できました。

docker run -d -p 80:80 ––isolation=hyperv microsoft/iis

具体的には --isolation=hyperv を付けるだけです。これだけで切り替え可能です。

実際に前回 docker pull してきた IIS イメージを Hyper-V Containers を使って実行してみました。Windows Containers を使う場合より数秒は起動が遅い気がしますが、仮想マシンを立ち上げるより十分高速です。

f:id:shiba-yan:20161016205614p:plain

タスクマネージャーを見ると Hyper-V 絡みのプロセスが立ち上がっています。ユーザー名には GUID が振られていますが、docker コマンドから確認することは出来ないようでした。

IIS が起動しているのにワーカープロセスが居ないので、Hyper-V で動いていることが分かります。

f:id:shiba-yan:20161016205854p:plain

ブラウザでアクセスすると IIS のデフォルトページが表示されているので、IIS がちゃんと動作していることも確認できました。Hyper-V Containers を使うのはとても簡単ですね。

f:id:shiba-yan:20161016205919p:plain

あまりにも簡単に動作してしまったので、ついでに最近公開された SQL Server 2016 Express の Docker イメージを試しました。とはいえ docker pull して起動するだけです。

パスワードを渡すだけで SQL Server 2016 Express の環境が数秒で整うのはかなり便利です。

f:id:shiba-yan:20161016212508p:plain

当然ながら SSMS で接続して自由に操作できます。Hyper-V Containers は Windows 10 でも使えるらしいので、Hyper-V に対応したマシンなら環境構築が楽になりそうですね。

手持ちの MacBook Pro が Hyper-V に対応していないので、試せていないのが残念ですが。

Windows Server 2016 の Windows Containers と Docker を使って IIS と ASP.NET を動かしてみた

Windows Server 2016 が MSDN からダウンロード出来るようになっていたので、Service Fabric Cluster 用に買った Intel NUC にインストールしてみました。

f:id:shiba-yan:20161014002113p:plain

Hyper-V 上に入れた 2016 で Windows Containers を試したとき、1 日経ってもコンテナが起動しなかったのでホスト OS に Windows Container をインストールして再度試しました。

MSDN のドキュメントも更新されているようなので、Docker を含んだセットアップは手順通り行いました。

ドキュメントにある .NET Core のサンプルはあっさり動作したので、前に Hyper-V 上だと実行に失敗した microsoft/iis イメージを実行してみます。

既に Windows Container と IIS を使って ASP.NET を動作させる方法が色んなところで紹介されてます。

ASP.NET アプリケーションを用意するのは正直面倒だったので、とりあえず IIS のデフォルトページが表示されるところまでやります。

イメージをそのまま pull して、実行するだけという簡単なコマンドです。

docker pull microsoft/iis

docker run -d -p 80:80 microsoft/iis

pull には物凄く時間がかかりますが、一度イメージを作成してしまえば起動は高速です。docker run を実行してから数秒でコンテナが起動しました。

docker ps で実行中のコンテナを確認できます。ポートの設定も同時に見れるので便利です。

f:id:shiba-yan:20161014003103p:plain

これでコンテナと同時に IIS も起動しているので、ブラウザで見るといつものページが表示されます。

ここまで時間は 30 分ぐらいかかりましたが、9 割がイメージのダウンロードと作成でした。

f:id:shiba-yan:20161014002753p:plain

理由はよくわかりませんでしたが、コンテナホストから localhost は見れませんでした。別のマシンからは表示されたので、実際にはあまり問題にならない気はします。

実行中のコンテナには docker exec を使えば入ることが出来ます。コンテナの ID が必要なので、予め docker ps を実行してコピーしておきます。

docker exec -i -t CONTAINER_ID cmd

powershell を指定してもいいのですが、背景色が狂ってしまって見にくかったのでとりあえず cmd で行きます。これを実行すると、コンテナに入ることが出来ます。

f:id:shiba-yan:20161014004026p:plain

コンテナホストは日本語 OS ですが、コンテナの中は英語になっていることが分かります。IIS がインストールされたコンテナなので inetpub がありますが、コンテナホストには存在していません。抜け出すには exit と入力するだけです。

機嫌よくなってきたので ASP.NET も簡単なアプリを用意して動かしてみることにしました。こっちも先人の知恵を頼りに Dockerfile を用意してイメージを作成します。

SHELL で powershell を使うようにすると、コマンドレットがそのまま使えるので便利ですね。ASP.NET の実行に必要な機能をインストールしておきます。

FROM microsoft/iis

SHELL ["powershell"]

RUN Install-WindowsFeature NET-Framework-45-ASPNET ; \
    Install-WindowsFeature Web-Asp-Net45

COPY . C:\\inetpub\\wwwroot

CMD ["ping", "-t", "localhost"]

何もしないとコンテナがすぐ終わってしまうので、終わらないような処理を最後に書いておきます。これは他にもっと良い手があるのではないかと思います。

Dockerfile をビルドした ASP.NET アプリケーションと同じディレクトリに置いて、docker build を実行してイメージを作成します。

f:id:shiba-yan:20161014011401p:plain

これも 2 回目以降はキャッシュが使われるので非常に高速です。

後はこれまで通り docker run に作成したイメージ ID を渡せば、そのイメージが起動します。

f:id:shiba-yan:20161014011912p:plain

ブラウザでアクセスすると、ASP.NET アプリケーションが実行されているのを確認できます。マシン名は Windows Containers によって適当に付けられているみたいです。

普通の Windows Server と IIS が動いているので、Dockerfile に必要な IIS 拡張をインストールする処理を書けば、URL Rewrite や ARR も問題なく使えると思います。Docker の理解が深まりました。

Outlook.com Premium を契約して独自ドメインのメールアドレスを作成してみた

いつの間にか Outlook.com Premium が Pilot から Preview になったみたいで、気が付いたら自分の Outlook.com のアカウントで使えるようになっていました。

いい加減に shibayan.jp なメールアドレスを作りたかったので、実際に Outlook.com Premium に登録をして独自ドメインの設定を行ってみました。

f:id:shiba-yan:20161008161709p:plain

https://premium.outlook.com/

世の中には Office 365 を一人で使う手遅れな人もいるみたいですが、僕みたいな一般人は Outlook.com Premium と Office 365 Solo で十分要件を満たせます。

Sign in すると最初にドメインの候補が表示されます。Microsoft アカウントのユーザー名が日本語なので盛大に文字化けしてましたが、取得済みのドメインを使うので「use my own domain」を選択します。

f:id:shiba-yan:20161008161942p:plain

事前の情報だと GoDaddy でドメインを取得する機能が付いているみたいです。

ドメインを入力する画面になるので、使いたいドメインを入れました。当然ながら shibayan.jp です。

f:id:shiba-yan:20161008161950p:plain

ボタンを押して進めていくと MX レコードの追加を求められました。ちゃんと設定せずに次に進もうとすると検証エラーになるみたいです。受信できなくなるので当然ですね。

f:id:shiba-yan:20161008161959p:plain

shibayan.jp は Azure DNS で管理しているので、Azure Portal から MX レコードをサクッと追加しておきました。昔に比べると使いやすくなった気がします。

f:id:shiba-yan:20161008162006p:plain

DNS に追加した MX レコードの検証に成功すると次の画面に進めます。

f:id:shiba-yan:20161008162329p:plain

次は SPF レコードと Outlook.com が独自に必要としている CNAME レコードを追加します。MX レコードと同じように Azure DNS を使ってポチポチと設定しました。

ここまでの作業で DNS 周りは完了したらしいので、最後に最初に作成するメールアドレスを決めます。ありがちですが、思いつかなかったので適当に決めておきました。

f:id:shiba-yan:20161008162344p:plain

やけにテンションの高いメッセージと共に確認ダイアログが表示されます。

f:id:shiba-yan:20161008162353p:plain

メールアドレスを決定すると、最後に Outlook.com Premium サブスクリプションの支払いが待ってます。トップページにあったように最初だけ年間 19.95 ドルで使えるようになっています。

f:id:shiba-yan:20161008162402p:plain

個人的にはどこかで値下げされたりするのではと思ってますが、大した金額ではないので払います。サブスクリプションのキャンセルは Microsoft アカウントの画面から行えるようだったので安心です。

扱いとしては Ad-free Outlook.com となっているみたいです。

f:id:shiba-yan:20161008163901p:plain

支払い後に Outlook.com Premium に戻ると、管理画面が表示されるようになります。ここからユーザーを招待したり、エイリアスの追加などが出来るようになってます。表示は少し遅いです。

f:id:shiba-yan:20161008164054p:plain

その後 Outlook.com の設定から差出人アドレスを変更すると、追加したドメインのメールアドレスとして送信出来るようになります。受信も問題なく使えるようになっているはずです。

f:id:shiba-yan:20161008163954p:plain

Microsoft アカウントのエイリアスとしても設定されていたので、プライマリに切り替えると追加したメールアドレスでログインできるようになる気がしますが、まだ怖くて試していないです。

そのあたりの検証は Office 365 MVP *1 な @kazuakix さんがしてくれます。

*1:社畜的な意味でもオフィスに 24/365

HockeyApp で配布したアプリケーションを Windows 10 Mobile にインストールする方法

最近は趣味で Windows 10 Mobile 向けにはてなブログのオレオレアプリを作っていたりもしますが、人柱になってくれる人が 2 人ほどいたので HockeyApp を使ってアプリケーションの配布を試しました。

Windows 10 では PowerShell スクリプトを叩くだけですが、よく考えたら Windows 10 Mobile にインストールする方法を知らなかったので、Phone ブログを書いてる人に聞いてみました。

仕方ないので自分で調べて試しました。どうやら WinAppDeployCmd というツールを使うみたいです。

Install Universal Windows Apps with the WinAppDeployCmd tool

WinAppDeployCmd を使った場合、証明書のインストールをしてくれないらしいので、インストールするためにはサイドロードモードにして自分で証明書を入れるか、開発者モードに切り替える必要があるみたいです。

f:id:shiba-yan:20160928010143p:plain:w450

めんどくさいのと開発用端末なので開発者モードにしてあります。

devices コマンドを実行すると、接続されている Windows 10 Mobile デバイスが見えるみたいなので、最初に実行して認識されているかと IP アドレスを確認します。

f:id:shiba-yan:20160928005654p:plain

USB 接続の場合はループバックアドレスになるみたいです。多分ですけど。

IP アドレスが分かれば、install コマンドを使って、HockeyApp で配布したアプリに含まれている appxbundle のインストールを行います。-file で appxbundle のフルパスを渡すだけです。

WinAppDeployCmd install -file "UWPApp.appxbundle" -ip 127.0.0.1

MSDN のサンプルでは appx になってましたが、appxbundle を指定しても問題なくインストールが出来ました。少し時間はかかりましたが、管理者権限とかいらないので結構簡単です。

f:id:shiba-yan:20160928005500p:plain

コマンド上ではインストールが完了したので Windows 10 Mobile 側を確認すると、ちゃんとアプリがインストールされていたので実行も問題なく出来ました。UWP 版のオレオレはてなブログアプリです。

f:id:shiba-yan:20160928011053p:plain:w450

閲覧系の機能は割と付けたつもりですが、まだまだ不十分かつ頻繁にクラッシュするので HockeyApp での配布を整えてのんびりやっていきたいと思っています。*1

かずあきさんのように人柱希望の方が居れば Twitter とかでメールアドレスを教えてもらえれば招待メールを投げることが出来ます。ほぼ居ないと思いますけど…。

*1:公式で UWP 版が出るとは思えないので。

UWP でアプリを作ってから 1 週間でやったことをまとめた

色々と苦労ばかりしてますが、何だかんだで UWP で作ったアプリの更新を頻繁に行っています。

情報が非常に少ないという点が苦労の原因なので、文句ばかり言わず調べた部分に関してはまとめます。実際にアプリに組み込んで試したことだけ書いてますが、間違っている可能性は高いです。

HockeyApp を有効化

Visual Studio から HockeyApp のクラッシュ分析を有効化すると、簡単にアカウント作ったりアプリの登録が出来ますが、AppId の設定は自分で行う必要があるみたいでした。

using Microsoft.HockeyApp;

public sealed partial class App
{
    public App()
    {
        HockeyClient.Current.Configure("APPID");

        InitializeComponent();

        Suspending += OnSuspending;
    }
}

公式のサンプルが InitializeComponent の前に呼び出していたので、同じようにしました。

f:id:shiba-yan:20160817214734p:plain

正しく設定が行えていると、HockeyApp のダッシュボードに情報が表示され始めます。最低でも Version が表示されていない場合は設定に失敗しているので、AppId を確認する必要があります。

課金処理を StoreContext API に変更

昔から存在している CurrentApp を使った課金処理は、Windows 10 Anniversary Update から新しく追加された StoreContext に置き換えられるようです。

https://msdn.microsoft.com/en-us/windows/uwp/monetize/in-app-purchases-and-trials

API が大きく変わっているのと、サンプルコードがいまいちでわかりにくかったので、実際に自分が書いたコードを参考までに載せておきます。正しいのかはわからないので自己責任で。

アドオンの購入は RequestPurchaseAsync メソッドに StoreId を渡すだけなので、これまでとあまり違いはないです。ProductId ではなく StoreId なので注意が必要です。

var context = StoreContext.GetDefault();

var result = await context.RequestPurchaseAsync(StoreId);

switch (result.Status)
{
    case StorePurchaseStatus.AlreadyPurchased:
        // 既に購入済み
        break;

    case StorePurchaseStatus.Succeeded:
        // 購入完了
        break;

    default:
        // エラー扱いにする
        return;
}

購入後は Status の値によってダイアログを出したりすることになると思います。

そして購入済みライセンスのチェックですが、新しい API では SKU という概念が追加されたみたいなので、これまでより少しめんどくさくなりました。

For a SKU, the Store ID has the format /xxxx, where xxxx is a 4-character alpha-numeric string that identifies a SKU for the product. For example, 9NBLGGH4R315/000N. This ID is returned by the StoreId property of a StoreSku object, and it is sometimes called the SKU Store ID.

In-app purchases and trials

情報自体は GetAppLicenseAsync メソッドで取得できますが、AddOnLicenses のキーは StoreSku から取得できる StoreId なので、単純にインデクサーで引くとエラーになります。

なので、LINQ を使って StartsWith で比較するか、StoreSku を先に調べて引っ張ってくるかの方法が必要になりそうです。挙動が不明だったので、私は後者を選びました。

// Durable なアドオンを取得する
var list = await context.GetAssociatedStoreProductsAsync(new[] { "Durable" });

// Skus は必ず 1 つ存在する
var skuStoreId = list.Products[StoreId].Skus[0].StoreId;

// ライセンス情報を取得
var license = await context.GetAppLicenseAsync();

// AddOnLicenses は KeyNotFoundException を投げる
if (license.AddOnLicenses.ContainsKey(skuStoreId) && license.AddOnLicenses[skuStoreId].IsActive)
{
    // アドオンを購入済み
}

ひとまず、これで StoreContext を使った IAP が動作するようになりました。

AdMediator が削除されたので変更

これまで Microsoft Store Engagement and Monetization SDK としてリリースされていた拡張が、先日新しく Microsoft Store Services SDK に変わりましたが、このタイミングで AdMediator が削除されました。

今後はサーバーサイドに切り替わっていくみたいですが、SDK がリリースされてもサーバー側がリリースされていないので、現状は Microsoft Advertising のみ利用可能です。

  • AdMediator is no longer being maintained as we shift to server side mediation.
    • For Windows 10 apps, an MSDN topic is coming out this week with prescriptive steps to refactor.
Microsoft Store Services SDK extension

英語版のドキュメントは既に Store Services SDK 向けに更新されています。

https://msdn.microsoft.com/windows/uwp/monetize/microsoft-store-services-sdk

おそらく近日中にサーバー側がリリースされるんでしょう、足並み揃えろという感は拭えませんが。

Feedback Hub の起動コードを変更

Insider 向け機能として提供されている Feedback Hub を使ったフィードバック機能ですが、Store Services SDK の更新に従って微妙に API が更新されています。

まず StoreServicesFeedbackLauncher.IsSupported メソッドを使って、利用可能かチェックします。

if (StoreServicesFeedbackLauncher.IsSupported())
{
    feedbackButton.Visibility = Visibility.Visible;
}

何故か IsSupported はメソッドに変更されています。このあたりイマイチですね。

実際に Feedback Hub を開くためには StoreServicesFeedbackLauncher.GetDefault メソッドでインスタンスを取得した後、LaunchAsync メソッドを呼び出します。

private async void FeedbackButton_Click(object sender, RoutedEventArgs e)
{
    await StoreServicesFeedbackLauncher.GetDefault().LaunchAsync();
}

この修正はシンプルなのですぐ対応できます。

実際にフィードバックが送られるとどうなるのかはよくわかっていないですが、めんどくさい部分を Windows Store が受け持ってくれるのは便利ですね。