Compare commits
No commits in common. "CheckDownload" and "CreateMd5Json" have entirely different histories.
CheckDownl
...
CreateMd5J
197
Form1.Designer.cs
generated
197
Form1.Designer.cs
generated
@ -1,6 +1,6 @@
|
||||
namespace CheckDownload
|
||||
namespace MD5Create
|
||||
{
|
||||
partial class Update
|
||||
partial class MD5Create
|
||||
{
|
||||
/// <summary>
|
||||
/// 必需的设计器变量。
|
||||
@ -28,53 +28,158 @@
|
||||
/// </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.Path_Text = new System.Windows.Forms.Label();
|
||||
this.Path1_Box = new System.Windows.Forms.TextBox();
|
||||
this.Choose1_Button = new System.Windows.Forms.Button();
|
||||
this.folderBrowserDialog1 = new System.Windows.Forms.FolderBrowserDialog();
|
||||
this.label1 = new System.Windows.Forms.Label();
|
||||
this.label2 = new System.Windows.Forms.Label();
|
||||
this.progressBar1 = new System.Windows.Forms.ProgressBar();
|
||||
this.Start_Button = new System.Windows.Forms.Button();
|
||||
this.Process_Text = new System.Windows.Forms.Label();
|
||||
this.Process_Box = new System.Windows.Forms.RichTextBox();
|
||||
this.Exit_Button = new System.Windows.Forms.Button();
|
||||
this.label3 = new System.Windows.Forms.Label();
|
||||
this.textBox1 = new System.Windows.Forms.TextBox();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// Update_Text
|
||||
// Path_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 = "更新状态:";
|
||||
this.Path_Text.AutoSize = true;
|
||||
this.Path_Text.Location = new System.Drawing.Point(12, 15);
|
||||
this.Path_Text.Name = "Path_Text";
|
||||
this.Path_Text.Size = new System.Drawing.Size(35, 12);
|
||||
this.Path_Text.TabIndex = 0;
|
||||
this.Path_Text.Text = "路径:";
|
||||
//
|
||||
// Update_Pro
|
||||
// Path1_Box
|
||||
//
|
||||
this.Update_Pro.Location = new System.Drawing.Point(12, 36);
|
||||
this.Update_Pro.Name = "Update_Pro";
|
||||
this.Update_Pro.Size = new System.Drawing.Size(339, 23);
|
||||
this.Update_Pro.TabIndex = 1;
|
||||
this.Path1_Box.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
|
||||
| System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.Path1_Box.Location = new System.Drawing.Point(49, 12);
|
||||
this.Path1_Box.Name = "Path1_Box";
|
||||
this.Path1_Box.ReadOnly = true;
|
||||
this.Path1_Box.Size = new System.Drawing.Size(319, 21);
|
||||
this.Path1_Box.TabIndex = 1;
|
||||
//
|
||||
// Status_Box
|
||||
// Choose1_Button
|
||||
//
|
||||
this.Status_Box.AutoSize = true;
|
||||
this.Status_Box.Location = new System.Drawing.Point(72, 12);
|
||||
this.Status_Box.Name = "Status_Box";
|
||||
this.Status_Box.Size = new System.Drawing.Size(23, 12);
|
||||
this.Status_Box.TabIndex = 2;
|
||||
this.Status_Box.Text = "...";
|
||||
this.Choose1_Button.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.Choose1_Button.Location = new System.Drawing.Point(374, 12);
|
||||
this.Choose1_Button.Name = "Choose1_Button";
|
||||
this.Choose1_Button.Size = new System.Drawing.Size(32, 21);
|
||||
this.Choose1_Button.TabIndex = 2;
|
||||
this.Choose1_Button.Text = "...";
|
||||
this.Choose1_Button.UseVisualStyleBackColor = true;
|
||||
this.Choose1_Button.Click += new System.EventHandler(this.Choose1_Button_Click);
|
||||
//
|
||||
// Update
|
||||
// label1
|
||||
//
|
||||
this.label1.AutoSize = true;
|
||||
this.label1.Location = new System.Drawing.Point(12, 53);
|
||||
this.label1.Name = "label1";
|
||||
this.label1.Size = new System.Drawing.Size(0, 12);
|
||||
this.label1.TabIndex = 3;
|
||||
//
|
||||
// label2
|
||||
//
|
||||
this.label2.AutoSize = true;
|
||||
this.label2.Location = new System.Drawing.Point(12, 79);
|
||||
this.label2.Name = "label2";
|
||||
this.label2.Size = new System.Drawing.Size(35, 12);
|
||||
this.label2.TabIndex = 4;
|
||||
this.label2.Text = "进度:";
|
||||
//
|
||||
// progressBar1
|
||||
//
|
||||
this.progressBar1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
|
||||
| System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.progressBar1.Location = new System.Drawing.Point(49, 76);
|
||||
this.progressBar1.Name = "progressBar1";
|
||||
this.progressBar1.Size = new System.Drawing.Size(357, 23);
|
||||
this.progressBar1.TabIndex = 5;
|
||||
//
|
||||
// Start_Button
|
||||
//
|
||||
this.Start_Button.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
|
||||
this.Start_Button.Location = new System.Drawing.Point(12, 322);
|
||||
this.Start_Button.Name = "Start_Button";
|
||||
this.Start_Button.Size = new System.Drawing.Size(75, 23);
|
||||
this.Start_Button.TabIndex = 6;
|
||||
this.Start_Button.Text = "开始";
|
||||
this.Start_Button.UseVisualStyleBackColor = true;
|
||||
this.Start_Button.Click += new System.EventHandler(this.Start_Button_Click);
|
||||
//
|
||||
// Process_Text
|
||||
//
|
||||
this.Process_Text.AutoSize = true;
|
||||
this.Process_Text.Location = new System.Drawing.Point(12, 47);
|
||||
this.Process_Text.Name = "Process_Text";
|
||||
this.Process_Text.Size = new System.Drawing.Size(35, 12);
|
||||
this.Process_Text.TabIndex = 7;
|
||||
this.Process_Text.Text = "版本:";
|
||||
//
|
||||
// Process_Box
|
||||
//
|
||||
this.Process_Box.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
|
||||
| System.Windows.Forms.AnchorStyles.Left)
|
||||
| System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.Process_Box.Location = new System.Drawing.Point(49, 111);
|
||||
this.Process_Box.Name = "Process_Box";
|
||||
this.Process_Box.Size = new System.Drawing.Size(357, 203);
|
||||
this.Process_Box.TabIndex = 8;
|
||||
this.Process_Box.Text = "";
|
||||
//
|
||||
// Exit_Button
|
||||
//
|
||||
this.Exit_Button.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.Exit_Button.Location = new System.Drawing.Point(331, 322);
|
||||
this.Exit_Button.Name = "Exit_Button";
|
||||
this.Exit_Button.Size = new System.Drawing.Size(75, 23);
|
||||
this.Exit_Button.TabIndex = 9;
|
||||
this.Exit_Button.Text = "退出";
|
||||
this.Exit_Button.UseVisualStyleBackColor = true;
|
||||
this.Exit_Button.Click += new System.EventHandler(this.Exit_Button_Click);
|
||||
//
|
||||
// label3
|
||||
//
|
||||
this.label3.AutoSize = true;
|
||||
this.label3.Location = new System.Drawing.Point(12, 111);
|
||||
this.label3.Name = "label3";
|
||||
this.label3.Size = new System.Drawing.Size(35, 12);
|
||||
this.label3.TabIndex = 10;
|
||||
this.label3.Text = "执行:";
|
||||
//
|
||||
// textBox1
|
||||
//
|
||||
this.textBox1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
|
||||
| System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.textBox1.ForeColor = System.Drawing.SystemColors.WindowText;
|
||||
this.textBox1.Location = new System.Drawing.Point(49, 42);
|
||||
this.textBox1.Name = "textBox1";
|
||||
this.textBox1.Size = new System.Drawing.Size(357, 21);
|
||||
this.textBox1.TabIndex = 11;
|
||||
this.textBox1.Text = "1.0.0";
|
||||
//
|
||||
// MD5Create
|
||||
//
|
||||
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.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;
|
||||
this.Name = "Update";
|
||||
this.ShowInTaskbar = false;
|
||||
this.Text = "自动更新";
|
||||
this.TopMost = true;
|
||||
this.Load += new System.EventHandler(this.Update_Load);
|
||||
this.ClientSize = new System.Drawing.Size(418, 357);
|
||||
this.Controls.Add(this.textBox1);
|
||||
this.Controls.Add(this.label3);
|
||||
this.Controls.Add(this.Exit_Button);
|
||||
this.Controls.Add(this.Process_Box);
|
||||
this.Controls.Add(this.Process_Text);
|
||||
this.Controls.Add(this.Start_Button);
|
||||
this.Controls.Add(this.progressBar1);
|
||||
this.Controls.Add(this.label2);
|
||||
this.Controls.Add(this.label1);
|
||||
this.Controls.Add(this.Choose1_Button);
|
||||
this.Controls.Add(this.Path1_Box);
|
||||
this.Controls.Add(this.Path_Text);
|
||||
this.Name = "MD5Create";
|
||||
this.Text = "MD5Create";
|
||||
this.ResumeLayout(false);
|
||||
this.PerformLayout();
|
||||
|
||||
@ -82,9 +187,19 @@
|
||||
|
||||
#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 Path_Text;
|
||||
private System.Windows.Forms.TextBox Path1_Box;
|
||||
private System.Windows.Forms.Button Choose1_Button;
|
||||
private System.Windows.Forms.FolderBrowserDialog folderBrowserDialog1;
|
||||
private System.Windows.Forms.Label label1;
|
||||
private System.Windows.Forms.Label label2;
|
||||
private System.Windows.Forms.ProgressBar progressBar1;
|
||||
private System.Windows.Forms.Button Start_Button;
|
||||
private System.Windows.Forms.Label Process_Text;
|
||||
private System.Windows.Forms.RichTextBox Process_Box;
|
||||
private System.Windows.Forms.Button Exit_Button;
|
||||
private System.Windows.Forms.Label label3;
|
||||
private System.Windows.Forms.TextBox textBox1;
|
||||
}
|
||||
}
|
||||
|
||||
|
608
Form1.cs
608
Form1.cs
@ -2,521 +2,241 @@
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Data;
|
||||
using System.Diagnostics;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Drawing;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
using Aliyun.OSS;
|
||||
using Aliyun.OSS.Common;
|
||||
using System.Xml;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
namespace CheckDownload
|
||||
namespace MD5Create
|
||||
{
|
||||
public partial class Update : Form
|
||||
public partial class MD5Create : Form
|
||||
{
|
||||
// MD5文件名称
|
||||
private const string Md5File = "md5.json";
|
||||
// 阿里云OSS访问地址
|
||||
private const string OssEndpoint = "oss-cn-hongkong.aliyuncs.com";
|
||||
// 阿里云OSS存储空间名称
|
||||
private const string OssBucketName = "sxho-hk";
|
||||
// 阿里云OSS访问密钥ID
|
||||
private const string OssAccessKeyId = "LTAI5tBc8BgooVrHrzfEeg1q";
|
||||
// 阿里云OSS访问密钥Secret
|
||||
private const string OssAccessKeySecret = "nMvSp0UqzodTzKImuAMK1a1bkSks5O";
|
||||
// 用于存储下载的文件数据
|
||||
private Dictionary<string, (byte[] Data, string ExpectedMd5)> _downloadedFiles = new Dictionary<string, (byte[], string)>();
|
||||
// 已完成的下载数量
|
||||
private int _completedCount = 0;
|
||||
// 总下载数量
|
||||
private int _totalCount = 0;
|
||||
|
||||
// 初始化窗体
|
||||
public Update()
|
||||
public MD5Create()
|
||||
{
|
||||
InitializeComponent();
|
||||
ConfigureProgressBar();
|
||||
// Initialize progress bar
|
||||
progressBar1.Minimum = 0;
|
||||
progressBar1.Maximum = 100;
|
||||
progressBar1.Value = 0;
|
||||
progressBar1.Step = 1;
|
||||
}
|
||||
|
||||
// 配置进度条
|
||||
private void ConfigureProgressBar()
|
||||
// 程序启动前检查目录和版本号
|
||||
private void Start_Button_Click(object sender, EventArgs e)
|
||||
{
|
||||
Update_Pro.Minimum = 0;
|
||||
Update_Pro.Maximum = 100;
|
||||
Update_Pro.Value = 0;
|
||||
Update_Pro.Step = 1;
|
||||
}
|
||||
|
||||
private void UpdateProgressValue(int percentage)
|
||||
if (string.IsNullOrWhiteSpace(Path1_Box.Text))
|
||||
{
|
||||
if (percentage < 0) percentage = 0;
|
||||
if (percentage > 100) percentage = 100;
|
||||
|
||||
if (this.InvokeRequired)
|
||||
{
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateStatus(string message)
|
||||
{
|
||||
if (this.InvokeRequired)
|
||||
{
|
||||
this.Invoke((MethodInvoker)delegate { Status_Box.Text = message; });
|
||||
}
|
||||
else
|
||||
{
|
||||
Status_Box.Text = message;
|
||||
}
|
||||
}
|
||||
|
||||
public async void Update_Load(object sender, EventArgs e)
|
||||
{
|
||||
PositionFormToBottomRight();
|
||||
await UpdateFile();
|
||||
}
|
||||
|
||||
private void PositionFormToBottomRight()
|
||||
{
|
||||
Rectangle workingArea = Screen.GetWorkingArea(this);
|
||||
this.Location = new Point(workingArea.Right - this.Width, workingArea.Bottom - this.Height);
|
||||
}
|
||||
|
||||
private async Task UpdateFile()
|
||||
{
|
||||
try
|
||||
{
|
||||
const int totalSteps = 4;
|
||||
int currentStep = 0;
|
||||
|
||||
UpdateStatus("下载在线MD5文件并读取...");
|
||||
OssClient client = new OssClient(OssEndpoint, OssAccessKeyId, OssAccessKeySecret);
|
||||
var onlineData = ReadOnlineMd5File(client, OssBucketName, Md5File);
|
||||
if (!ValidateOnlineData(onlineData.Version, onlineData.Md5, onlineData.Data))
|
||||
{
|
||||
UpdateStatus("在线MD5文件无效");
|
||||
await Task.Delay(3000);
|
||||
this.Close();
|
||||
MessageBox.Show("请先选择目录!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
||||
return;
|
||||
}
|
||||
|
||||
UpdateStatus("比较本地和在线MD5文件...");
|
||||
var compareResult = CompareMd5Data(onlineData.Data);
|
||||
if (compareResult.Count == 0)
|
||||
if (string.IsNullOrWhiteSpace(textBox1.Text))
|
||||
{
|
||||
UpdateStatus("所有文件都是最新的,无需更新");
|
||||
UpdateProgressValue(100);
|
||||
await Task.Delay(2000);
|
||||
this.Close();
|
||||
MessageBox.Show("请输入版本号!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
||||
return;
|
||||
}
|
||||
|
||||
UpdateStatus("下载并验证文件...");
|
||||
_totalCount = compareResult.Count;
|
||||
await DownloadAndVerifyFiles(compareResult);
|
||||
UpdateProgressValue(100);
|
||||
// Reset progress bar
|
||||
progressBar1.Value = 0;
|
||||
|
||||
UpdateStatus("更新完成");
|
||||
await Task.Delay(1000);
|
||||
GenerateMD5Json(Path1_Box.Text);
|
||||
}
|
||||
|
||||
private void Choose1_Button_Click(object sender, EventArgs e)
|
||||
{
|
||||
folderBrowserDialog1.Description = "请选择文件夹";
|
||||
folderBrowserDialog1.RootFolder = Environment.SpecialFolder.MyComputer;
|
||||
folderBrowserDialog1.ShowNewFolderButton = true;
|
||||
if (Path1_Box.Text.Length > 0) folderBrowserDialog1.SelectedPath = Path1_Box.Text;
|
||||
if (folderBrowserDialog1.ShowDialog() == DialogResult.OK)
|
||||
{
|
||||
Path1_Box.Text = folderBrowserDialog1.SelectedPath;
|
||||
}
|
||||
}
|
||||
|
||||
private void Exit_Button_Click(object sender, EventArgs e)
|
||||
{
|
||||
this.Close();
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
||||
// 计算 MD5 的值
|
||||
private string MD5Generation(string filePath)
|
||||
{
|
||||
UpdateStatus($"更新失败: {ex.Message}");
|
||||
await Task.Delay(3000);
|
||||
this.Close();
|
||||
using (var md5 = MD5.Create())
|
||||
using (var stream = File.OpenRead(filePath))
|
||||
{
|
||||
byte[] hash = md5.ComputeHash(stream);
|
||||
return BitConverter.ToString(hash).Replace("-", "").ToLower();
|
||||
}
|
||||
}
|
||||
|
||||
private (string Version, string Md5, JObject Data) ReadOnlineMd5File(OssClient client, string bucket, string key)
|
||||
// 获取目录中文件总数(用于进度计算)
|
||||
private int GetTotalFileCount(string directoryPath, string excludeFolder)
|
||||
{
|
||||
try
|
||||
{
|
||||
var obj = client.GetObject(bucket, key);
|
||||
using (var reader = new StreamReader(obj.Content))
|
||||
{
|
||||
string json = reader.ReadToEnd();
|
||||
var parsed = JObject.Parse(json);
|
||||
string version = parsed["version"]?.ToString();
|
||||
var data = (JObject)parsed["data"];
|
||||
string jsonMd5 = CalculateMD5(json);
|
||||
return (version, jsonMd5, data);
|
||||
}
|
||||
}
|
||||
catch (Exception ex) when (ex is OssException || ex is JsonException)
|
||||
{
|
||||
UpdateStatus($"读取在线MD5文件失败: {ex.Message}");
|
||||
return (null, null, null);
|
||||
}
|
||||
}
|
||||
int count = Directory.GetFiles(directoryPath).Length;
|
||||
|
||||
private bool ValidateOnlineData(string version, string md5, JObject data)
|
||||
foreach (var dir in Directory.GetDirectories(directoryPath))
|
||||
{
|
||||
if (string.IsNullOrEmpty(version) || string.IsNullOrEmpty(md5) || data == null)
|
||||
{
|
||||
UpdateStatus("在线MD5文件无效");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private Dictionary<string, string> CompareMd5Data(JObject onlineData, string currentPath = "")
|
||||
{
|
||||
var differences = new Dictionary<string, string>();
|
||||
|
||||
foreach (var onlineProperty in onlineData.Properties())
|
||||
{
|
||||
string key = onlineProperty.Name;
|
||||
JToken onlineValue = onlineProperty.Value;
|
||||
string fullPath = string.IsNullOrEmpty(currentPath) ? key : $"{currentPath}/{key}";
|
||||
|
||||
if (onlineValue.Type == JTokenType.String)
|
||||
{
|
||||
string expectedMd5 = onlineValue.ToString();
|
||||
if (!File.Exists(fullPath))
|
||||
{
|
||||
if (!differences.ContainsKey(fullPath))
|
||||
{
|
||||
differences[fullPath] = expectedMd5;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
string localMd5 = CalculateMD5(File.ReadAllBytes(fullPath));
|
||||
if (localMd5 != expectedMd5)
|
||||
{
|
||||
if (!differences.ContainsKey(fullPath))
|
||||
{
|
||||
differences[fullPath] = expectedMd5;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (onlineValue.Type == JTokenType.Object)
|
||||
{
|
||||
var subDifferences = CompareMd5Data((JObject)onlineValue, fullPath);
|
||||
foreach (var diff in subDifferences)
|
||||
{
|
||||
if (!differences.ContainsKey(diff.Key))
|
||||
{
|
||||
differences[diff.Key] = diff.Value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return differences;
|
||||
}
|
||||
|
||||
private async Task DownloadAndVerifyFiles(Dictionary<string, string> fileList)
|
||||
{
|
||||
try
|
||||
{
|
||||
OssClient client = new OssClient(OssEndpoint, OssAccessKeyId, OssAccessKeySecret);
|
||||
_totalCount = fileList.Count;
|
||||
_completedCount = 0;
|
||||
_downloadedFiles.Clear();
|
||||
|
||||
var options = new ParallelOptions { MaxDegreeOfParallelism = 4 };
|
||||
|
||||
await Task.Run(() =>
|
||||
{
|
||||
Parallel.ForEach(fileList, options, (file, state) =>
|
||||
{
|
||||
string filePath = file.Key;
|
||||
string expectedMd5 = file.Value;
|
||||
|
||||
try
|
||||
{
|
||||
string ossKey = $"File/{expectedMd5}";
|
||||
var obj = client.GetObject(OssBucketName, ossKey);
|
||||
using (var memoryStream = new MemoryStream())
|
||||
{
|
||||
obj.Content.CopyTo(memoryStream);
|
||||
byte[] fileData = memoryStream.ToArray();
|
||||
|
||||
lock (_downloadedFiles)
|
||||
{
|
||||
_downloadedFiles[filePath] = (fileData, expectedMd5);
|
||||
}
|
||||
|
||||
Interlocked.Increment(ref _completedCount);
|
||||
int progress = (int)((double)_completedCount / _totalCount * 95);
|
||||
UpdateProgressValue(progress);
|
||||
UpdateStatus($"已下载 {_completedCount}/{_totalCount}");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
UpdateStatus($"下载文件 {filePath} 失败: {ex.Message}");
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
if (_downloadedFiles.Count != fileList.Count)
|
||||
{
|
||||
throw new Exception($"部分文件下载失败,成功 {_downloadedFiles.Count}/{fileList.Count}");
|
||||
}
|
||||
|
||||
VerifyAndSaveAllFiles();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
UpdateStatus($"下载过程出错: {ex.Message}");
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
[DllImport("kernel32.dll", SetLastError = true)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
private static extern bool GetProcessHandleCount(IntPtr hProcess, out uint pdwHandleCount);
|
||||
|
||||
private void VerifyAndSaveAllFiles()
|
||||
{
|
||||
UpdateStatus("正在校验文件...");
|
||||
var failedFiles = new List<string>();
|
||||
int processedCount = 0;
|
||||
int totalFiles = _downloadedFiles.Count;
|
||||
|
||||
foreach (var item in _downloadedFiles)
|
||||
{
|
||||
string relativePath = item.Key;
|
||||
byte[] data = item.Value.Data;
|
||||
string expectedMd5 = item.Value.ExpectedMd5;
|
||||
|
||||
try
|
||||
{
|
||||
processedCount++;
|
||||
UpdateStatus($"正在校验和保存文件 ({processedCount}/{totalFiles}): {relativePath}");
|
||||
|
||||
string actualMd5 = CalculateMD5(data);
|
||||
if (actualMd5 != expectedMd5.ToLower())
|
||||
{
|
||||
throw new Exception($"MD5校验失败 (期望: {expectedMd5}, 实际: {actualMd5})");
|
||||
}
|
||||
|
||||
string localPath = Path.Combine(Application.StartupPath, relativePath);
|
||||
Directory.CreateDirectory(Path.GetDirectoryName(localPath));
|
||||
|
||||
// 尝试保存文件,如果文件被占用则尝试解锁
|
||||
if (!TrySaveFile(localPath, data))
|
||||
{
|
||||
// 如果无法解锁文件,则使用备用文件名保存
|
||||
string backupPath = localPath + ".new";
|
||||
File.WriteAllBytes(backupPath, data);
|
||||
|
||||
// 创建一个批处理文件,在应用程序退出后替换文件
|
||||
CreateReplaceScript(localPath, backupPath);
|
||||
UpdateStatus($"文件 {relativePath} 正在被占用,将在程序重启后更新");
|
||||
}
|
||||
|
||||
int percentage = 95 + (int)(processedCount * 5.0 / totalFiles);
|
||||
UpdateProgressValue(Math.Min(100, percentage));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
UpdateStatus($"文件校验失败: {relativePath} - {ex.Message}");
|
||||
failedFiles.Add(relativePath);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var failedFile in failedFiles)
|
||||
{
|
||||
_downloadedFiles.Remove(failedFile);
|
||||
}
|
||||
|
||||
if (failedFiles.Count > 0)
|
||||
{
|
||||
throw new Exception($"{failedFiles.Count}个文件校验失败");
|
||||
}
|
||||
else
|
||||
{
|
||||
UpdateStatus("所有文件校验和保存成功");
|
||||
UpdateProgressValue(100);
|
||||
}
|
||||
}
|
||||
|
||||
private bool TrySaveFile(string filePath, byte[] data)
|
||||
{
|
||||
try
|
||||
{
|
||||
// 直接尝试写入文件
|
||||
File.WriteAllBytes(filePath, data);
|
||||
return true;
|
||||
}
|
||||
catch (IOException)
|
||||
{
|
||||
// 文件被占用,尝试解锁
|
||||
UpdateStatus($"文件 {Path.GetFileName(filePath)} 被占用,尝试解锁...");
|
||||
|
||||
try
|
||||
{
|
||||
// 尝试找出占用文件的进程
|
||||
var processes = Process.GetProcesses();
|
||||
foreach (var process in processes)
|
||||
{
|
||||
try
|
||||
{
|
||||
// 跳过当前进程
|
||||
if (process.Id == Process.GetCurrentProcess().Id)
|
||||
if (dir.Equals(excludeFolder, StringComparison.OrdinalIgnoreCase))
|
||||
continue;
|
||||
|
||||
// 检查进程是否可能占用了文件
|
||||
string processName = process.ProcessName.ToLower();
|
||||
if (processName.Contains("explorer") ||
|
||||
processName.Contains("chrome") ||
|
||||
processName.Contains("edge") ||
|
||||
processName.Contains("firefox") ||
|
||||
processName.Contains("iexplore") ||
|
||||
processName.Contains("winword") ||
|
||||
processName.Contains("excel") ||
|
||||
processName.Contains("powerpnt") ||
|
||||
processName.Contains("acrobat") ||
|
||||
processName.Contains("reader"))
|
||||
{
|
||||
// 跳过常见的系统进程
|
||||
continue;
|
||||
count += GetTotalFileCount(dir, excludeFolder);
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
// 尝试获取进程句柄数量,如果句柄数量较多,可能正在使用文件
|
||||
uint handleCount = 0;
|
||||
if (GetProcessHandleCount(process.Handle, out handleCount) && handleCount > 0)
|
||||
// 生成目录结构的 json 表示
|
||||
private Dictionary<string, object> GenerateDirectoryJson(string directoryPath, string rootPath, int totalFiles, ref int processedFiles, string excludeFolder, string fileFolder)
|
||||
{
|
||||
// 尝试关闭进程
|
||||
UpdateStatus($"尝试关闭可能占用文件的进程: {process.ProcessName}");
|
||||
process.CloseMainWindow();
|
||||
var result = new Dictionary<string, object>();
|
||||
|
||||
// 等待进程关闭
|
||||
if (!process.WaitForExit(1000))
|
||||
// 处理当前目录文件
|
||||
foreach (var file in Directory.GetFiles(directoryPath))
|
||||
{
|
||||
// 如果进程没有响应,尝试强制结束
|
||||
process.Kill();
|
||||
}
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
// 忽略处理单个进程时的错误
|
||||
}
|
||||
finally
|
||||
{
|
||||
process.Dispose();
|
||||
}
|
||||
}
|
||||
// 计算文件MD5
|
||||
string fileMD5 = MD5Generation(file);
|
||||
string fileName = Path.GetFileName(file);
|
||||
result[fileName] = fileMD5;
|
||||
|
||||
// 再次尝试写入文件
|
||||
Thread.Sleep(500); // 等待一段时间确保文件已释放
|
||||
File.WriteAllBytes(filePath, data);
|
||||
UpdateStatus($"文件 {Path.GetFileName(filePath)} 解锁成功并已更新");
|
||||
return true;
|
||||
}
|
||||
catch
|
||||
try
|
||||
{
|
||||
// 如果仍然无法写入,返回失败
|
||||
return false;
|
||||
}
|
||||
// 复制文件到fileFolder目录,以MD5值命名且不保留后缀
|
||||
string destPath = Path.Combine(fileFolder, fileMD5);
|
||||
File.Copy(file, destPath, overwrite: true);
|
||||
|
||||
Process_Box.Invoke((MethodInvoker)(() =>
|
||||
{
|
||||
Process_Box.AppendText($"已复制: {file} -> {destPath}{Environment.NewLine}");
|
||||
}));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
UpdateStatus($"保存文件时发生错误: {ex.Message}");
|
||||
return false;
|
||||
}
|
||||
Process_Box.Invoke((MethodInvoker)(() =>
|
||||
{
|
||||
Process_Box.AppendText($"复制文件失败 {file}: {ex.Message}{Environment.NewLine}");
|
||||
}));
|
||||
}
|
||||
|
||||
private void CreateReplaceScript(string originalFile, string newFile)
|
||||
// 更新进度条
|
||||
processedFiles++;
|
||||
int progress = (int)((double)processedFiles / totalFiles * 100);
|
||||
progressBar1.Invoke((MethodInvoker)(() =>
|
||||
{
|
||||
progressBar1.Value = Math.Min(progress, progressBar1.Maximum);
|
||||
}));
|
||||
|
||||
// 显示处理路径
|
||||
string relativePath = GetRelativePath(file, rootPath);
|
||||
Process_Box.Invoke((MethodInvoker)(() =>
|
||||
{
|
||||
Process_Box.AppendText($".\\{relativePath}{Environment.NewLine}");
|
||||
}));
|
||||
}
|
||||
|
||||
// 递归处理子目录(自动跳过排除文件夹)
|
||||
foreach (var dir in Directory.GetDirectories(directoryPath))
|
||||
{
|
||||
if (Path.GetFullPath(dir).Equals(Path.GetFullPath(excludeFolder), StringComparison.OrdinalIgnoreCase))
|
||||
continue;
|
||||
|
||||
string dirName = Path.GetFileName(dir);
|
||||
result[dirName] = GenerateDirectoryJson(dir, rootPath, totalFiles, ref processedFiles, excludeFolder, fileFolder);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// 获取相对路径
|
||||
private string GetRelativePath(string fullPath, string basePath)
|
||||
{
|
||||
if (!basePath.EndsWith(Path.DirectorySeparatorChar.ToString()))
|
||||
basePath += Path.DirectorySeparatorChar;
|
||||
|
||||
Uri baseUri = new Uri(basePath);
|
||||
Uri fullUri = new Uri(fullPath);
|
||||
return Uri.UnescapeDataString(baseUri.MakeRelativeUri(fullUri).ToString()
|
||||
.Replace('/', Path.DirectorySeparatorChar));
|
||||
}
|
||||
|
||||
// 生成 json 文件
|
||||
private void GenerateMD5Json(string rootDirectory)
|
||||
{
|
||||
if (!Directory.Exists(rootDirectory))
|
||||
{
|
||||
MessageBox.Show("指定的目录不存在!", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
string batchFilePath = Path.Combine(Application.StartupPath, "update_files.bat");
|
||||
string processId = Process.GetCurrentProcess().Id.ToString();
|
||||
string escapedOriginalFile = originalFile.Replace("\\", "\\\\");
|
||||
string escapedNewFile = newFile.Replace("\\", "\\\\");
|
||||
Process_Box.Clear();
|
||||
progressBar1.Value = 0;
|
||||
Application.DoEvents();
|
||||
|
||||
// 创建批处理文件内容
|
||||
StringBuilder batchContent = new StringBuilder();
|
||||
batchContent.AppendLine("@echo off");
|
||||
batchContent.AppendLine(":check_process");
|
||||
batchContent.AppendLine($"tasklist /FI \"PID eq {processId}\" 2>NUL | find /I \"{ processId }\" >NUL");
|
||||
batchContent.AppendLine("if %ERRORLEVEL% == 0 (");
|
||||
batchContent.AppendLine(" timeout /t 1 /nobreak > NUL");
|
||||
batchContent.AppendLine(" goto check_process");
|
||||
batchContent.AppendLine(")");
|
||||
batchContent.AppendLine("timeout /t 2 /nobreak > NUL");
|
||||
batchContent.AppendLine($"del \"{escapedOriginalFile}\" /f /q");
|
||||
batchContent.AppendLine($"move \"{escapedNewFile}\" \"{escapedOriginalFile}\"");
|
||||
batchContent.AppendLine("del \"%~f0\" /f /q");
|
||||
// 存储MD5值
|
||||
string md5FolderPath = Path.Combine(rootDirectory, "MD5");
|
||||
Directory.CreateDirectory(md5FolderPath);
|
||||
// 存储MD5值对应的文件
|
||||
string fileFolderPath = Path.Combine(md5FolderPath, "File");
|
||||
Directory.CreateDirectory(fileFolderPath);
|
||||
|
||||
// 写入批处理文件
|
||||
bool fileExists = File.Exists(batchFilePath);
|
||||
using (StreamWriter writer = new StreamWriter(batchFilePath, fileExists))
|
||||
int totalFiles = GetTotalFileCount(rootDirectory, md5FolderPath);
|
||||
int processedFiles = 0;
|
||||
|
||||
// 如果文件数量为0,直接设置进度为100%
|
||||
if (totalFiles == 0)
|
||||
{
|
||||
if (!fileExists)
|
||||
{
|
||||
writer.Write(batchContent.ToString());
|
||||
}
|
||||
else
|
||||
{
|
||||
// 如果文件已存在,只添加移动文件的命令
|
||||
writer.WriteLine($"del \"{escapedOriginalFile}\" /f /q");
|
||||
writer.WriteLine($"move \"{escapedNewFile}\" \"{escapedOriginalFile}\"");
|
||||
}
|
||||
progressBar1.Value = 100;
|
||||
Process_Box.AppendText("没有找到任何文件\n");
|
||||
return;
|
||||
}
|
||||
|
||||
// 如果是第一次创建批处理文件,启动它
|
||||
if (!fileExists)
|
||||
var directoryStructure = GenerateDirectoryJson(rootDirectory, rootDirectory, totalFiles, ref processedFiles, md5FolderPath, fileFolderPath);
|
||||
|
||||
// 创建包含版本号的新结构
|
||||
var versionedStructure = new Dictionary<string, object>
|
||||
{
|
||||
ProcessStartInfo startInfo = new ProcessStartInfo
|
||||
{
|
||||
FileName = "cmd.exe",
|
||||
Arguments = $"/c start \"\" /min \"{batchFilePath}\"",
|
||||
CreateNoWindow = true,
|
||||
UseShellExecute = true,
|
||||
WindowStyle = ProcessWindowStyle.Hidden
|
||||
{ "version", textBox1.Text.Trim() },
|
||||
{ "data", directoryStructure }
|
||||
};
|
||||
Process.Start(startInfo);
|
||||
}
|
||||
|
||||
// 序列化和保存JSON
|
||||
string json = JsonConvert.SerializeObject(versionedStructure, Newtonsoft.Json.Formatting.Indented);
|
||||
string jsonMD5 = CalculateMD5FromString(json);
|
||||
string outputPath = Path.Combine(md5FolderPath, "md5.json");
|
||||
File.WriteAllText(outputPath, json);
|
||||
|
||||
// 最终更新
|
||||
progressBar1.Value = 100;
|
||||
Process_Box.AppendText($"\nmd5.json文件已生成在:{outputPath}\n");
|
||||
Process_Box.AppendText($"JSON内容MD5校验值:{jsonMD5}");
|
||||
Process_Box.ScrollToCaret();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
UpdateStatus($"创建替换脚本时出错: {ex.Message}");
|
||||
MessageBox.Show($"生成JSON文件时出错:{ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
}
|
||||
}
|
||||
|
||||
private string CalculateMD5(string input)
|
||||
// 计算字符串的MD5值
|
||||
private string CalculateMD5FromString(string input)
|
||||
{
|
||||
using (var md5 = MD5.Create())
|
||||
{
|
||||
byte[] inputBytes = Encoding.UTF8.GetBytes(input);
|
||||
byte[] hashBytes = md5.ComputeHash(inputBytes);
|
||||
return BitConverter.ToString(hashBytes).Replace("-", "").ToLowerInvariant();
|
||||
}
|
||||
}
|
||||
|
||||
private string CalculateMD5(byte[] data)
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (int i = 0; i < hashBytes.Length; i++)
|
||||
{
|
||||
using (var md5 = MD5.Create())
|
||||
{
|
||||
byte[] hashBytes = md5.ComputeHash(data);
|
||||
return BitConverter.ToString(hashBytes).Replace("-", "").ToLowerInvariant();
|
||||
sb.Append(hashBytes[i].ToString("x2")); // 使用小写十六进制格式
|
||||
}
|
||||
return sb.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -117,4 +117,7 @@
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<metadata name="folderBrowserDialog1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>17, 17</value>
|
||||
</metadata>
|
||||
</root>
|
@ -1,14 +1,13 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="packages\Costura.Fody.6.0.0\build\Costura.Fody.props" Condition="Exists('packages\Costura.Fody.6.0.0\build\Costura.Fody.props')" />
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectGuid>{F4681804-7E5A-4A02-87EF-B28E34AA443B}</ProjectGuid>
|
||||
<ProjectGuid>{353C07CE-BA22-44F3-8816-5F97E2B9DDE0}</ProjectGuid>
|
||||
<OutputType>WinExe</OutputType>
|
||||
<RootNamespace>CheckDownload</RootNamespace>
|
||||
<AssemblyName>CheckDownload</AssemblyName>
|
||||
<RootNamespace>MD5Create</RootNamespace>
|
||||
<AssemblyName>MD5Create</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
|
||||
@ -24,12 +23,11 @@
|
||||
<UpdatePeriodically>false</UpdatePeriodically>
|
||||
<UpdateRequired>false</UpdateRequired>
|
||||
<MapFileExtensions>true</MapFileExtensions>
|
||||
<ApplicationRevision>0</ApplicationRevision>
|
||||
<ApplicationRevision>2</ApplicationRevision>
|
||||
<ApplicationVersion>1.0.0.%2a</ApplicationVersion>
|
||||
<UseApplicationTrust>false</UseApplicationTrust>
|
||||
<PublishWizardCompleted>true</PublishWizardCompleted>
|
||||
<BootstrapperEnabled>true</BootstrapperEnabled>
|
||||
<NuGetPackageImportStamp>
|
||||
</NuGetPackageImportStamp>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
@ -50,23 +48,23 @@
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<ManifestCertificateThumbprint>5F728211560A8301D63BE7DD69560329B0CAB9FC</ManifestCertificateThumbprint>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<ManifestKeyFile>MD5Create_TemporaryKey.pfx</ManifestKeyFile>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<GenerateManifests>true</GenerateManifests>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<SignManifests>true</SignManifests>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="Aliyun.OSS, Version=2.14.1.0, Culture=neutral, PublicKeyToken=0ad4175f0dac0b9b, processorArchitecture=MSIL">
|
||||
<HintPath>packages\Aliyun.OSS.SDK.2.14.1\lib\net461\Aliyun.OSS.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Costura, Version=6.0.0.0, Culture=neutral, PublicKeyToken=9919ef960d84173d, processorArchitecture=MSIL">
|
||||
<HintPath>packages\Costura.Fody.6.0.0\lib\netstandard2.0\Costura.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="DnsClient, Version=1.8.0.0, Culture=neutral, PublicKeyToken=4574bb5573c51424, processorArchitecture=MSIL">
|
||||
<HintPath>packages\DnsClient.1.8.0\lib\net472\DnsClient.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Newtonsoft.Json, Version=13.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
|
||||
<HintPath>packages\Newtonsoft.Json.13.0.3\lib\net45\Newtonsoft.Json.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Buffers, Version=4.0.3.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
|
||||
<HintPath>packages\System.Buffers.4.5.1\lib\net461\System.Buffers.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
@ -99,6 +97,7 @@
|
||||
<AutoGen>True</AutoGen>
|
||||
<DependentUpon>Resources.resx</DependentUpon>
|
||||
</Compile>
|
||||
<None Include="MD5Create_TemporaryKey.pfx" />
|
||||
<None Include="packages.config" />
|
||||
<None Include="Properties\Settings.settings">
|
||||
<Generator>SettingsSingleFileGenerator</Generator>
|
||||
@ -126,14 +125,4 @@
|
||||
</BootstrapperPackage>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<Import Project="packages\Fody.6.8.2\build\Fody.targets" Condition="Exists('packages\Fody.6.8.2\build\Fody.targets')" />
|
||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||
<PropertyGroup>
|
||||
<ErrorText>这台计算机上缺少此项目引用的 NuGet 程序包。使用“NuGet 程序包还原”可下载这些程序包。有关更多信息,请参见 http://go.microsoft.com/fwlink/?LinkID=322105。缺少的文件是 {0}。</ErrorText>
|
||||
</PropertyGroup>
|
||||
<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\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'))" />
|
||||
</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')" />
|
||||
</Project>
|
@ -3,7 +3,7 @@ Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 17
|
||||
VisualStudioVersion = 17.13.35825.156 d17.13
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CheckDownload", "CheckDownload.csproj", "{F4681804-7E5A-4A02-87EF-B28E34AA443B}"
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MD5Create", "MD5Create.csproj", "{353C07CE-BA22-44F3-8816-5F97E2B9DDE0}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
@ -11,15 +11,15 @@ Global
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{F4681804-7E5A-4A02-87EF-B28E34AA443B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{F4681804-7E5A-4A02-87EF-B28E34AA443B}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{F4681804-7E5A-4A02-87EF-B28E34AA443B}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{F4681804-7E5A-4A02-87EF-B28E34AA443B}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{353C07CE-BA22-44F3-8816-5F97E2B9DDE0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{353C07CE-BA22-44F3-8816-5F97E2B9DDE0}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{353C07CE-BA22-44F3-8816-5F97E2B9DDE0}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{353C07CE-BA22-44F3-8816-5F97E2B9DDE0}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {EB680316-B04E-4697-BD44-CF7E4AE2D8BD}
|
||||
SolutionGuid = {25B0F992-2814-48A9-9F14-6F5D10FF4855}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
BIN
MD5Create_TemporaryKey.pfx
Normal file
BIN
MD5Create_TemporaryKey.pfx
Normal file
Binary file not shown.
@ -4,7 +4,7 @@ using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace CheckDownload
|
||||
namespace MD5Create
|
||||
{
|
||||
static class Program
|
||||
{
|
||||
@ -16,7 +16,7 @@ namespace CheckDownload
|
||||
{
|
||||
Application.EnableVisualStyles();
|
||||
Application.SetCompatibleTextRenderingDefault(false);
|
||||
Application.Run(new Update());
|
||||
Application.Run(new MD5Create());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -5,11 +5,11 @@ using System.Runtime.InteropServices;
|
||||
// 有关程序集的一般信息由以下
|
||||
// 控制。更改这些特性值可修改
|
||||
// 与程序集关联的信息。
|
||||
[assembly: AssemblyTitle("CheckDownload")]
|
||||
[assembly: AssemblyTitle("MD5Create")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("CheckDownload")]
|
||||
[assembly: AssemblyProduct("MD5Create")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2025")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
@ -20,7 +20,7 @@ using System.Runtime.InteropServices;
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID
|
||||
[assembly: Guid("f4681804-7e5a-4a02-87ef-b28e34aa443b")]
|
||||
[assembly: Guid("353c07ce-ba22-44f3-8816-5f97e2b9dde0")]
|
||||
|
||||
// 程序集的版本信息由下列四个值组成:
|
||||
//
|
||||
|
4
Properties/Resources.Designer.cs
generated
4
Properties/Resources.Designer.cs
generated
@ -8,7 +8,7 @@
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace CheckDownload.Properties
|
||||
namespace MD5Create.Properties
|
||||
{
|
||||
|
||||
|
||||
@ -44,7 +44,7 @@ namespace CheckDownload.Properties
|
||||
{
|
||||
if ((resourceMan == null))
|
||||
{
|
||||
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("CheckDownload.Properties.Resources", typeof(Resources).Assembly);
|
||||
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("MD5Create.Properties.Resources", typeof(Resources).Assembly);
|
||||
resourceMan = temp;
|
||||
}
|
||||
return resourceMan;
|
||||
|
2
Properties/Settings.Designer.cs
generated
2
Properties/Settings.Designer.cs
generated
@ -8,7 +8,7 @@
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace CheckDownload.Properties
|
||||
namespace MD5Create.Properties
|
||||
{
|
||||
|
||||
|
||||
|
45
md5.json
45
md5.json
@ -1,45 +0,0 @@
|
||||
{
|
||||
"version": "1.0.1",
|
||||
"date": {
|
||||
"Admin-Keyauth-test.exe": "90e4541dd0ce570d726ef5ec7e955f1e",
|
||||
"CodeDependencies.iss": "3f20c3b14eefa82dd73c4ba8c8cd16a8",
|
||||
"f1c7016af6c8ca5eaad5c1ad0b8ad28b.json": "f1c7016af6c8ca5eaad5c1ad0b8ad28b",
|
||||
"GKeyManager_1.4.8_test_auto.exe": "7d1eb2a411ea6e7e14bd4de40274a52f",
|
||||
"main.go": "b1c53d8b985e6680cbe6b579c25a827e",
|
||||
"output_test.iss": "fb17a52e4b6dd12c643cd37f61497ab6",
|
||||
"new": {
|
||||
"md5-a.json": "1d0cd2f12943c23201610035ca2fc53f"
|
||||
},
|
||||
"test": {
|
||||
"aspnetcore-runtime-6.0.36-win-x86.exe": "638cd17cc32c6882fe01c56eaf003a2c",
|
||||
"dockerfile": "3ac7da6188e62fd43f8b8558486fe702",
|
||||
"go.mod": "4a3891b4e68630f56d57e0eca125a185",
|
||||
"go.sum": "37aff3bcc4eeea1c52aa867c83670d9c",
|
||||
"Login_update.exe": "d4fbcab2a61960de56c7a01c5ecace85",
|
||||
"Main.exe": "af5b5d9f44f74e121b0d78e21dfe8328",
|
||||
"main.go": "a725751ba669944ac36ee6a3cdcffca1",
|
||||
"md5.json": "58c4bf8e5a9c77ac06eea0bbd6cf25ab",
|
||||
"netcorecheck.exe": "298fa2564c44e3c1fdbc84cc76d97bd9",
|
||||
"ssh.tar": "5f87ff72678afc5e15cd92d4344ff901",
|
||||
"vc_redist.x86.exe": "3ca2b599c42442b57aeb07229d731d71",
|
||||
"Windows6.1-KB2533623-x64.msu": "0a894c59c245dad32e6e48ecbdbc8921",
|
||||
"Windows6.1-KB2533623-x86.msu": "edf1d538c85f24ec0ef0991e6b27f0d7",
|
||||
"windowsdesktop-runtime-6.0.36-win-x86.exe": "9c62d5c212725b00563ca6b201326b8f",
|
||||
"FIle": {
|
||||
"aspnetcorev2_inprocess.dll": "a9ec468ef61b60f43cf24d4b62bef9de",
|
||||
"D3DCompiler_47_cor3.dll": "5ce90e0d97f339e0cdf9873d3cb7c222",
|
||||
"KeyManages.pdb": "7c1cbed9f87e556630d35f3ec9ea3092",
|
||||
"Login_update.exe": "dad6b14e7a0ee41514bcbee826084b87",
|
||||
"Main.exe": "1566dc18caa5ff94e84b7a0b097a1256",
|
||||
"PenImc_cor3.dll": "931cf859776dbac94c5ab2f69055d9c6",
|
||||
"PresentationNative_cor3.dll": "690cd2dd64ceaecc84a037835682a1ab",
|
||||
"vcruntime140_cor3.dll": "9248c36666a2fec5e2a8913d6edabf80",
|
||||
"wpfgfx_cor3.dll": "5fbd0fb4e2a2cc6f7ed3c6369b369ef6"
|
||||
},
|
||||
"utils": {
|
||||
"encryptData.go": "509d003b33b915372639919f2ad6de6f"
|
||||
}
|
||||
},
|
||||
"新建文件夹": {}
|
||||
}
|
||||
}
|
@ -1,9 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<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="DnsClient" version="1.8.0" targetFramework="net472" />
|
||||
<package id="Fody" version="6.8.2" targetFramework="net472" developmentDependency="true" />
|
||||
<package id="Newtonsoft.Json" version="13.0.3" targetFramework="net472" />
|
||||
<package id="System.Buffers" version="4.5.1" targetFramework="net472" />
|
||||
</packages>
|
Loading…
x
Reference in New Issue
Block a user