更新Fody依赖项至6.9.2,添加线程安全的大小显示更新方法,并在UI中实现下载进度显示

This commit is contained in:
2025-06-29 17:46:13 +08:00
parent 08ddd9723b
commit 8ad1be350b
4 changed files with 100 additions and 13 deletions

View File

@@ -184,8 +184,8 @@
</PropertyGroup> </PropertyGroup>
<Error Condition="!Exists('packages\Costura.Fody.6.0.0\build\Costura.Fody.props')" Text="$([System.String]::Format('$(ErrorText)', 'packages\Costura.Fody.6.0.0\build\Costura.Fody.props'))" /> <Error Condition="!Exists('packages\Costura.Fody.6.0.0\build\Costura.Fody.props')" Text="$([System.String]::Format('$(ErrorText)', 'packages\Costura.Fody.6.0.0\build\Costura.Fody.props'))" />
<Error Condition="!Exists('packages\Costura.Fody.6.0.0\build\Costura.Fody.targets')" Text="$([System.String]::Format('$(ErrorText)', 'packages\Costura.Fody.6.0.0\build\Costura.Fody.targets'))" /> <Error Condition="!Exists('packages\Costura.Fody.6.0.0\build\Costura.Fody.targets')" Text="$([System.String]::Format('$(ErrorText)', 'packages\Costura.Fody.6.0.0\build\Costura.Fody.targets'))" />
<Error Condition="!Exists('packages\Fody.6.8.2\build\Fody.targets')" Text="$([System.String]::Format('$(ErrorText)', 'packages\Fody.6.8.2\build\Fody.targets'))" /> <Error Condition="!Exists('packages\Fody.6.9.2\build\Fody.targets')" Text="$([System.String]::Format('$(ErrorText)', 'packages\Fody.6.9.2\build\Fody.targets'))" />
</Target> </Target>
<Import Project="packages\Costura.Fody.6.0.0\build\Costura.Fody.targets" Condition="Exists('packages\Costura.Fody.6.0.0\build\Costura.Fody.targets')" /> <Import Project="packages\Costura.Fody.6.0.0\build\Costura.Fody.targets" Condition="Exists('packages\Costura.Fody.6.0.0\build\Costura.Fody.targets')" />
<Import Project="packages\Fody.6.8.2\build\Fody.targets" Condition="Exists('packages\Fody.6.8.2\build\Fody.targets')" /> <Import Project="packages\Fody.6.9.2\build\Fody.targets" Condition="Exists('packages\Fody.6.9.2\build\Fody.targets')" />
</Project> </Project>

17
Form1.Designer.cs generated
View File

@@ -32,6 +32,7 @@
this.Update_Pro = new System.Windows.Forms.ProgressBar(); this.Update_Pro = new System.Windows.Forms.ProgressBar();
this.Status_Box = new System.Windows.Forms.Label(); this.Status_Box = new System.Windows.Forms.Label();
this.Count_Box = new System.Windows.Forms.Label(); this.Count_Box = new System.Windows.Forms.Label();
this.Size_Box = new System.Windows.Forms.Label();
this.SuspendLayout(); this.SuspendLayout();
// //
// Update_Text // Update_Text
@@ -55,24 +56,33 @@
this.Status_Box.AutoSize = false; this.Status_Box.AutoSize = false;
this.Status_Box.Location = new System.Drawing.Point(72, 12); this.Status_Box.Location = new System.Drawing.Point(72, 12);
this.Status_Box.Name = "Status_Box"; this.Status_Box.Name = "Status_Box";
this.Status_Box.Size = new System.Drawing.Size(213, 12); this.Status_Box.Size = new System.Drawing.Size(94, 12);
this.Status_Box.TabIndex = 2; this.Status_Box.TabIndex = 2;
this.Status_Box.Text = "..."; this.Status_Box.Text = "...";
// //
// Count_Box // Count_Box
// //
this.Count_Box.Location = new System.Drawing.Point(291, 12); this.Count_Box.Location = new System.Drawing.Point(296, 12);
this.Count_Box.Name = "Count_Box"; this.Count_Box.Name = "Count_Box";
this.Count_Box.Size = new System.Drawing.Size(60, 13); this.Count_Box.Size = new System.Drawing.Size(55, 13);
this.Count_Box.TabIndex = 3; this.Count_Box.TabIndex = 3;
this.Count_Box.TextAlign = System.Drawing.ContentAlignment.TopRight; this.Count_Box.TextAlign = System.Drawing.ContentAlignment.TopRight;
// //
// Size_Box
//
this.Size_Box.Location = new System.Drawing.Point(166, 12);
this.Size_Box.Name = "Size_Box";
this.Size_Box.Size = new System.Drawing.Size(130, 13);
this.Size_Box.TabIndex = 4;
this.Size_Box.TextAlign = System.Drawing.ContentAlignment.TopRight;
//
// Update // Update
// //
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(363, 73); this.ClientSize = new System.Drawing.Size(363, 73);
this.ControlBox = false; this.ControlBox = false;
this.Controls.Add(this.Size_Box);
this.Controls.Add(this.Count_Box); this.Controls.Add(this.Count_Box);
this.Controls.Add(this.Status_Box); this.Controls.Add(this.Status_Box);
this.Controls.Add(this.Update_Pro); this.Controls.Add(this.Update_Pro);
@@ -96,6 +106,7 @@
private System.Windows.Forms.ProgressBar Update_Pro; private System.Windows.Forms.ProgressBar Update_Pro;
private System.Windows.Forms.Label Status_Box; private System.Windows.Forms.Label Status_Box;
private System.Windows.Forms.Label Count_Box; private System.Windows.Forms.Label Count_Box;
private System.Windows.Forms.Label Size_Box;
} }
} }

View File

@@ -149,6 +149,22 @@ namespace CheckDownload
} }
} }
/// <summary>
/// 更新大小显示文本(线程安全)
/// </summary>
/// <param name="sizeMessage">大小值</param>
private void UpdateSize(string sizeMessage)
{
if (this.InvokeRequired)
{
this.Invoke((MethodInvoker)delegate { Size_Box.Text = sizeMessage; });
}
else
{
Size_Box.Text = sizeMessage;
}
}
/// <summary> /// <summary>
/// 窗体加载事件处理,启动更新流程 /// 窗体加载事件处理,启动更新流程
/// </summary> /// </summary>
@@ -183,6 +199,7 @@ namespace CheckDownload
CleanupNewFiles(); CleanupNewFiles();
UpdateStatus("下载在线MD5文件并读取..."); UpdateStatus("下载在线MD5文件并读取...");
UpdateCount(""); UpdateCount("");
UpdateSize("");
string tempFilePath = Path.Combine(_tempDirectory, Md5File); string tempFilePath = Path.Combine(_tempDirectory, Md5File);
// 使用新的带123盘的下载方法 // 使用新的带123盘的下载方法
if (!await DownloadMd5FileWithFallback(Md5File, tempFilePath)) if (!await DownloadMd5FileWithFallback(Md5File, tempFilePath))
@@ -210,6 +227,7 @@ namespace CheckDownload
{ {
UpdateStatus("所有文件都是最新的,无需更新"); UpdateStatus("所有文件都是最新的,无需更新");
UpdateCount(""); UpdateCount("");
UpdateSize("");
UpdateProgressValue(100); UpdateProgressValue(100);
// 无需更新时清理临时文件夹 // 无需更新时清理临时文件夹
@@ -238,11 +256,13 @@ namespace CheckDownload
{ {
UpdateStatus($"有 {failedFiles.Count} 个文件下载失败,开始重试..."); UpdateStatus($"有 {failedFiles.Count} 个文件下载失败,开始重试...");
UpdateCount(""); UpdateCount("");
UpdateSize("");
var stillFailing = await RetryFailedFilesAsync(new Dictionary<string, string>(failedFiles)); var stillFailing = await RetryFailedFilesAsync(new Dictionary<string, string>(failedFiles));
if (stillFailing.Any()) if (stillFailing.Any())
{ {
UpdateStatus($"重试后仍有 {stillFailing.Count} 个文件下载失败。"); UpdateStatus($"重试后仍有 {stillFailing.Count} 个文件下载失败。");
UpdateCount(""); UpdateCount("");
UpdateSize("");
} }
} }
@@ -507,7 +527,7 @@ namespace CheckDownload
using (var fileStream = File.Create(tempFilePath)) using (var fileStream = File.Create(tempFilePath))
{ {
await obj.Content.CopyToAsync(fileStream); await DownloadWithProgressAsync(obj.Content, fileStream, obj.Metadata.ContentLength);
} }
return true; return true;
} }
@@ -515,6 +535,7 @@ namespace CheckDownload
{ {
UpdateStatus($"{fileName}"); UpdateStatus($"{fileName}");
UpdateCount($"{_completedCount + 1}/{_totalCount}"); UpdateCount($"{_completedCount + 1}/{_totalCount}");
UpdateSize("");
string ossKey = $"File/{expectedMd5}"; string ossKey = $"File/{expectedMd5}";
return await DownloadFileWithFallback(ossKey, tempFilePath); return await DownloadFileWithFallback(ossKey, tempFilePath);
} }
@@ -587,11 +608,13 @@ namespace CheckDownload
{ {
UpdateStatus($"正在从123盘下载: {fileName}"); UpdateStatus($"正在从123盘下载: {fileName}");
UpdateCount(""); UpdateCount("");
UpdateSize("");
string authUrl = GenerateAuthUrl($"http://{OneDriveMainDomain}{OneDrivePath}", fileName); string authUrl = GenerateAuthUrl($"http://{OneDriveMainDomain}{OneDrivePath}", fileName);
UpdateStatus($"使用主域名下载文件..."); UpdateStatus($"使用主域名下载文件...");
UpdateCount(""); UpdateCount("");
UpdateSize("");
var request = new HttpRequestMessage(HttpMethod.Get, authUrl) { Version = HttpVersion.Version11 }; var request = new HttpRequestMessage(HttpMethod.Get, authUrl) { Version = HttpVersion.Version11 };
request.Headers.Add("User-Agent", "CheckDownload/1.0"); request.Headers.Add("User-Agent", "CheckDownload/1.0");
@@ -608,11 +631,12 @@ namespace CheckDownload
using (var remote = await response.Content.ReadAsStreamAsync()) using (var remote = await response.Content.ReadAsStreamAsync())
using (var localFile = File.Create(localPath)) using (var localFile = File.Create(localPath))
{ {
await remote.CopyToAsync(localFile); await DownloadWithProgressAsync(remote, localFile, response.Content.Headers.ContentLength);
} }
UpdateStatus($"123盘主域名下载成功: {fileName}"); UpdateStatus($"123盘主域名下载成功: {fileName}");
UpdateCount(""); UpdateCount("");
UpdateSize("");
return true; return true;
} }
} }
@@ -620,17 +644,20 @@ namespace CheckDownload
{ {
UpdateStatus($"123盘主域名下载失败尝试备用域名: {fileName}"); UpdateStatus($"123盘主域名下载失败尝试备用域名: {fileName}");
UpdateCount(""); UpdateCount("");
UpdateSize("");
} }
try try
{ {
UpdateStatus($"正在从123盘备用域名下载: {fileName}"); UpdateStatus($"正在从123盘备用域名下载: {fileName}");
UpdateCount(""); UpdateCount("");
UpdateSize("");
string authUrl = GenerateAuthUrl($"http://{OneDriveBackupDomain}{OneDrivePath}", fileName); string authUrl = GenerateAuthUrl($"http://{OneDriveBackupDomain}{OneDrivePath}", fileName);
UpdateStatus($"使用备用域名下载文件..."); UpdateStatus($"使用备用域名下载文件...");
UpdateCount(""); UpdateCount("");
UpdateSize("");
var request = new HttpRequestMessage(HttpMethod.Get, authUrl) { Version = HttpVersion.Version11 }; var request = new HttpRequestMessage(HttpMethod.Get, authUrl) { Version = HttpVersion.Version11 };
request.Headers.Add("User-Agent", "CheckDownload/1.0"); request.Headers.Add("User-Agent", "CheckDownload/1.0");
@@ -647,11 +674,12 @@ namespace CheckDownload
using (var remote = await response.Content.ReadAsStreamAsync()) using (var remote = await response.Content.ReadAsStreamAsync())
using (var localFile = File.Create(localPath)) using (var localFile = File.Create(localPath))
{ {
await remote.CopyToAsync(localFile); await DownloadWithProgressAsync(remote, localFile, response.Content.Headers.ContentLength);
} }
UpdateStatus($"123盘备用域名下载成功: {fileName}"); UpdateStatus($"123盘备用域名下载成功: {fileName}");
UpdateCount(""); UpdateCount("");
UpdateSize("");
return true; return true;
} }
} }
@@ -692,7 +720,7 @@ namespace CheckDownload
using (var remote = await response.Content.ReadAsStreamAsync()) using (var remote = await response.Content.ReadAsStreamAsync())
using (var localFile = File.Create(localPath)) using (var localFile = File.Create(localPath))
{ {
await remote.CopyToAsync(localFile); await DownloadWithProgressAsync(remote, localFile, response.Content.Headers.ContentLength);
} }
return true; return true;
@@ -721,7 +749,7 @@ namespace CheckDownload
using (var remote = await response.Content.ReadAsStreamAsync()) using (var remote = await response.Content.ReadAsStreamAsync())
using (var localFile = File.Create(localPath)) using (var localFile = File.Create(localPath))
{ {
await remote.CopyToAsync(localFile); await DownloadWithProgressAsync(remote, localFile, response.Content.Headers.ContentLength);
} }
return true; return true;
@@ -746,6 +774,7 @@ namespace CheckDownload
{ {
UpdateStatus($"第 {i + 1} 次重试,剩余 {filesToRetry.Count} 个文件..."); UpdateStatus($"第 {i + 1} 次重试,剩余 {filesToRetry.Count} 个文件...");
UpdateCount(""); UpdateCount("");
UpdateSize("");
var failedThisRound = new ConcurrentDictionary<string, string>(); var failedThisRound = new ConcurrentDictionary<string, string>();
await PerformDownloads(filesToRetry, failedThisRound); await PerformDownloads(filesToRetry, failedThisRound);
@@ -756,6 +785,7 @@ namespace CheckDownload
{ {
UpdateStatus($"等待 3 秒后进行下一次重试..."); UpdateStatus($"等待 3 秒后进行下一次重试...");
UpdateCount(""); UpdateCount("");
UpdateSize("");
await Task.Delay(3000); await Task.Delay(3000);
} }
} }
@@ -808,6 +838,7 @@ namespace CheckDownload
{ {
UpdateStatus("正在校验文件..."); UpdateStatus("正在校验文件...");
UpdateCount(""); UpdateCount("");
UpdateSize("");
var failedFiles = new ConcurrentBag<string>(); var failedFiles = new ConcurrentBag<string>();
var filesForScripting = new ConcurrentBag<(string original, string newFile)>(); var filesForScripting = new ConcurrentBag<(string original, string newFile)>();
@@ -875,6 +906,7 @@ namespace CheckDownload
{ {
UpdateStatus("所有文件校验和保存成功"); UpdateStatus("所有文件校验和保存成功");
UpdateCount(""); UpdateCount("");
UpdateSize("");
UpdateProgressValue(100); UpdateProgressValue(100);
} }
} }
@@ -1039,7 +1071,7 @@ namespace CheckDownload
} }
using (var fileStream = File.Create(localPath)) using (var fileStream = File.Create(localPath))
{ {
obj.Content.CopyTo(fileStream); await DownloadWithProgressAsync(obj.Content, fileStream, obj.Metadata.ContentLength);
} }
return true; return true;
} }
@@ -1083,7 +1115,7 @@ namespace CheckDownload
using (var remote = await response.Content.ReadAsStreamAsync()) using (var remote = await response.Content.ReadAsStreamAsync())
using (var localFile = File.Create(localPath)) using (var localFile = File.Create(localPath))
{ {
await remote.CopyToAsync(localFile); await DownloadWithProgressAsync(remote, localFile, response.Content.Headers.ContentLength);
} }
} }
return true; return true;
@@ -1398,5 +1430,49 @@ namespace CheckDownload
return BitConverter.ToString(hashBytes).Replace("-", string.Empty).ToLowerInvariant(); return BitConverter.ToString(hashBytes).Replace("-", string.Empty).ToLowerInvariant();
} }
} }
/// <summary>
/// 异步将远程数据流写入本地文件流,并实时更新下载进度
/// </summary>
/// <param name="remoteStream">远程数据源的流</param>
/// <param name="localStream">本地文件的流</param>
/// <param name="totalBytes">文件的总字节数,用于计算进度</param>
private async Task DownloadWithProgressAsync(Stream remoteStream, Stream localStream, long? totalBytes)
{
long totalRead = 0;
byte[] buffer = new byte[8192]; // 8KB 缓冲区
int bytesRead;
while ((bytesRead = await remoteStream.ReadAsync(buffer, 0, buffer.Length)) > 0)
{
await localStream.WriteAsync(buffer, 0, bytesRead);
totalRead += bytesRead;
if (totalBytes.HasValue)
{
string progressText = $"{FormatBytes(totalRead)}/{FormatBytes(totalBytes.Value)}";
UpdateSize(progressText);
}
}
}
/// <summary>
/// 将字节大小格式化为更易读的单位B, KB, MB, GB, TB
/// </summary>
/// <param name="bytes">要格式化的字节数</param>
/// <returns>格式化后的字符串</returns>
private static string FormatBytes(long bytes)
{
string[] suffixes = { "B", "KB", "MB", "GB", "TB" };
int i = 0;
double dblSByte = bytes;
if (bytes > 1024)
{
for (i = 0; (bytes / 1024) > 0 && i < suffixes.Length - 1; i++, bytes /= 1024)
{
dblSByte = bytes / 1024.0;
}
}
return $"{dblSByte:0.##}{suffixes[i]}";
}
} }
} }

View File

@@ -3,7 +3,7 @@
<package id="Aliyun.OSS.SDK" version="2.14.1" targetFramework="net472" /> <package id="Aliyun.OSS.SDK" version="2.14.1" targetFramework="net472" />
<package id="Costura.Fody" version="6.0.0" targetFramework="net472" developmentDependency="true" /> <package id="Costura.Fody" version="6.0.0" targetFramework="net472" developmentDependency="true" />
<package id="DnsClient" version="1.8.0" targetFramework="net472" /> <package id="DnsClient" version="1.8.0" targetFramework="net472" />
<package id="Fody" version="6.8.2" targetFramework="net472" developmentDependency="true" /> <package id="Fody" version="6.9.2" targetFramework="net472" developmentDependency="true" />
<package id="LanzouCloudSolve" version="1.0.3" targetFramework="net472" /> <package id="LanzouCloudSolve" version="1.0.3" targetFramework="net472" />
<package id="Microsoft.Bcl.AsyncInterfaces" version="9.0.6" targetFramework="net472" /> <package id="Microsoft.Bcl.AsyncInterfaces" version="9.0.6" targetFramework="net472" />
<package id="Newtonsoft.Json" version="13.0.3" targetFramework="net472" /> <package id="Newtonsoft.Json" version="13.0.3" targetFramework="net472" />