downkyicore更新机制详解:自动升级与版本检查实现
downkyicore作为哔哩哔哩视频下载工具,其更新机制确保用户能够及时获取最新功能和安全修复。本文将深入解析其自动升级与版本检查的实现原理,包括版本检测流程、更新通知机制及数据迁移策略。
版本检查核心组件
downkyicore的版本检查功能主要由VersionCheckerService实现,该服务通过GitHub API获取最新版本信息并与本地版本比对。其核心实现位于DownKyi/Services/VersionCheckerService.cs,构造函数接收仓库所有者、仓库名称及是否包含预发布版本等参数:
public VersionCheckerService(string repoOwner, string repoName, bool includePrereleases = false)
{
_repoOwner = repoOwner;
_repoName = repoName;
_includePrereleases = includePrereleases;
}
服务提供GetLatestReleaseAsync方法从GitHub API获取版本信息,根据includePrereleases参数决定是否获取预发布版本:
public async Task<GitHubRelease?> GetLatestReleaseAsync(string? excludedVersion = null)
{
using var client = new HttpClient();
client.DefaultRequestHeaders.Add("User-Agent", "downkyi");
client.Timeout = TimeSpan.FromSeconds(3);
try
{
if (_includePrereleases)
{
var releasesUrl = $"https://api.github.com/repos/{_repoOwner}/{_repoName}/releases";
var releasesJson = await client.GetStringAsync(releasesUrl);
var releases = JsonConvert.DeserializeObject<GitHubRelease[]>(releasesJson);
return string.IsNullOrEmpty(excludedVersion)
? releases?.FirstOrDefault()
: releases?.FirstOrDefault(r => r.TagName.TrimStart('v') != excludedVersion);
}
else
{
var latestReleaseUrl = $"https://api.github.com/repos/{_repoOwner}/{_repoName}/releases/latest";
var latestReleaseJson = await client.GetStringAsync(latestReleaseUrl);
var release = JsonConvert.DeserializeObject<GitHubRelease>(latestReleaseJson);
return string.IsNullOrEmpty(excludedVersion) ||
release?.TagName.TrimStart('v') != excludedVersion ? release : null;
}
}
catch (Exception e)
{
// 异常处理
}
return null;
}
版本比较逻辑由IsNewVersionAvailable方法实现,通过Version类比较本地版本与远程版本:
public bool IsNewVersionAvailable(string latestVersion)
{
string v = new AppInfo().VersionName;
#if DEBUG
v = v.Replace("-debug", string.Empty);
#endif
var current = new Version(v.TrimStart('v'));
var latest = new Version(latestVersion.TrimStart('v'));
return latest > current;
}
版本信息模型
版本信息通过DownKyi/Models/GitHubRelease.cs定义的数据模型存储,包含标签名、版本名称、发布说明、是否预发布及发布时间等字段:
public class GitHubRelease
{
[JsonProperty("tag_name")]
public string TagName { get; set; }
[JsonProperty("name")]
public string Name { get; set; }
[JsonProperty("body")]
public string Body { get; set; }
[JsonProperty("prerelease")]
public bool Prerelease { get; set; }
[JsonProperty("published_at")]
public DateTime? PublishedAt { get; set; }
// 空值检查方法
public static bool IsNullOrEmpty(GitHubRelease? release)
{
return release == null || release.IsEmpty();
}
}
更新触发与通知流程
版本检查在应用启动和"关于"页面中触发。在DownKyi/ViewModels/MainWindowViewModel.cs中,应用启动时创建VersionCheckerService实例并检查更新:
var service = new VersionCheckerService(App.RepoOwner, App.RepoName,
SettingsManager.GetInstance().GetIsReceiveBetaVersionOnLaunch());
var release = await service.GetLatestReleaseAsync(SettingsManager.GetInstance().GetSkipVersionOnLaunch());
if (!GitHubRelease.IsNullOrEmpty(release) && service.IsNewVersionAvailable(release.TagName.TrimStart('v')))
{
// 显示更新对话框
}
当检测到新版本时,通过DownKyi/ViewModels/Dialogs/NewVersionAvailableDialogViewModel.cs处理更新通知,对话框展示版本信息并提供更新和跳过选项:
public override void OnDialogOpened(IDialogParameters parameters)
{
var release = parameters.GetValue<GitHubRelease>("release");
EnableSkipVersionOnLaunch = parameters.GetValue<bool>("enableSkipVersion");
MarkdownText = release.Body;
TagName = release.TagName;
NewVersion = release.TagName.TrimStart('v');
}
private async Task ExecuteAllowCommand()
{
const ButtonResult result = ButtonResult.OK;
await PlatformHelper.OpenUrl($"https://github.com/{App.RepoOwner}/{App.RepoName}/releases/tag/{TagName}");
RaiseRequestClose(new DialogResult(result));
}
private void ExecuteSkipCurrentVersionCommand()
{
SettingsManager.GetInstance().SetSkipVersionOnLaunch(NewVersion);
RaiseRequestClose(new DialogResult());
}
数据迁移与版本升级
应用升级时可能需要进行数据迁移,DownKyi/ViewModels/Dialogs/ViewUpgradingDialogViewModel.cs处理版本间的数据迁移逻辑,如从1.0.20版本迁移到1.0.21版本时的登录信息和下载数据迁移:
private void Upgrade()
{
Task.Run(Upgrade1_0_20To1_0_21);
}
private async void Upgrade1_0_20To1_0_21()
{
// 迁移登录信息
var loginInfoPath = StorageManager.GetLogin();
if (File.Exists(loginInfoPath))
{
using Stream stream = File.Open(loginInfoPath, FileMode.Open);
if (NrbfDecoder.StartsWithPayloadHeader(stream))
{
// 反序列化并迁移Cookie数据
LoginHelper.SaveLoginInfoCookies(cookies);
}
}
// 迁移下载数据库
string[] possibleDatabasePaths = { StorageManager.GetDownload(), StorageManager.GetDownload().Replace(".db", "_debug.db") };
var oldDbPath = possibleDatabasePaths.FirstOrDefault(File.Exists);
if (oldDbPath != null)
{
// 连接旧数据库并迁移数据到新格式
_downloadedRepository.Insert(downloadedList);
}
}
迁移过程中通过UI线程更新进度信息,并在迁移失败时备份数据库文件:
private async Task HandleFailedDatabase(string dbPath)
{
string backupDir = Path.Combine(Path.GetDirectoryName(dbPath) ?? ".", "Backup");
if (!Directory.Exists(backupDir)) Directory.CreateDirectory(backupDir);
string backupPath = Path.Combine(backupDir, $"{fileName}_failed_{timestamp}{extension}");
File.Move(dbPath, backupPath);
await SetImportantMessage($"原数据库已备份至: {Path.GetFileName(backupPath)}");
}
更新机制流程图
总结
downkyicore的更新机制通过VersionCheckerService与GitHub API交互实现版本检查,结合GitHubRelease模型解析版本信息,使用对话框通知用户更新,并通过数据迁移确保版本升级的平滑过渡。这一机制确保用户能够及时获取最新功能,同时保障数据安全。开发者可通过DownKyi/Services/VersionCheckerService.cs和相关视图模型深入了解实现细节,进一步扩展更新功能。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考



