C Sharpの基礎 - ClickOnce
ナビゲーションに移動
検索に移動
概要
開発中は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);
}
}
}