diff --git a/App.config b/App.config index 0256a61..978c5c5 100644 --- a/App.config +++ b/App.config @@ -11,7 +11,7 @@ - + diff --git a/CheckDownload.csproj b/CheckDownload.csproj index 83348a0..710a0d0 100644 --- a/CheckDownload.csproj +++ b/CheckDownload.csproj @@ -83,8 +83,8 @@ packages\LanzouCloudSolve.1.0.3\lib\netstandard2.0\LanzouCloudSolve.dll - - packages\Microsoft.Bcl.AsyncInterfaces.8.0.0\lib\net462\Microsoft.Bcl.AsyncInterfaces.dll + + packages\Microsoft.Bcl.AsyncInterfaces.9.0.6\lib\net462\Microsoft.Bcl.AsyncInterfaces.dll packages\Newtonsoft.Json.13.0.3\lib\net45\Newtonsoft.Json.dll @@ -94,6 +94,9 @@ packages\System.Buffers.4.5.1\lib\net461\System.Buffers.dll + + packages\System.IO.Pipelines.9.0.6\lib\net462\System.IO.Pipelines.dll + packages\System.Memory.4.5.5\lib\net461\System.Memory.dll @@ -104,11 +107,11 @@ packages\System.Runtime.CompilerServices.Unsafe.6.0.0\lib\net461\System.Runtime.CompilerServices.Unsafe.dll - - packages\System.Text.Encodings.Web.8.0.0\lib\net462\System.Text.Encodings.Web.dll + + packages\System.Text.Encodings.Web.9.0.6\lib\net462\System.Text.Encodings.Web.dll - - packages\System.Text.Json.8.0.1\lib\net462\System.Text.Json.dll + + packages\System.Text.Json.9.0.6\lib\net462\System.Text.Json.dll packages\System.Threading.Tasks.Extensions.4.5.4\lib\net461\System.Threading.Tasks.Extensions.dll @@ -181,8 +184,8 @@ - + - + \ No newline at end of file diff --git a/Form1.Designer.cs b/Form1.Designer.cs index b4b0f2a..9a5c82f 100644 --- a/Form1.Designer.cs +++ b/Form1.Designer.cs @@ -1,47 +1,39 @@ -namespace CheckDownload -{ - partial class Update - { - /// - /// 必需的设计器变量。 - /// - private System.ComponentModel.IContainer components = null; - - /// - /// 清理所有正在使用的资源。 - /// - /// 如果应释放托管资源,为 true;否则为 false。 - protected override void Dispose(bool disposing) - { - if (disposing && (components != null)) - { - components.Dispose(); - } - base.Dispose(disposing); - } - - #region Windows 窗体设计器生成的代码 - - /// - /// 设计器支持所需的方法 - 不要修改 - /// 使用代码编辑器修改此方法的内容。 - /// - private void InitializeComponent() - { - this.Update_Text = new System.Windows.Forms.Label(); +namespace CheckDownload +{ + partial class Update + { + /// + /// 必需的设计器变量。 + /// + private System.ComponentModel.IContainer components = null; + + /// + /// 清理所有正在使用的资源。 + /// + /// 如果应释放托管资源,为 true;否则为 false。 + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows 窗体设计器生成的代码 + + /// + /// 设计器支持所需的方法 - 不要修改 + /// 使用代码编辑器修改此方法的内容。 + /// + private void InitializeComponent() + { this.Update_Pro = new System.Windows.Forms.ProgressBar(); this.Status_Box = new System.Windows.Forms.Label(); + this.Count_Box = new System.Windows.Forms.Label(); + this.Size_Box = new System.Windows.Forms.Label(); this.SuspendLayout(); // - // Update_Text - // - this.Update_Text.AutoSize = true; - this.Update_Text.Location = new System.Drawing.Point(12, 12); - this.Update_Text.Name = "Update_Text"; - this.Update_Text.Size = new System.Drawing.Size(59, 12); - this.Update_Text.TabIndex = 0; - this.Update_Text.Text = "更新状态:"; - // // Update_Pro // this.Update_Pro.Location = new System.Drawing.Point(12, 36); @@ -51,22 +43,41 @@ // // Status_Box // - this.Status_Box.AutoSize = true; - this.Status_Box.Location = new System.Drawing.Point(72, 12); + this.Status_Box.AutoEllipsis = true; + this.Status_Box.Location = new System.Drawing.Point(12, 12); this.Status_Box.Name = "Status_Box"; - this.Status_Box.Size = new System.Drawing.Size(23, 12); + this.Status_Box.Size = new System.Drawing.Size(165, 12); this.Status_Box.TabIndex = 2; this.Status_Box.Text = "..."; // + // Count_Box + // + this.Count_Box.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.Count_Box.Location = new System.Drawing.Point(306, 12); + this.Count_Box.Name = "Count_Box"; + this.Count_Box.Size = new System.Drawing.Size(50, 12); + this.Count_Box.TabIndex = 3; + this.Count_Box.TextAlign = System.Drawing.ContentAlignment.TopRight; + // + // Size_Box + // + this.Size_Box.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.Size_Box.Location = new System.Drawing.Point(183, 12); + this.Size_Box.Name = "Size_Box"; + this.Size_Box.Size = new System.Drawing.Size(117, 12); + this.Size_Box.TabIndex = 4; + this.Size_Box.TextAlign = System.Drawing.ContentAlignment.TopRight; + // // Update // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.ClientSize = new System.Drawing.Size(363, 73); this.ControlBox = false; + this.Controls.Add(this.Size_Box); + this.Controls.Add(this.Count_Box); this.Controls.Add(this.Status_Box); this.Controls.Add(this.Update_Pro); - this.Controls.Add(this.Update_Text); this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None; this.MaximizeBox = false; this.MinimizeBox = false; @@ -76,15 +87,14 @@ this.TopMost = true; this.Load += new System.EventHandler(this.Update_Load); this.ResumeLayout(false); - this.PerformLayout(); - - } - - #endregion - - private System.Windows.Forms.Label Update_Text; - private System.Windows.Forms.ProgressBar Update_Pro; - private System.Windows.Forms.Label Status_Box; - } -} + } + + #endregion + private System.Windows.Forms.ProgressBar Update_Pro; + private System.Windows.Forms.Label Status_Box; + private System.Windows.Forms.Label Count_Box; + private System.Windows.Forms.Label Size_Box; + } +} + diff --git a/Form1.cs b/Form1.cs index 9aacdb1..7e26381 100644 --- a/Form1.cs +++ b/Form1.cs @@ -39,22 +39,29 @@ namespace CheckDownload // 阿里云OSS访问密钥Secret private const string OssAccessKeySecret = "7ClQns3wz6psmIp9T2OfuEn3tpzrCK"; // 123盘鉴权密钥 - private const string OneDriveAuthKey = "ZhwG3LxOtGJwM3ym"; + private const string OneDriveAuthKey = "6SwdpWdSJuJRSh"; // 123盘UID - private const string OneDriveUid = "1850250683"; + private const string OneDriveUid = "1826795402"; // 123盘路径(不包含域名)- 修改此处即可同时生效于主备域名 - private const string OneDrivePath = "/1850250683/SuWin"; + private const string OneDrivePath = "/1826795402/KeyAuth"; // 123盘主域名 private const string OneDriveMainDomain = "vip.123pan.cn"; // 123盘备用域名 private const string OneDriveBackupDomain = "vip.123yx.com"; // 123盘鉴权有效时间(秒) private const int OneDriveAuthTimeout = 600; + // 下载流超时时间(毫秒) + private const int DownloadStreamTimeoutMs = 60000; // 网络优化: 静态HttpClient实例,避免套接字耗尽 private static readonly HttpClient _httpClient = new HttpClient { Timeout = TimeSpan.FromSeconds(20) }; // OSS客户端:仅初始化一次,避免频繁创建导致内存占用过高 - private static readonly OssClient _ossClient = new OssClient(OssEndpoint, OssAccessKeyId, OssAccessKeySecret); + private static readonly ClientConfiguration _ossClientConfig = new ClientConfiguration + { + ConnectionTimeout = 20000, // 20 seconds + MaxErrorRetry = 0 + }; + private static readonly OssClient _ossClient = new OssClient(OssEndpoint, OssAccessKeyId, OssAccessKeySecret, _ossClientConfig); // 网络优化: 备用DNS服务列表,提高解析成功率 private static readonly List _dnsServers = new List { "223.5.5.5", "119.29.29.29" }; // 最大并发下载数量 @@ -67,6 +74,52 @@ namespace CheckDownload private int _completedCount = 0; // 总下载数量 private int _totalCount = 0; + // 已下载总字节数 + private long _totalDownloadedBytes = 0; + // 下载总计时器 + private Stopwatch _overallStopwatch; + // 已下载速度字节数 + private long _speedDownloadedBytes = 0; + // 更新计数显示(线程安全) + private void UpdateCountBox(int completed, int total) + { + string text = total > 0 ? $"{completed}/{total}" : ""; + if (this.InvokeRequired) + { + this.Invoke((MethodInvoker)delegate { Count_Box.Text = text; }); + } + else + { + Count_Box.Text = text; + } + } + // 更新文件大小和速度显示(线程安全) + private void UpdateSizeBox(string text) + { + if (this.InvokeRequired) + { + this.Invoke((MethodInvoker)delegate { Size_Box.Text = text; }); + } + else + { + Size_Box.Text = text; + } + } + // 累计已下载字节并更新Size_Box + private void AddDownloadedBytes(long bytes, bool countForSpeed) + { + long total = Interlocked.Add(ref _totalDownloadedBytes, bytes); + if (countForSpeed) + { + Interlocked.Add(ref _speedDownloadedBytes, bytes); + } + + if (_overallStopwatch == null) return; + + double mbTotal = total / 1024.0 / 1024.0; + double mbSpeed = (_speedDownloadedBytes / 1024.0 / 1024.0) / Math.Max(0.1, _overallStopwatch.Elapsed.TotalSeconds); + UpdateSizeBox($"{mbTotal:F1}MB/{mbSpeed:F1}MB/s"); + } // 临时文件夹路径 private string _tempDirectory; // 基准目录路径(用于文件更新的目标目录) @@ -107,13 +160,11 @@ namespace CheckDownload this.Invoke((MethodInvoker)delegate { Update_Pro.Value = Math.Min(Math.Max(percentage, Update_Pro.Minimum), Update_Pro.Maximum); - Application.DoEvents(); }); } else { Update_Pro.Value = Math.Min(Math.Max(percentage, Update_Pro.Minimum), Update_Pro.Maximum); - Application.DoEvents(); } } @@ -165,12 +216,12 @@ namespace CheckDownload try { CleanupNewFiles(); - UpdateStatus("下载在线MD5文件并读取..."); + UpdateStatus("下载MD5..."); string tempFilePath = Path.Combine(_tempDirectory, Md5File); // 使用新的带123盘的下载方法 if (!await DownloadMd5FileWithFallback(Md5File, tempFilePath)) { - UpdateStatus("下载在线MD5文件失败"); + UpdateStatus("MD5下载失败"); await Task.Delay(3000); this.Close(); return; @@ -178,7 +229,7 @@ namespace CheckDownload var onlineData = ReadOnlineMd5File(tempFilePath); if (!ValidateOnlineData(onlineData.Version, onlineData.Md5, onlineData.Data)) { - UpdateStatus("在线MD5文件无效"); + UpdateStatus("MD5文件无效"); await Task.Delay(3000); this.Close(); return; @@ -187,30 +238,34 @@ namespace CheckDownload // 基于md5.json内容智能检测基准目录 InitializeBaseDirectoryFromMd5Data(onlineData.Data); - UpdateStatus("比较本地和在线MD5文件..."); + UpdateStatus("比较文件..."); var compareResult = CompareMd5Data(onlineData.Data); if (compareResult.Count == 0) { - UpdateStatus("所有文件都是最新的,无需更新"); UpdateProgressValue(100); + UpdateCountBox(0, 0); + UpdateSizeBox(""); // 无需更新时清理临时文件夹 CleanupTempDirectory(); - - // 显示更新完成并等待2秒 - UpdateStatus("更新完成"); + UpdateStatus("无需更新"); await Task.Delay(2000); this.Close(); return; } - UpdateStatus("下载并验证文件..."); + UpdateStatus("下载文件..."); // 根据路径长度排序,优先下载小文件/浅层文件,可加其它排序规则 var orderedFileList = compareResult.OrderBy(k => k.Key.Length) .ToDictionary(k => k.Key, v => v.Value); _totalCount = orderedFileList.Count; _completedCount = 0; + _totalDownloadedBytes = 0; + _speedDownloadedBytes = 0; + _overallStopwatch = Stopwatch.StartNew(); + UpdateSizeBox("0MB/0MB/s"); + UpdateCountBox(_completedCount, _totalCount); _downloadedFiles.Clear(); var failedFiles = new ConcurrentDictionary(); @@ -218,17 +273,17 @@ namespace CheckDownload if (!failedFiles.IsEmpty) { - UpdateStatus($"有 {failedFiles.Count} 个文件下载失败,开始重试..."); + UpdateStatus($"重试 {failedFiles.Count} 个失败文件..."); var stillFailing = await RetryFailedFilesAsync(new Dictionary(failedFiles)); if (stillFailing.Any()) { - UpdateStatus($"重试后仍有 {stillFailing.Count} 个文件下载失败。"); + UpdateStatus($"{stillFailing.Count} 个文件重试失败"); } } if (_completedCount == 0 && orderedFileList.Count > 0) { - throw new Exception("所有文件下载失败。"); + throw new Exception("全部文件下载失败"); } await VerifyAndSaveAllFiles(); @@ -238,13 +293,15 @@ namespace CheckDownload // 显示完成状态并退出 UpdateStatus("更新完成"); + UpdateCountBox(0, 0); + UpdateSizeBox(""); await Task.Delay(3000); this.Close(); return; } catch (Exception ex) { - UpdateStatus($"更新失败: {ex.Message}"); + UpdateStatus($"更新失败: {ex.Message.Split(new[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries).FirstOrDefault()}"); await Task.Delay(3000); this.Close(); } @@ -260,7 +317,7 @@ namespace CheckDownload var newFiles = Directory.GetFiles(_baseDirectory, "*.new", SearchOption.AllDirectories); if (newFiles.Length > 0) { - UpdateStatus("正在清理旧的更新文件..."); + UpdateStatus("清理旧文件..."); foreach (var file in newFiles) { try @@ -297,9 +354,14 @@ namespace CheckDownload return (version, jsonMd5, data); } } - catch (Exception ex) when (ex is OssException || ex is JsonException) + catch (OssException) { - UpdateStatus($"读取在线MD5文件失败: {ex.Message}"); + UpdateStatus("读取MD5失败"); + return (null, null, null); + } + catch (JsonException) + { + UpdateStatus("读取MD5失败"); return (null, null, null); } } @@ -315,7 +377,7 @@ namespace CheckDownload { if (string.IsNullOrEmpty(version) || string.IsNullOrEmpty(md5) || data == null) { - UpdateStatus("在线MD5文件无效"); + UpdateStatus("MD5文件无效"); return false; } return true; @@ -384,6 +446,11 @@ namespace CheckDownload { _totalCount = fileList.Count; _completedCount = 0; + _totalDownloadedBytes = 0; + _speedDownloadedBytes = 0; + _overallStopwatch = Stopwatch.StartNew(); + UpdateSizeBox("0MB/0MB/s"); + UpdateCountBox(_completedCount, _totalCount); _downloadedFiles.Clear(); var failedFiles = new ConcurrentDictionary(); @@ -391,11 +458,11 @@ namespace CheckDownload if (!failedFiles.IsEmpty) { - UpdateStatus($"有 {failedFiles.Count} 个文件下载失败,开始重试..."); + UpdateStatus($"重试 {failedFiles.Count} 个失败文件..."); var stillFailing = await RetryFailedFilesAsync(new Dictionary(failedFiles)); if (stillFailing.Any()) { - UpdateStatus($"重试后仍有 {stillFailing.Count} 个文件下载失败。"); + UpdateStatus($"{stillFailing.Count} 个文件重试失败"); } } @@ -432,7 +499,8 @@ namespace CheckDownload int progress = (int)((double)_completedCount / _totalCount * 95); UpdateProgressValue(progress); - UpdateStatus($"{Path.GetFileName(file.Key)} {_completedCount}/{_totalCount}"); + UpdateStatus($"下载: {Path.GetFileName(file.Key)}"); + UpdateCountBox(_completedCount, _totalCount); } else { @@ -457,21 +525,29 @@ namespace CheckDownload { string tempFilePath = Path.Combine(_tempDirectory, filePath); string fileName = Path.GetFileName(filePath); + long downloadedBytes = 0; try { if (await CheckExistingTempFile(tempFilePath, expectedMd5, fileName)) { + // 已存在临时文件 + downloadedBytes = new FileInfo(tempFilePath).Length; + AddDownloadedBytes(downloadedBytes, false); return true; } - UpdateStatus($"{fileName} {_completedCount + 1}/{_totalCount}"); + UpdateStatus($"下载: {fileName}"); + UpdateCountBox(_completedCount + 1, _totalCount); if (await DownloadFileFromOneDrive(filePath, expectedMd5, tempFilePath)) { + downloadedBytes = new FileInfo(tempFilePath).Length; + AddDownloadedBytes(downloadedBytes, true); return true; } - UpdateStatus($"{fileName} {_completedCount + 1}/{_totalCount}"); + UpdateStatus($"下载: {fileName}"); + UpdateCountBox(_completedCount + 1, _totalCount); string ossKey = $"File/{expectedMd5}"; var obj = _ossClient.GetObject(OssBucketName, ossKey); @@ -484,19 +560,38 @@ namespace CheckDownload using (var fileStream = File.Create(tempFilePath)) { - await obj.Content.CopyToAsync(fileStream); + using (var cts = new CancellationTokenSource(DownloadStreamTimeoutMs)) + { + await obj.Content.CopyToAsync(fileStream, 81920, cts.Token); + } } + downloadedBytes = new FileInfo(tempFilePath).Length; + AddDownloadedBytes(downloadedBytes, true); return true; } - catch (Exception ex) when (ex is OssException || ex is WebException) + catch (Exception ex) when (ex is OssException || ex is WebException || ex is OperationCanceledException) { - UpdateStatus($"{fileName} {_completedCount + 1}/{_totalCount}"); + UpdateStatus($"下载: {fileName}"); + UpdateCountBox(_completedCount + 1, _totalCount); string ossKey = $"File/{expectedMd5}"; - return await DownloadFileWithFallback(ossKey, tempFilePath); + bool ok = await DownloadFileWithFallback(ossKey, tempFilePath); + if (ok) + { + try + { + downloadedBytes = new FileInfo(tempFilePath).Length; + AddDownloadedBytes(downloadedBytes, true); + } + catch + { + // File might not be accessible for a moment after download + } + } + return ok; } - catch (Exception ex) + catch { - UpdateStatus($"下载异常: {fileName} - {ex.Message}"); + UpdateStatus($"下载异常: {fileName}"); return false; } } @@ -517,25 +612,25 @@ namespace CheckDownload return false; } - UpdateStatus($"检查已存在的临时文件: {fileName}"); + UpdateStatus($"检查: {fileName}"); string actualMd5 = await Task.Run(() => CalculateMD5FromFile(tempFilePath)); if (actualMd5.Equals(expectedMd5, StringComparison.OrdinalIgnoreCase)) { - UpdateStatus($"临时文件完整,跳过下载: {fileName}"); + UpdateStatus($"跳过: {fileName}"); return true; } else { - UpdateStatus($"临时文件不完整,重新下载: {fileName}"); + UpdateStatus($"重下载: {fileName}"); File.Delete(tempFilePath); return false; } } catch (Exception ex) { - UpdateStatus($"检查临时文件时出错,将重新下载: {fileName} - {ex.Message}"); + UpdateStatus($"检查出错: {fileName}"); try { if (File.Exists(tempFilePath)) @@ -561,11 +656,11 @@ namespace CheckDownload { try { - UpdateStatus($"正在从123盘下载: {fileName}"); + UpdateStatus($"123盘下载: {fileName}"); string authUrl = GenerateAuthUrl($"http://{OneDriveMainDomain}{OneDrivePath}", fileName); - UpdateStatus($"使用主域名下载文件..."); + UpdateStatus("123盘主域..."); var request = new HttpRequestMessage(HttpMethod.Get, authUrl) { Version = HttpVersion.Version11 }; request.Headers.Add("User-Agent", "CheckDownload/1.0"); @@ -582,25 +677,28 @@ namespace CheckDownload using (var remote = await response.Content.ReadAsStreamAsync()) using (var localFile = File.Create(localPath)) { - await remote.CopyToAsync(localFile); + using (var cts = new CancellationTokenSource(DownloadStreamTimeoutMs)) + { + await remote.CopyToAsync(localFile, 81920, cts.Token); + } } - UpdateStatus($"123盘主域名下载成功: {fileName}"); + UpdateStatus($"主域成功: {fileName}"); return true; } } - catch (Exception ex) + catch { - UpdateStatus($"123盘主域名下载失败,尝试备用域名: {fileName}"); + UpdateStatus("主域失败, 转备用..."); } try { - UpdateStatus($"正在从123盘备用域名下载: {fileName}"); + UpdateStatus($"123盘备用下载: {fileName}"); string authUrl = GenerateAuthUrl($"http://{OneDriveBackupDomain}{OneDrivePath}", fileName); - UpdateStatus($"使用备用域名下载文件..."); + UpdateStatus("123盘备用域..."); var request = new HttpRequestMessage(HttpMethod.Get, authUrl) { Version = HttpVersion.Version11 }; request.Headers.Add("User-Agent", "CheckDownload/1.0"); @@ -617,16 +715,19 @@ namespace CheckDownload using (var remote = await response.Content.ReadAsStreamAsync()) using (var localFile = File.Create(localPath)) { - await remote.CopyToAsync(localFile); + using (var cts = new CancellationTokenSource(DownloadStreamTimeoutMs)) + { + await remote.CopyToAsync(localFile, 81920, cts.Token); + } } - UpdateStatus($"123盘备用域名下载成功: {fileName}"); + UpdateStatus($"备用域成功: {fileName}"); return true; } } - catch (Exception ex) + catch { - UpdateStatus($"123盘备用域名下载失败: {fileName} - {ex.Message}"); + UpdateStatus($"备用域失败: {fileName}"); return false; } } @@ -661,7 +762,10 @@ namespace CheckDownload using (var remote = await response.Content.ReadAsStreamAsync()) using (var localFile = File.Create(localPath)) { - await remote.CopyToAsync(localFile); + using (var cts = new CancellationTokenSource(DownloadStreamTimeoutMs)) + { + await remote.CopyToAsync(localFile, 81920, cts.Token); + } } return true; @@ -690,13 +794,16 @@ namespace CheckDownload using (var remote = await response.Content.ReadAsStreamAsync()) using (var localFile = File.Create(localPath)) { - await remote.CopyToAsync(localFile); + using (var cts = new CancellationTokenSource(DownloadStreamTimeoutMs)) + { + await remote.CopyToAsync(localFile, 81920, cts.Token); + } } return true; } } - catch (Exception ex) + catch { return false; } @@ -713,7 +820,7 @@ namespace CheckDownload for (int i = 0; i < MaxDownloadRetries && filesToRetry.Any(); i++) { - UpdateStatus($"第 {i + 1} 次重试,剩余 {filesToRetry.Count} 个文件..."); + UpdateStatus($"重试 {i + 1}/{MaxDownloadRetries}, 剩{filesToRetry.Count}个"); var failedThisRound = new ConcurrentDictionary(); await PerformDownloads(filesToRetry, failedThisRound); @@ -722,7 +829,7 @@ namespace CheckDownload if (filesToRetry.Any() && i < MaxDownloadRetries - 1) { - UpdateStatus($"等待 3 秒后进行下一次重试..."); + UpdateStatus("等待3秒后重试"); await Task.Delay(3000); } } @@ -753,18 +860,18 @@ namespace CheckDownload var ips = JsonConvert.DeserializeObject>(responseBody); if (ips != null && ips.Any()) { - UpdateStatus($"通过 {dnsServer} 成功解析域名 {domain}"); + UpdateStatus($"DNS解析成功: {dnsServer}"); return ips; } } - catch (Exception ex) + catch { - UpdateStatus($"通过 {dnsServer} 解析域名失败,尝试下一个..."); + UpdateStatus($"DNS解析失败: {dnsServer}"); await Task.Delay(500); } } - UpdateStatus($"所有DNS服务器均无法解析域名: {domain}"); + UpdateStatus("所有DNS解析失败"); return new List(); } @@ -773,7 +880,7 @@ namespace CheckDownload /// private async Task VerifyAndSaveAllFiles() { - UpdateStatus("正在校验文件..."); + UpdateStatus("校验文件..."); var failedFiles = new ConcurrentBag(); var filesForScripting = new ConcurrentBag<(string original, string newFile)>(); @@ -839,7 +946,7 @@ namespace CheckDownload } else { - UpdateStatus("所有文件校验和保存成功"); + UpdateStatus("校验保存成功"); UpdateProgressValue(100); } } @@ -859,25 +966,25 @@ namespace CheckDownload } catch (IOException) { - UpdateStatus($"文件被占用,尝试解锁..."); + UpdateStatus("文件占用,解锁中..."); try { await Task.Delay(1000); File.Move(sourcePath, targetPath); - UpdateStatus($"文件解锁成功并已更新"); + UpdateStatus("解锁并更新成功"); return true; } catch { - UpdateStatus($"文件仍被占用,无法移动"); + UpdateStatus("文件仍被占用"); return false; } } catch (Exception ex) { - UpdateStatus($"移动文件时发生错误: {ex.Message}"); + UpdateStatus("移动文件出错"); return false; } } @@ -927,9 +1034,9 @@ namespace CheckDownload }; Process.Start(startInfo); } - catch (Exception ex) + catch { - UpdateStatus($"创建替换脚本时出错: {ex.Message}"); + UpdateStatus("创建脚本出错"); } } @@ -951,9 +1058,9 @@ namespace CheckDownload Directory.CreateDirectory(_tempDirectory); } } - catch (Exception ex) + catch { - UpdateStatus($"初始化临时目录失败: {ex.Message}"); + UpdateStatus("初始化Temp失败"); } } @@ -1004,13 +1111,28 @@ namespace CheckDownload } using (var fileStream = File.Create(localPath)) { - obj.Content.CopyTo(fileStream); + using (var cts = new CancellationTokenSource(DownloadStreamTimeoutMs)) + { + await obj.Content.CopyToAsync(fileStream, 81920, cts.Token); + } } return true; } - catch (Exception ex) when (ex is OssException || ex is WebException || ex is IOException) + catch (OssException) { - UpdateStatus($"主下载失败,尝试备用方案..."); + UpdateStatus("主下载失败,转备用..."); + } + catch (WebException) + { + UpdateStatus("主下载失败,转备用..."); + } + catch (IOException) + { + UpdateStatus("主下载失败,转备用..."); + } + catch (OperationCanceledException) + { + UpdateStatus("主下载失败,转备用..."); } var domain = new Uri("https://" + OssEndpoint).Host; @@ -1048,14 +1170,21 @@ namespace CheckDownload using (var remote = await response.Content.ReadAsStreamAsync()) using (var localFile = File.Create(localPath)) { - await remote.CopyToAsync(localFile); + using (var cts = new CancellationTokenSource(DownloadStreamTimeoutMs)) + { + await remote.CopyToAsync(localFile, 81920, cts.Token); + } } } return true; } - catch (Exception) + catch (HttpRequestException) { - UpdateStatus($"备用方案用IP {ip} 下载失败"); + UpdateStatus($"IP下载失败: {ip}"); + } + catch (OperationCanceledException) + { + UpdateStatus($"IP下载失败: {ip}"); } } return false; @@ -1130,9 +1259,9 @@ namespace CheckDownload return authUrl; } - catch (Exception ex) + catch { - UpdateStatus($"生成鉴权URL失败: {ex.Message}"); + UpdateStatus("生成AuthUrl失败"); return $"{url}/{file}"; } } @@ -1184,18 +1313,18 @@ namespace CheckDownload { try { - UpdateStatus("尝试从123盘下载MD5文件..."); + UpdateStatus("123盘下载MD5..."); if (await DownloadFromOneDrive($"http://{OneDriveMainDomain}{OneDrivePath}", fileName, localPath)) { return true; } - UpdateStatus("123盘下载失败,尝试阿里云OSS备用方案..."); + UpdateStatus("123盘失败,转OSS..."); return await DownloadFileWithFallback(fileName, localPath); } catch (Exception ex) { - UpdateStatus($"所有下载方式都失败: {ex.Message}"); + UpdateStatus("所有下载方式均失败"); return false; } } @@ -1215,7 +1344,7 @@ namespace CheckDownload if (Directory.Exists(tempPath)) { - UpdateStatus("清理临时文件..."); + UpdateStatus("清理Temp..."); Directory.Delete(tempPath, true); } } @@ -1343,7 +1472,7 @@ namespace CheckDownload return currentDir; } - catch (Exception ex) + catch { return currentDir; } diff --git a/packages.config b/packages.config index 2c4649d..50677d8 100644 --- a/packages.config +++ b/packages.config @@ -3,16 +3,17 @@ - + - + + - - + + \ No newline at end of file