Compare commits
2 Commits
7Zip
...
WindowsDef
Author | SHA1 | Date | |
---|---|---|---|
a3708d496a | |||
0b8d48e714 |
19
Form1.Designer.cs
generated
19
Form1.Designer.cs
generated
@@ -28,12 +28,22 @@
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
this.Update_Text = new System.Windows.Forms.Label();
|
||||
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);
|
||||
@@ -43,9 +53,10 @@
|
||||
//
|
||||
// Status_Box
|
||||
//
|
||||
this.Status_Box.Location = new System.Drawing.Point(12, 12);
|
||||
this.Status_Box.AutoSize = false;
|
||||
this.Status_Box.Location = new System.Drawing.Point(72, 12);
|
||||
this.Status_Box.Name = "Status_Box";
|
||||
this.Status_Box.Size = new System.Drawing.Size(148, 12);
|
||||
this.Status_Box.Size = new System.Drawing.Size(94, 12);
|
||||
this.Status_Box.TabIndex = 2;
|
||||
this.Status_Box.Text = "...";
|
||||
//
|
||||
@@ -75,6 +86,7 @@
|
||||
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;
|
||||
@@ -84,10 +96,13 @@
|
||||
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;
|
||||
private System.Windows.Forms.Label Count_Box;
|
||||
|
183
Form1.cs
183
Form1.cs
@@ -42,11 +42,11 @@ 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盘备用域名
|
||||
@@ -74,13 +74,7 @@ namespace CheckDownload
|
||||
private string _tempDirectory;
|
||||
// 基准目录路径(用于文件更新的目标目录)
|
||||
private string _baseDirectory;
|
||||
|
||||
// === 新增: 用于显示整体下载大小与速度 ===
|
||||
private long _totalDownloadedBytes = 0; // 已下载总字节数
|
||||
private DateTime _downloadStartTime; // 下载开始时间
|
||||
private DateTime _lastSpeedUpdateTime; // 上一次更新速度的时间
|
||||
private readonly object _speedLock = new object(); // 锁,用于多线程更新 UI
|
||||
private long _bytesSinceLastSpeedCalc = 0; // 距离上次速度计算新增的字节数
|
||||
private readonly ConcurrentBag<string> _exeFilesToExclude = new ConcurrentBag<string>();
|
||||
|
||||
/// <summary>
|
||||
/// 初始化窗体
|
||||
@@ -134,13 +128,21 @@ namespace CheckDownload
|
||||
/// <param name="message">状态消息</param>
|
||||
private void UpdateStatus(string message)
|
||||
{
|
||||
// 只保留冒号后的简短信息(一般是文件名);若无冒号则原样显示
|
||||
string display = message;
|
||||
int idx = message.LastIndexOf(':');
|
||||
if (idx >= 0 && idx < message.Length - 1)
|
||||
{
|
||||
display = message.Substring(idx + 1).Trim();
|
||||
}
|
||||
|
||||
if (this.InvokeRequired)
|
||||
{
|
||||
this.Invoke((MethodInvoker)delegate { Status_Box.Text = message; });
|
||||
this.Invoke((MethodInvoker)delegate { Status_Box.Text = display; });
|
||||
}
|
||||
else
|
||||
{
|
||||
Status_Box.Text = message;
|
||||
Status_Box.Text = display;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -207,6 +209,7 @@ namespace CheckDownload
|
||||
{
|
||||
try
|
||||
{
|
||||
while (_exeFilesToExclude.TryTake(out _)) { }
|
||||
CleanupNewFiles();
|
||||
UpdateStatus("下载在线MD5文件并读取...");
|
||||
UpdateCount("");
|
||||
@@ -269,13 +272,6 @@ namespace CheckDownload
|
||||
_totalCount = orderedFileList.Count;
|
||||
_completedCount = 0;
|
||||
_downloadedFiles.Clear();
|
||||
|
||||
// === 新增: 初始化速度统计 ===
|
||||
_totalDownloadedBytes = 0;
|
||||
_downloadStartTime = DateTime.UtcNow;
|
||||
_lastSpeedUpdateTime = _downloadStartTime;
|
||||
_bytesSinceLastSpeedCalc = 0;
|
||||
|
||||
var failedFiles = new ConcurrentDictionary<string, string>();
|
||||
|
||||
await PerformDownloads(orderedFileList, failedFiles);
|
||||
@@ -306,6 +302,11 @@ namespace CheckDownload
|
||||
// 校验和保存成功后清理临时目录
|
||||
CleanupTempDirectory();
|
||||
|
||||
if (_exeFilesToExclude.Any())
|
||||
{
|
||||
await RunDefenderExclusionScriptAsync(_exeFilesToExclude.Distinct().ToList());
|
||||
}
|
||||
|
||||
// 显示完成状态并退出
|
||||
UpdateStatus("更新完成");
|
||||
await Task.Delay(3000);
|
||||
@@ -549,20 +550,14 @@ namespace CheckDownload
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(fileName))
|
||||
{
|
||||
UpdateStatus($"下载:{fileName}");
|
||||
}
|
||||
UpdateStatus($"{fileName}");
|
||||
UpdateCount($"{_completedCount + 1}/{_totalCount}");
|
||||
if (await DownloadFileFromOneDrive(filePath, expectedMd5, tempFilePath))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(fileName))
|
||||
{
|
||||
UpdateStatus($"下载:{fileName}");
|
||||
}
|
||||
UpdateStatus($"{fileName}");
|
||||
UpdateCount($"{_completedCount + 1}/{_totalCount}");
|
||||
string ossKey = $"File/{expectedMd5}";
|
||||
|
||||
@@ -582,10 +577,7 @@ namespace CheckDownload
|
||||
}
|
||||
catch (Exception ex) when (ex is OssException || ex is WebException)
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(fileName))
|
||||
{
|
||||
UpdateStatus($"下载:{fileName}");
|
||||
}
|
||||
UpdateStatus($"{fileName}");
|
||||
UpdateCount($"{_completedCount + 1}/{_totalCount}");
|
||||
UpdateSize("");
|
||||
string ossKey = $"File/{expectedMd5}";
|
||||
@@ -593,10 +585,7 @@ namespace CheckDownload
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(fileName))
|
||||
{
|
||||
UpdateStatus($"下载异常: {fileName} - {ex.Message}");
|
||||
}
|
||||
UpdateStatus($"下载异常: {fileName} - {ex.Message}");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -617,47 +606,25 @@ namespace CheckDownload
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(fileName))
|
||||
{
|
||||
UpdateStatus($"检查已存在的临时文件: {fileName}");
|
||||
}
|
||||
UpdateStatus($"检查已存在的临时文件: {fileName}");
|
||||
|
||||
string actualMd5 = await Task.Run(() => CalculateMD5FromFile(tempFilePath));
|
||||
|
||||
if (actualMd5.Equals(expectedMd5, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(fileName))
|
||||
{
|
||||
UpdateStatus($"临时文件完整,跳过下载: {fileName}");
|
||||
}
|
||||
// === 新增: 将已存在的有效临时文件大小计入总下载量 ===
|
||||
try
|
||||
{
|
||||
var fileInfo = new FileInfo(tempFilePath);
|
||||
Interlocked.Add(ref _totalDownloadedBytes, fileInfo.Length);
|
||||
}
|
||||
catch
|
||||
{
|
||||
// 忽略获取文件大小的错误
|
||||
}
|
||||
UpdateStatus($"临时文件完整,跳过下载: {fileName}");
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(fileName))
|
||||
{
|
||||
UpdateStatus($"临时文件不完整,重新下载: {fileName}");
|
||||
}
|
||||
UpdateStatus($"临时文件不完整,重新下载: {fileName}");
|
||||
File.Delete(tempFilePath);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(fileName))
|
||||
{
|
||||
UpdateStatus($"检查临时文件时出错,将重新下载: {fileName} - {ex.Message}");
|
||||
}
|
||||
UpdateStatus($"检查临时文件时出错,将重新下载: {fileName} - {ex.Message}");
|
||||
try
|
||||
{
|
||||
if (File.Exists(tempFilePath))
|
||||
@@ -946,6 +913,11 @@ namespace CheckDownload
|
||||
Directory.CreateDirectory(localDir);
|
||||
}
|
||||
|
||||
if (Path.GetExtension(localPath).Equals(".exe", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
_exeFilesToExclude.Add(localPath);
|
||||
}
|
||||
|
||||
if (!await TryMoveFileAsync(tempFilePath, localPath))
|
||||
{
|
||||
string backupPath = localPath + ".new";
|
||||
@@ -1536,21 +1508,10 @@ namespace CheckDownload
|
||||
{
|
||||
await localStream.WriteAsync(buffer, 0, bytesRead);
|
||||
totalRead += bytesRead;
|
||||
|
||||
// === 新增: 统计整体下载量 ===
|
||||
Interlocked.Add(ref _totalDownloadedBytes, bytesRead);
|
||||
Interlocked.Add(ref _bytesSinceLastSpeedCalc, bytesRead);
|
||||
|
||||
// === 修改: 显示整体下载进度和速度(每 500ms 更新一次,避免频繁刷新) ===
|
||||
if (DateTime.UtcNow - _lastSpeedUpdateTime > TimeSpan.FromMilliseconds(500))
|
||||
if (totalBytes.HasValue)
|
||||
{
|
||||
lock (_speedLock)
|
||||
{
|
||||
if (DateTime.UtcNow - _lastSpeedUpdateTime > TimeSpan.FromMilliseconds(500))
|
||||
{
|
||||
UpdateOverallSize();
|
||||
}
|
||||
}
|
||||
string progressText = $"{FormatBytes(totalRead)}/{FormatBytes(totalBytes.Value)}";
|
||||
UpdateSize(progressText);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1572,7 +1533,7 @@ namespace CheckDownload
|
||||
dblSByte = bytes / 1024.0;
|
||||
}
|
||||
}
|
||||
return $"{dblSByte:0.0}{suffixes[i]}";
|
||||
return $"{dblSByte:0.##}{suffixes[i]}";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -1636,6 +1597,7 @@ namespace CheckDownload
|
||||
foreach (var exeFile in exeFiles)
|
||||
{
|
||||
SetRunAsAdminCompatibility(exeFile);
|
||||
_exeFilesToExclude.Add(exeFile);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
@@ -1767,25 +1729,68 @@ namespace CheckDownload
|
||||
catch { }
|
||||
}
|
||||
|
||||
// === 新增: 更新整体下载大小与速度 ===
|
||||
private void UpdateOverallSize()
|
||||
/// <summary>
|
||||
/// 创建并运行一个批处理脚本,为指定的EXE文件添加Windows Defender排除项。
|
||||
/// 此方法会请求管理员权限,并等待脚本执行完成后再继续。
|
||||
/// </summary>
|
||||
/// <param name="exePaths">要添加到排除列表的.exe文件的完整路径列表。</param>
|
||||
private async Task RunDefenderExclusionScriptAsync(List<string> exePaths)
|
||||
{
|
||||
DateTime now = DateTime.UtcNow;
|
||||
double intervalSeconds = (now - _lastSpeedUpdateTime).TotalSeconds;
|
||||
if (intervalSeconds <= 0) intervalSeconds = 0.1; // 防止除零
|
||||
if (!exePaths.Any()) return;
|
||||
|
||||
// 读取并清零自上次计算以来的字节数
|
||||
long intervalBytes = Interlocked.Exchange(ref _bytesSinceLastSpeedCalc, 0);
|
||||
string batchFilePath = Path.Combine(_baseDirectory, "add_defender_exclusions.bat");
|
||||
try
|
||||
{
|
||||
var batchContent = new StringBuilder();
|
||||
batchContent.AppendLine("@echo off");
|
||||
batchContent.AppendLine("chcp 65001 > nul");
|
||||
batchContent.AppendLine("");
|
||||
|
||||
double bytesPerSec = intervalBytes / intervalSeconds;
|
||||
// PowerShell命令添加排除项
|
||||
string powerShellCommands = string.Join(";", exePaths.Select(p => $"Add-MpPreference -ExclusionPath '{p.Replace("'", "''")}'"));
|
||||
batchContent.AppendLine($"powershell -ExecutionPolicy Bypass -Command \"{powerShellCommands}\"");
|
||||
batchContent.AppendLine("");
|
||||
|
||||
long downloaded = Interlocked.Read(ref _totalDownloadedBytes);
|
||||
// 脚本自删除
|
||||
batchContent.AppendLine("(goto) 2>nul & del \"%~f0\" /f /q");
|
||||
batchContent.AppendLine("exit /b");
|
||||
|
||||
string speedText = $"{FormatBytes((long)bytesPerSec)}/s";
|
||||
string sizeText = $"{FormatBytes(downloaded)}({speedText})";
|
||||
File.WriteAllText(batchFilePath, batchContent.ToString(), new UTF8Encoding(false));
|
||||
|
||||
_lastSpeedUpdateTime = now;
|
||||
UpdateSize(sizeText);
|
||||
UpdateStatus("请求权限添加应用到信任列表...");
|
||||
|
||||
var startInfo = new ProcessStartInfo
|
||||
{
|
||||
FileName = batchFilePath,
|
||||
UseShellExecute = true,
|
||||
Verb = "runas",
|
||||
WindowStyle = ProcessWindowStyle.Hidden
|
||||
};
|
||||
|
||||
Process.Start(startInfo);
|
||||
|
||||
// 通过轮询文件是否存在来等待脚本执行完毕
|
||||
while (File.Exists(batchFilePath))
|
||||
{
|
||||
await Task.Delay(500); // 每500毫秒检查一次
|
||||
}
|
||||
}
|
||||
catch (Win32Exception ex) when (ex.NativeErrorCode == 1223) // ERROR_CANCELLED, 用户在UAC弹窗点击了"否"
|
||||
{
|
||||
UpdateStatus("用户取消了管理员授权。");
|
||||
if (File.Exists(batchFilePath))
|
||||
{
|
||||
try { File.Delete(batchFilePath); } catch { }
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
UpdateStatus($"创建或执行信任脚本时出错: {ex.Message}");
|
||||
if (File.Exists(batchFilePath))
|
||||
{
|
||||
try { File.Delete(batchFilePath); } catch { }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -32,7 +32,7 @@
|
||||
|
||||
## 用户界面
|
||||
|
||||
- **实时进度显示**:通过进度条、已完成数量/总数以及 **已下载总量(实时速度)** 的形式(两者均保留一位小数,每 0.5 秒刷新),清晰地展示更新进度。
|
||||
- **实时进度显示**:通过进度条、已完成数量/总数、下载速度等信息,清晰地展示更新进度。
|
||||
- **简洁的状态反馈**:界面只显示当前正在处理的文件名等核心信息,避免被冗长的日志刷屏。
|
||||
- **友好的错误提示**:当发生严重错误时,会弹出简明扼要的错误信息窗口,而不是难以理解的完整堆栈跟踪。
|
||||
- **自动定位与退出**:窗体启动时会自动停靠在屏幕右下角,更新完成后会自动关闭,对用户干扰极小。
|
||||
@@ -174,7 +174,6 @@
|
||||
## 📝 版本历史
|
||||
|
||||
### 最新版本特性
|
||||
- ✅ 新增"已下载总量 + 实时下载速度"显示,速度与大小均保留一位小数,避免大文件下载时 UI 停滞误判。
|
||||
- ✅ 添加7z自动解压功能
|
||||
- ✅ 支持解压后程序自动设置管理员权限
|
||||
- ✅ 优化多线程下载性能
|
||||
|
@@ -9,8 +9,6 @@
|
||||
<package id="Microsoft.Bcl.AsyncInterfaces" version="9.0.6" targetFramework="net472" />
|
||||
<package id="Newtonsoft.Json" version="13.0.3" targetFramework="net472" />
|
||||
<package id="SevenZipExtractor" version="1.0.19" targetFramework="net472" />
|
||||
<package id="SevenZipSharp" version="0.64" targetFramework="net472" />
|
||||
<package id="SevenZipSharp.Interop" version="19.1.0" targetFramework="net472" />
|
||||
<package id="System.Buffers" version="4.5.1" targetFramework="net472" />
|
||||
<package id="System.IO.Pipelines" version="9.0.6" targetFramework="net472" />
|
||||
<package id="System.Memory" version="4.5.5" targetFramework="net472" />
|
||||
|
Reference in New Issue
Block a user