第4回 ClickOnceテクノロジを最大限に生かす開発:連載 ClickOnceの真実(4/4 ページ)
ClickOnceの配布を制御してパフォーマンスを向上させるには? アップデートをプログラムから実行するには? ClickOnceのカスタマイズを解説。
任意のタイミングで実行するアップデート(手動による更新処理)
ClickOnceでは、アプリケーションの起動時といったタイミングで実行される自動的なアップデート機能のみならず、任意のタイミングで実行できる手動によるアップデートも可能だ。
実はこれを実装するためのコードも、先ほど示したオンデマンド配置のコードと大した差はない。違うのは、オンデマンド配置ではIsFileGroupDownloadedメソッドを使って「すでにダウンロードされたかどうか」を判定したが、アップデートではCheckForUpdateメソッドによって「アップデートの必要があるかどうか」を判定する(アップデートが必要な場合はTrueを返し、そうでなければFalseを返す)点だ。
また、オンデマンド配置ではDownloadFileGroupメソッドを使って実際にファイル群のダウンロードを行ったが、アップデートではUpdateメソッドによりアップデート処理を行う。
このCheckForUpdateメソッドとUpdateメソッドはどちらも同期処理として実行される。ApplicationDeploymentクラスには非同期処理のためのCheckForUpdateAsyncメソッドやUpdateAsyncメソッドが用意されているが、DownloadFileGroupメソッドと同様にこれらのメソッドはユーザー・インターフェイスを持たない。そこで、これに関してもダウンロード・ダイアログを表示する機能を本稿のClickOnceAppDeploymentクラスでは提供している。
ClickOnceAppDeploymentクラスのCheckForUpdateメソッドは、[アプリケーション コンポーネントの確認中]というシンプルなダイアログを表示する。また、Updateメソッドはダウンロードの進ちょくを示すダウンロード・ダイアログを表示する。
さらに、ClickOnceAppDeploymentクラスのUpdateメソッドについては、bool値をパラメータに取るオーバーロードを追加している*3。このバージョンのメソッドのパラメータにTrueを渡すと、必須更新と見なして何も表示せずにアップデートを強制実行する。逆にFalseを指定すると、アップデートを行うかどうかをユーザーに質問する次のようなダイアログを表示する。
*3 パラメータなしのバージョンのUpdateメソッドは、単にダウンロード・ダイアログを表示しながらアップデートを行うだけである。
以下では、このようなダイアログを表示するClickOnceAppDeploymentクラスを使って、独自のアップデート処理を実現するコード例を示そう。なおこのコードは、冒頭のサンプル・アプリケーションで[アップデート]ボタンがクリックされたときのイベント・ハンドラである。
private void buttonUpdate_Click(object sender, EventArgs e)
{
MyUpdate();
}
private void MyUpdate()
{
if (ClickOnceAppDeployment.IsNetworkDeployed)
{
ClickOnceAppDeployment deploy =
ClickOnceAppDeployment.CurrentDeployment;
if (deploy.CheckForUpdate())
{
// ユーザーに更新の確認を表示して更新を行います。
if (deploy.Update(deploy.IsUpdateRequired))
{
DialogResult dret = MessageBox.Show(
"アプリケーションは更新されました。\n" +
"アプリケーションを新しいバージョンに切り替えるには" +
"現在実行中のアプリケーションを再起動する必要が" +
"あります。\n\n" +
"アプリケーションを再起動しますか?\n" +
"(※OSは再起動しません。)",
"今すぐ再起動しますか?",
MessageBoxButtons.YesNo, MessageBoxIcon.Question);
if (dret == DialogResult.Yes)
{
Application.Restart();
}
}
else
{
switch (deploy.ProcessingMode)
{
case ProcessingMode.Canceled:
MessageBox.Show("処理をキャンセルしました。");
break;
case ProcessingMode.Skipped:
MessageBox.Show("処理をスキップしました。");
break;
case ProcessingMode.Error:
// エラー・メッセージはUpdateメソッド内で表示済み。
break;
}
}
}
else
{
switch (deploy.ProcessingMode)
{
case ProcessingMode.Canceled:
MessageBox.Show("処理をキャンセルしました。");
break;
case ProcessingMode.Error:
// エラー・メッセージは
// CheckForUpdateメソッド内で表示済み。
break;
case ProcessingMode.Completed:
MessageBox.Show("更新の必要はありません。");
break;
}
}
}
else
{
MessageBox.Show(
"ClickOnceで配置されたアプリケーションではありません。");
}
}
}
上記のコードでは、まず、[アップデート]ボタンがクリックされたときのイベント・ハンドラからMyUpdateメソッドが呼び出されている。MyUpdateメソッドの内部では、現在実行中のアプリケーションがClickOnceで配布されたものかを確認して、ClickOnceAppDeploymentオブジェクトを生成し、そのUpdateメソッドを呼び出している。
このUpdateメソッドの呼び出しでは、そのパラメータにIsUpdateRequiredプロパティを指定しているが、これは「必須更新か(=強制的にアップデートする必要があるか)、そうでないか(=ユーザーに確認してアップデートするか)をbool値で取得する」ためのものだ*4。つまりIsUpdateRequiredプロパティがFalseの場合、Updateメソッドの呼び出しの中で、先ほど示した「ユーザーにアップデートを行うかどうかを質問するダイアログ」が表示されるわけである。
*4 必須更新の設定方法については「第3回 Visual Studio 2005でClickOnceを極めよう― ClickOnceの更新オプションの設定」を参照してほしい。
正常にアップデートが完了するとUpdateメソッドはTrueを返す(もちろんアップデートされていない場合はFalseを返す)。実際に戻り値がTrueだった場合は次のようなダイアログをユーザーに提示する。
ユーザーにアプリケーションの再起動の許可を求めるダイアログ
アプリケーションを再起動しなければ、実行中のアプリケーションは更新されない。このダイアログで[はい]がクリックされると、実際にアプリケーションを再起動して新しいバージョンのものが実行される。[いいえ]がクリックされた場合は何もしない。
このダイアログで[はい]が選択されたら、Applicationクラス(System.Windows.Forms名前空間)の静的メソッドRestartを呼び出す(このメソッドは.NET Framework 2.0で追加されたもので、基本的にはClickOnceでアップデートした後で再起動するために用意されている)。これによりアプリケーションが再起動する。
今回は、ClickOnceの機能を拡張して、配布や更新の動作をカスタマイズする方法を説明した。次回は、ClickOnceアプリを実行するために必要な前提条件をあらかじめインストールする機能である必須コンポーネント(=ブートストラッパ)を拡張する方法を説明する予定だ。お楽しみに。
Copyright© Digital Advantage Corp. All Rights Reserved.