C Sharpの基礎 - ClickOnce

提供:MochiuWiki : SUSE, EC, PCB
ナビゲーションに移動 検索に移動

概要

開発中はAssemblyVersionでアスタリスク (*) を使用して、各ビルドの追跡を容易にする。

製品リリース時には、両方のバージョンを明示的な数値に固定する。
メジャーアップデートや互換性に影響する変更を行う場合は、AssemblyVersionを適切にインクリメントする

この2つのバージョン管理を適切に行うことにより、アプリケーションの配布とメンテナンスが効率的に行えるようになる。


AssemblyVersion

# 例:
AssemblyVersion ("1.0.0.*")


  • バージョニング
    • メジャーバージョン
    • マイナーバージョン
    • ビルド番号
    • リビジョン番号
      * (アスタリスク) は自動インクリメントを意味しており、アプリケーションをビルドするたびに自動的に番号が増加する。
      この番号は、ビルド時の日付と時刻に基づいて生成される。
      日付部分 : 2000年1月1日からの経過日数
      時刻部分 : 午前0時からの経過秒数を2で除算した値


AssemblyVersionは、.NET Frameworkが参照アセンブリの互換性を判断するために使用する。
バージョンが変更される場合、そのアセンブリを参照している他のアプリケーションに影響を与える可能性がある。


AssemblyFileVersion

# 例:
AssemblyFileVersion ("1.0.0.0")


  • バージョニング
    • 製品の公開バージョンを表すために使用される。
    • Windowsエクスプローラでファイルのプロパティを確認した場合に表示されるバージョン
    • 手動で管理する必要があり、自動インクリメントは行われない。
    • 製品のリリース管理やサポート時の参照等に使用する。


一方、AssemblyFileVersionは純粋に情報提供目的であり、アプリケーションの動作には影響を与えない。
製品管理やユーザサポートで使用される。


使用例 : アプリケーション更新プログラム

 using System;
 using System.ComponentModel;
 using System.Deployment.Application;
 using System.Threading.Tasks;
 using System.Windows.Forms;
 
 public class ApplicationUpdater
 {
    // アップデートの進捗状況を通知するためのイベント
    public event EventHandler<ProgressChangedEventArgs> UpdateProgressChanged;
    public event EventHandler<AsyncCompletedEventArgs> UpdateCompleted;
 
    /// <summary>
    /// アプリケーションの更新を非同期で確認し、必要に応じて更新を実行します
    /// </summary>
    /// <returns>更新が実行されたかどうかを示すブール値</returns>
    public async Task<bool> CheckAndUpdateAsync()
    {
       try
       {
          // ClickOnceでデプロイされているかを確認
          if (!ApplicationDeployment.IsNetworkDeployed)
          {
             throw new InvalidOperationException("このアプリケーションはClickOnceでデプロイされていません。");
          }
 
          var deployment = ApplicationDeployment.CurrentDeployment;
 
          // 更新の確認を非同期で実行
          var updateCheckInfo = await Task.Run(() => deployment.CheckForDetailedUpdate());
 
          if (!updateCheckInfo.UpdateAvailable)
          {
             return false; // 更新は不要
          }
 
          // 更新のダウンロードと適用を非同期で実行
          await UpdateApplicationAsync(deployment);
 
          return true;
       }
       catch (DeploymentDownloadException ex)
       {
          throw new ApplicationException("アップデートのダウンロード中にエラーが発生しました。", ex);
       }
       catch (InvalidDeploymentException ex)
       {
          throw new ApplicationException("ClickOnceの展開に問題が発生しました。", ex);
       }
       catch (Exception ex)
       {
          throw new ApplicationException("アップデートプロセス中に予期せぬエラーが発生しました。", ex);
       }
    }
 
    /// <summary>
    /// アプリケーションの更新を非同期で実行し、進捗状況を通知します
    /// </summary>
    /// <param name="deployment">ApplicationDeploymentのインスタンス</param>
    private async Task UpdateApplicationAsync(ApplicationDeployment deployment)
    {
       try
       {
          // 進捗状況の通知を設定
          deployment.UpdateProgressChanged += (sender, args) => {
             UpdateProgressChanged?.Invoke(this, new ProgressChangedEventArgs(args.ProgressPercentage, $"ダウンロード進捗: {args.BytesCompleted}/{args.BytesTotal} バイト"));
          };
 
          deployment.UpdateCompleted += (sender, args) => {
             UpdateCompleted?.Invoke(this, args);
          };
 
          // 更新の適用を非同期で実行
          await Task.Run(() => deployment.Update());
 
          // アプリケーションの再起動が必要な場合の処理
          if (MessageBox.Show("アップデートが完了しました。アプリケーションを再起動しますか?", "更新完了", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
          {
             Application.Restart();
          }
       }
       catch (Exception ex)
       {
          throw new ApplicationException("更新の適用中にエラーが発生しました。", ex);
       }
    }
 }


 // 使用例
 
 public class Program
 {
    public static async Task Main()
    {
       var updater = new ApplicationUpdater();
 
       // 進捗状況の表示を設定
       updater.UpdateProgressChanged += (sender, args) => {
          Console.WriteLine($"進捗状況: {args.ProgressPercentage}% - {args.UserState}");
       };
 
       try
       {
          bool updatePerformed = await updater.CheckAndUpdateAsync();
          if (!updatePerformed)
          {
             Console.WriteLine("利用可能な更新はありません。");
          }
       }
       catch (ApplicationException ex)
       {
          MessageBox.Show($"更新プロセスでエラーが発生しました: {ex.Message}", "エラー", MessageBoxButtons.OK, MessageBoxIcon.Error);
       }
    }
 }