243 lines
9.2 KiB
C#
243 lines
9.2 KiB
C#
using System;
|
||
using System.Collections.Generic;
|
||
using System.ComponentModel;
|
||
using System.Data;
|
||
using System.Drawing;
|
||
using System.IO;
|
||
using System.Linq;
|
||
using System.Security.Cryptography;
|
||
using System.Text;
|
||
using System.Threading.Tasks;
|
||
using System.Windows.Forms;
|
||
using System.Xml;
|
||
using Newtonsoft.Json;
|
||
|
||
namespace MD5Create
|
||
{
|
||
public partial class MD5Create : Form
|
||
{
|
||
public MD5Create()
|
||
{
|
||
InitializeComponent();
|
||
// Initialize progress bar
|
||
progressBar1.Minimum = 0;
|
||
progressBar1.Maximum = 100;
|
||
progressBar1.Value = 0;
|
||
progressBar1.Step = 1;
|
||
}
|
||
|
||
// 程序启动前检查目录和版本号
|
||
private void Start_Button_Click(object sender, EventArgs e)
|
||
{
|
||
if (string.IsNullOrWhiteSpace(Path1_Box.Text))
|
||
{
|
||
MessageBox.Show("请先选择目录!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
||
return;
|
||
}
|
||
|
||
if (string.IsNullOrWhiteSpace(textBox1.Text))
|
||
{
|
||
MessageBox.Show("请输入版本号!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
||
return;
|
||
}
|
||
|
||
// Reset progress bar
|
||
progressBar1.Value = 0;
|
||
|
||
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();
|
||
}
|
||
|
||
// 计算 MD5 的值
|
||
private string MD5Generation(string filePath)
|
||
{
|
||
using (var md5 = MD5.Create())
|
||
using (var stream = File.OpenRead(filePath))
|
||
{
|
||
byte[] hash = md5.ComputeHash(stream);
|
||
return BitConverter.ToString(hash).Replace("-", "").ToLower();
|
||
}
|
||
}
|
||
|
||
// 获取目录中文件总数(用于进度计算)
|
||
private int GetTotalFileCount(string directoryPath, string excludeFolder)
|
||
{
|
||
int count = Directory.GetFiles(directoryPath).Length;
|
||
|
||
foreach (var dir in Directory.GetDirectories(directoryPath))
|
||
{
|
||
if (dir.Equals(excludeFolder, StringComparison.OrdinalIgnoreCase))
|
||
continue;
|
||
|
||
count += GetTotalFileCount(dir, excludeFolder);
|
||
}
|
||
return count;
|
||
}
|
||
|
||
// 生成目录结构的 json 表示
|
||
private Dictionary<string, object> GenerateDirectoryJson(string directoryPath, string rootPath, int totalFiles, ref int processedFiles, string excludeFolder, string fileFolder)
|
||
{
|
||
var result = new Dictionary<string, object>();
|
||
|
||
// 处理当前目录文件
|
||
foreach (var file in Directory.GetFiles(directoryPath))
|
||
{
|
||
// 计算文件MD5
|
||
string fileMD5 = MD5Generation(file);
|
||
string fileName = Path.GetFileName(file);
|
||
result[fileName] = fileMD5;
|
||
|
||
try
|
||
{
|
||
// 复制文件到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)
|
||
{
|
||
Process_Box.Invoke((MethodInvoker)(() =>
|
||
{
|
||
Process_Box.AppendText($"复制文件失败 {file}: {ex.Message}{Environment.NewLine}");
|
||
}));
|
||
}
|
||
|
||
// 更新进度条
|
||
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
|
||
{
|
||
Process_Box.Clear();
|
||
progressBar1.Value = 0;
|
||
Application.DoEvents();
|
||
|
||
// 存储MD5值
|
||
string md5FolderPath = Path.Combine(rootDirectory, "MD5");
|
||
Directory.CreateDirectory(md5FolderPath);
|
||
// 存储MD5值对应的文件
|
||
string fileFolderPath = Path.Combine(md5FolderPath, "File");
|
||
Directory.CreateDirectory(fileFolderPath);
|
||
|
||
int totalFiles = GetTotalFileCount(rootDirectory, md5FolderPath);
|
||
int processedFiles = 0;
|
||
|
||
// 如果文件数量为0,直接设置进度为100%
|
||
if (totalFiles == 0)
|
||
{
|
||
progressBar1.Value = 100;
|
||
Process_Box.AppendText("没有找到任何文件\n");
|
||
return;
|
||
}
|
||
|
||
var directoryStructure = GenerateDirectoryJson(rootDirectory, rootDirectory, totalFiles, ref processedFiles, md5FolderPath, fileFolderPath);
|
||
|
||
// 创建包含版本号的新结构
|
||
var versionedStructure = new Dictionary<string, object>
|
||
{
|
||
{ "version", textBox1.Text.Trim() },
|
||
{ "data", directoryStructure }
|
||
};
|
||
|
||
// 序列化和保存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)
|
||
{
|
||
MessageBox.Show($"生成JSON文件时出错:{ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||
}
|
||
}
|
||
|
||
// 计算字符串的MD5值
|
||
private string CalculateMD5FromString(string input)
|
||
{
|
||
using (var md5 = MD5.Create())
|
||
{
|
||
byte[] inputBytes = Encoding.UTF8.GetBytes(input);
|
||
byte[] hashBytes = md5.ComputeHash(inputBytes);
|
||
|
||
StringBuilder sb = new StringBuilder();
|
||
for (int i = 0; i < hashBytes.Length; i++)
|
||
{
|
||
sb.Append(hashBytes[i].ToString("x2")); // 使用小写十六进制格式
|
||
}
|
||
return sb.ToString();
|
||
}
|
||
}
|
||
}
|
||
} |