diff --git a/App.config b/App.config index 5754728..249db00 100644 --- a/App.config +++ b/App.config @@ -3,4 +3,8 @@ + + + + \ No newline at end of file diff --git a/Form1.cs b/Form1.cs index 99fb155..2a120ce 100644 --- a/Form1.cs +++ b/Form1.cs @@ -28,7 +28,7 @@ namespace MD5Create } // 程序启动前检查目录和版本号 - private void Start_Button_Click(object sender, EventArgs e) + private async void Start_Button_Click(object sender, EventArgs e) { if (string.IsNullOrWhiteSpace(Path1_Box.Text)) { @@ -45,7 +45,7 @@ namespace MD5Create // Reset progress bar progressBar1.Value = 0; - GenerateMD5Json(Path1_Box.Text); + await Task.Run(() => GenerateMD5Json(Path1_Box.Text)); } private void Choose1_Button_Click(object sender, EventArgs e) @@ -88,14 +88,34 @@ namespace MD5Create // 获取目录中文件总数(用于进度计算) private int GetTotalFileCount(string directoryPath, string excludeFolder) { - int count = Directory.GetFiles(directoryPath).Length; - - foreach (var dir in Directory.GetDirectories(directoryPath)) + int count = 0; + try { - if (dir.Equals(excludeFolder, StringComparison.OrdinalIgnoreCase)) - continue; + count += Directory.GetFiles(directoryPath).Length; + } + catch (Exception) + { + // 忽略无法访问的目录 + } - count += GetTotalFileCount(dir, excludeFolder); + try + { + foreach (var dir in Directory.GetDirectories(directoryPath)) + { + if (dir.Equals(excludeFolder, StringComparison.OrdinalIgnoreCase)) + continue; + + // 跳过符号链接 / Junction + var dirInfo = new DirectoryInfo(dir); + if ((dirInfo.Attributes & FileAttributes.ReparsePoint) != 0) + continue; + + count += GetTotalFileCount(dir, excludeFolder); + } + } + catch (Exception) + { + // 同样忽略 } return count; } @@ -103,26 +123,54 @@ namespace MD5Create // 生成目录结构的 json 表示 private Dictionary GenerateDirectoryJson(string directoryPath, string rootPath, int totalFiles, ref int processedFiles, string excludeFolder, string fileFolder) { - var result = new Dictionary(); + var filesDict = new Dictionary(StringComparer.OrdinalIgnoreCase); + var dirsDict = new Dictionary(StringComparer.OrdinalIgnoreCase); // 处理当前目录文件 - foreach (var file in Directory.GetFiles(directoryPath)) + string[] files; + try + { + files = Directory.GetFiles(directoryPath); + } + catch (Exception ex) + { + Process_Box.Invoke((MethodInvoker)(() => + { + Process_Box.AppendText($"无法访问目录文件列表 {directoryPath}: {ex.Message}{Environment.NewLine}"); + })); + files = Array.Empty(); + } + + foreach (var file in files) { - // 计算文件MD5 - string fileMD5 = MD5Generation(file); string fileName = Path.GetFileName(file); - result[fileName] = fileMD5; + string fileMD5; + try + { + fileMD5 = MD5Generation(file); + } + catch (Exception ex) + { + Process_Box.Invoke((MethodInvoker)(() => + { + Process_Box.AppendText($"计算MD5失败 {file}: {ex.Message}{Environment.NewLine}"); + })); + continue; + } + + filesDict[fileName] = fileMD5; try { - // 复制文件到fileFolder目录,以MD5值命名且不保留后缀 string destPath = Path.Combine(fileFolder, fileMD5); - File.Copy(file, destPath, overwrite: true); - - Process_Box.Invoke((MethodInvoker)(() => + if (!File.Exists(destPath)) { - Process_Box.AppendText($"已复制: {file} -> {destPath}{Environment.NewLine}"); - })); + File.Copy(file, destPath, overwrite: false); + Process_Box.Invoke((MethodInvoker)(() => + { + Process_Box.AppendText($"已复制: {file} -> {destPath}{Environment.NewLine}"); + })); + } } catch (Exception ex) { @@ -148,16 +196,41 @@ namespace MD5Create })); } - // 递归处理子目录(自动跳过排除文件夹) - foreach (var dir in Directory.GetDirectories(directoryPath)) + // 递归处理子目录 + string[] subDirs; + try + { + subDirs = Directory.GetDirectories(directoryPath); + } + catch (Exception ex) + { + Process_Box.Invoke((MethodInvoker)(() => + { + Process_Box.AppendText($"无法访问子目录列表 {directoryPath}: {ex.Message}{Environment.NewLine}"); + })); + subDirs = Array.Empty(); + } + + foreach (var dir in subDirs) { if (Path.GetFullPath(dir).Equals(Path.GetFullPath(excludeFolder), StringComparison.OrdinalIgnoreCase)) continue; + // 跳过符号链接 / Junction + var dirInfo = new DirectoryInfo(dir); + if ((dirInfo.Attributes & FileAttributes.ReparsePoint) != 0) + continue; + string dirName = Path.GetFileName(dir); - result[dirName] = GenerateDirectoryJson(dir, rootPath, totalFiles, ref processedFiles, excludeFolder, fileFolder); + dirsDict[dirName] = GenerateDirectoryJson(dir, rootPath, totalFiles, ref processedFiles, excludeFolder, fileFolder); } + var result = new Dictionary(StringComparer.OrdinalIgnoreCase) + { + { "files", filesDict }, + { "dirs", dirsDict } + }; + return result; } @@ -178,14 +251,20 @@ namespace MD5Create { if (!Directory.Exists(rootDirectory)) { - MessageBox.Show("指定的目录不存在!", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); + this.Invoke((MethodInvoker)(() => + { + MessageBox.Show("指定的目录不存在!", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); + })); return; } try { - Process_Box.Clear(); - progressBar1.Value = 0; + this.Invoke((MethodInvoker)(() => + { + Process_Box.Clear(); + progressBar1.Value = 0; + })); Application.DoEvents(); // 存储MD5值 @@ -222,14 +301,20 @@ namespace MD5Create File.WriteAllText(outputPath, json); // 最终更新 - progressBar1.Value = 100; - Process_Box.AppendText($"\nmd5.json文件已生成在:{outputPath}\n"); - Process_Box.AppendText($"JSON内容MD5校验值:{jsonMD5}"); - Process_Box.ScrollToCaret(); + this.Invoke((MethodInvoker)(() => + { + 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); + this.Invoke((MethodInvoker)(() => + { + MessageBox.Show($"生成JSON文件时出错:{ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); + })); } }