ClickOnceアプリを手動で更新

今回開発したシステムはクライアントモジュールをClickOnceで配布するのだが、ひとつ問題が発生した。

ClickOnceアプリケーションを起動すると、更新がある場合「更新の許可を求める」ダイアログが表示されるがここで「スキップ」を選ぶと次回起動時からこのダイアログが表示されなくなる。

以下の記事によると一度スキップすると以後7日間表示されないらしい。(しかもこれを変更できない)

もう一度発行し直してバージョンを上げると更新をかける事ができるけど、これでは解決にならないので、アプリケーションから自動更新を行う方法を調べてみた。

フォームにボタンを貼り付けて、そのボタンのClickイベントのイベントハンドラに以下のコードを記述する。

this.Cursor = Cursors.WaitCursor;
try {
    if(!ApplicationDeployment.IsNetworkDeployed) return;

    ApplicationDeployment currentDeploy = ApplicationDeployment.CurrentDeployment;

    if(currentDeploy.CheckForUpdate()) {
        if((MessageBox.Show(this, "最新版が利用できます。更新しますか?", "更新の確認",
            MessageBoxButtons.YesNo, MessageBoxIcon.Question)) == DialogResult.No) return;

        currentDeploy.Update();
        
        if((MessageBox.Show(this,
            "更新が完了しました。更新を有効にするにはアプリケーションを再起動する必要があります。再起動しますか?",
            "再起動の確認", MessageBoxButtons.YesNo, MessageBoxIcon.Question)) == DialogResult.No) return;

        Application.Restart();
    }

} catch(DeploymentException exp) {
    MessageBox.Show(this, exp.Message, "更新エラー", MessageBoxButtons.OK, MessageBoxIcon.Error);

} finally {
    this.Cursor = Cursors.Default;
}

「System.Deployment.ApplicationDeployment」クラスでClickOnceの情報にアクセスできる。

  1. 「IsNetworkDeployed」プロパティでClickOnceで配付されたか調べる。
  2. 「CurrentDeployment」プロパティで現在のアプリケーションのClickOnce配置情報を取得する。
  3. 「CheckForUpdate」メソッドで更新があるかどうかを確認する。
  4. 「Update」メソッドでアプリケーションを更新する。
  5. 「Application」クラスの「Restart」メソッドでアプリケーションを再起動する。

これで「スキップ」対策はできるかな。
個人的には「Application.Restart」でアプリケーションを再起動できるのを知っただけでも収穫があった。