こちらのエントリーはSilverlight Advent Calendar 2011の23日分の参加エントリーです。
さて、僭越ながら3日連続でエントリーを予定している2日目で、今回のテーマは「ブラウザー外実行」に関する内容です。
ということでまずはブラウザー外実行の概要から。
ブラウザー外実行概要
一般的にSilverlightのマネージAPIで開発されたアプリケーションはご存じのとおり、Silverlightランタイム上で動作する、拡張子がxapとなっているパッケージファイルに内包されたアプリケーションです。
このxapファイルは通常HTMLやaspxなどのWebページ上にobjectタグとparamタグを使って埋め込みます。
そして、SilverlightランタイムがインストールされたクライアントマシンからWebブラウザーで、埋め込まれたページにアクセスすることでパッケージが読み込まれてランタイム上で実行されます。
通常は上記のようなプロセスでアプリケーションが実行されているワケです。
そこで、ブラウザーが受け持っている、Silverlightアプリの実行に必要なさまざまな機能群を切り出して、これを独立した実行ファイルにしました。
その実行ファイルとランタイムの組み合わせでSilverlightアプリケーションを実行を可能にした機能が本日の本題「ブラウザー外実行」になります。
実行にブラウザーを利用しないので、アプリケーションが必要としないのであれば、ネットワーク接続がないクライアント環境でも手軽にSilverlightアプリケーションを実行できる機能になります。
ただし、インストールの際にはブラウザーを使ってアプリケーションを読み出す必要がありますので、ブラウザーやネットワーク接続そのものが必要ないワケではありません。
しかし、実装そのものは大きな変更をしなくても、パッケージに含まれるマニフェストファイルの変更だけでブラウザー外実行にすることが可能なため、お手軽にクライアントアプリケーション化することができるところが特徴です。
ブラウザー外実行の設定
ブラウザー外実行は先ほどもお話した通り、xapファイルに含まれるマニフェストファイルを変更するだけで利用可能になります。 しかし、マニフェストファイルを直接メンテナンスしなくても、主要な設定項目はVisual Studio 2010のプロパティからGUI操作で簡単に設定することが可能ですので、こちらで設定することをおすすめします。
Visual Studio 2010のソリューションエクスプローラーから「Silverlightプロジェクトを右クリック→プロパティ」、もしくは「Silverlightプロジェクト内の”Properties”をダブルクリック」を行います。
Silverlightプロジェクトのプロパティが表示されますので、Silverlightタブにある「アプリケーションのブラウザー外実行を有効にする」をチェックするとアプリケーションがブラウザー外実行することが可能になります。
チェックをオンにするとすぐ下にある「ブラウザー外実行の設定」ボタンをクリックするとブラウザー外実行の主要な設定項目が格納されています。
中でも「インストールメニューの表示」にチェックが入っていないとコードによるインストール手段を用意していない限りブラウザー外実行を行うことができないので注意して下さい。
ブラウザー外実行のアプリのインストール
ブラウザー外実行のアプリケーションのインストールは大きく2通りあります。
1つは「Silverlightの構成メニュー」からインストールする方法、もう1つは「コードによるインストール方法」になります。
「Silverlightの構成メニューからインストールする」の場合は、先ほどの「インストールメニューの表示」にチェックしておきます。
あとは以下のように実行中のSilverlightアプリケーション対して右クリックすることでインストールメニューが表示されます。
この「~をインストールします。」のメニューをクリックすることで次のようなダイアログが表示されます。
こちらのダイアログはインストールしたアプリケーションへのショートカットの配置先の指定となります。
スタートメニューもしくはデスクトップ上にショートカットが配置されるので、そこからアプリケーションを起動することが可能です。
ただし、上記のチェックがオンじゃなかったり、アプリケーション内で右クリックのイベントをハンドリングしている場合は構成メニューを表示させることができませんので、この方法ではインストールできません。
もう1つインストール方法は「コードからインストール」する方法になります。
コードからインストールする場合はApplicationクラスのInstallメソッドを実行するのみです。
ですので、Application.Install()でインストールが可能です。
あとはインストールしたショートカットをクリックすることがアプリケーションを起動できます。
ブラウザー外実行のアプリのアンインストール
ブラウザー外実行のアプリケーションのアンインストールも2通りあり、一つは「構成メニューからアンインストールする方法」、もう1つは「コントロールパネルからアンインストールする方法」です。
「構成メニューからのアンインストールする方法」はインストール時と同様にブラウザー外実行で実行されているSilverlightアプリケーション上で右クリックすることでアンインストールが可能です。
ただし、インストール時と同様、アプリケーションが右クリックをハンドリングしているとこれらは表示されません。
その場合はコントロールパネルからのアンインストールを行うこととなります。
ブラウザー外実行にはまだまだ説明したいことはあるのですが、本題とは外れますのでこれくらいにしたいと思います。
ブラウザー外実行のUpdate
前段階の説明が長くてすみません(^^;
Silverlightアプリケーションは通常のWebアプリケーションと同様、サーバー上にあるアプリケーションを置き換えてしまえば新しいモジュールの配布を行うことが可能ですが、ブラウザー外実行となるとモジュールそのものがクライアント側に配置されるため、アプリケーションを自動的に更新することができません。
しかし、Silverlightにはそのような時のためにアプリケーションの更新を検知する仕組みが用意されています。
Application.CheckAndDownloadUpdateAsync()
上記メソッドはApplicationクラスのメンバーですので、UIから取得する場合はApplication.Currentプロパティから実行可能です。
上記メソッドはブラウザー外実行でインストールされているアプリケーションのバージョンをチェック時、自身のモジュールのバージョンアップ版を見つけたらそのxapファイルをダウンロードして、更新します。
そのため、これらのチェックにはネットワーク通信が発生しますので、必然的にネットワーク接続がされている必要があります。
そして、ご存じのとおりSilverlightのすべての通信は非同期で実現されており、こちらも例外ではありません。そのため、それらの更新の可否を取得するために下記のイベントのイベントハンドラを指定する必要があります。
Application.CheckAndDownloadUpdateCompleted
これらをまとめると以下のようなコードになります。
(2011-12-23 22:30 コードにバグがあったので修正しました)
private void UserControl_Loaded(object sender, RoutedEventArgs e) { var app = Application.Current; //判定および更新結果の取得完了時イベント app.CheckAndDownloadUpdateCompleted += app_CheckAndDownloadUpdateCompleted; //判定・更新 app.CheckAndDownloadUpdateAsync(); }
パッケージの更新可否の確認
そして、このイベントハンドラのイベント引数を通じて、更新の可否を取得する必要があります。
更新の可否はイベント引数からUpdateAvailableというbool型のプロパティを通じて取得できます。
こちらがtrueの場合、アップデートのあったパッケージのダウンロードが成功したことを表しています。
こちらがfalseの場合はUpdateが存在しない、もしくはアップデートに失敗したということになります。
では、このアップデートの失敗はどのような場合に発生するかというと、以下のようになります。
- Silverlightランタイムのバージョンが異なる
- 配置されているモジュールが完全信頼モードで動作するアプリケーションなどの管理者権限を必要とするもの
上記のようなケースだと、同じくイベント引数のErrorというException型のプロパティにエラーの内容が格納されます。
Silverlightランタイムのバージョンが異なる場合はPlatformNotSupportedExceptionのインスタンスが格納されます。
既に配置されている完全信頼モードのパッケージと同じ証明書がつけられている場合は、上記のように問題なく更新できますが、証明書がなかったり、異なる証明書がついている場合は承認を必要としますのでSecurityExceptionのインスタンスが格納されます。
このあたりをまとめると以下のようなコードになります。
void app_CheckAndDownloadUpdateCompleted(object sender, CheckAndDownloadUpdateCompletedEventArgs e) { if(e.UpdateAvailable) { MessageBox.Show("アップデート完了。 アプリケーションを再起動してください。"); return; } else if(e.Error != null && e.Error is PlatformNotSupportedException) { MessageBox.Show("アップデートは存在していますが、Silverlightランタイムのバージョンが異なります。"); return; } else if(e.Error != null && e.Error is SecurityException) { MessageBox.Show("完全信頼モードのアプリケーションで、認証が必要です"); return; } MessageBox.Show("アップデートは存在しません。"); }
というワケで実行するとこんな感じで表示されるとおもいます。
アップデートを検知するために固定のWebサイトが必要だったので、今回のサンプルプログラムはWebプロジェクト入りになります。
というワケで23日のエントリーは以上になります。
今日の内容はMicrosoft Innovation Academyの「Silverlightプログラミング入門 前編」で実施しているセミナーの内容からのピックアップになりますので、よろしければ本編のセミナーもどうぞ(^^;
ツイート
こんにちは。去年、森さんのセミナーに参加させていただいた者です。
その節は大変お世話になりました。
非常に勉強になりまして、おかげさまで無事開発を終えることが出来ました!
そしてリリースも完了し、しばらくした今・・・実は問題が発生いたしまして・・・。
そしてここにたどり着きました。(^^;)
実は Visual Studio で作成したテスト用の証明書を使用して署名を行っていたため(有効期限が1年であったため)期限切れとなり発行出来なくなってしまいました。
新しい(異なる)証明書を使用して発行するとユーザのPCに既にインストール済みのアプリケーションが自動更新されなくなってしまうので非常に困っています。
そこで現在使用中の証明書の有効期限だけを延ばせないかと調べたところ RenewCert というものがあると知り、これを使って証明書の期限を延ばしてみたのですが、これで生成した証明書を使用して発行してもインストール済みのアプリケーションが自動更新されないのです。
<参考にしたサイト>
「インストールの署名に使用した証明書の期限が切れた後、Visual Studio 2005 ClickOnce アプリケーションを更新するときにエラー メッセージが表示される」
http://support.microsoft.com/kb/925521/ja
もう一週間以上、この件で悩んでいるため図々しいとは思いましたが、もし何か解決方法をご存知でしたら教えていただけないかと思いまして・・・。
ちなみに開発環境は Visual Studio 2010、Silverlight 4 です。
そのため上記 HP の条件には当てはまらないのでしょうか・・・?
よろしくお願いいたします。
先日はご受講いただきましてありがとうございました。
また、いろんな場所でお話させていただいておりますので、
機会がありましたらお気軽にお声掛けください。
さて、ご質問の件ですが、残念ながら私も証明書について、
それほど詳しい訳ではないので、お役に立てそうな情報は持っておりません。
せっかくご質問いただきましたが、このRenewCertの存在もこちらのコメントで初めて知ったので、
現在でもこの方法が有効かどうかまでは存じ上げておりません。
お役に立てず大変申し訳ありません。
お忙しい中、早々のご回答ありがとうございます。
こちらこそ突然このような質問をして申し訳ありません。
またセミナー等でお世話になることがあるかもしれませんので、その際はどうぞよろしくお願いいたします。