using Newtonsoft.Json; using Quartz; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using WIDESEAWCS_BasicInfoRepository; using WIDESEAWCS_BasicInfoService; using WIDESEAWCS_IBasicInfoRepository; using WIDESEAWCS_ISystemRepository; using WIDESEAWCS_ISystemServices; using WIDESEAWCS_ITaskInfoRepository; using WIDESEAWCS_ITaskInfoService; using WIDESEAWCS_QuartzJob; using WIDESEAWCS_QuartzJob.Repository; using WIDESEAWCS_QuartzJob.Service; using WIDESEAWCS_SignalR; using WIDESEAWCS_Tasks.ElevatorJob; namespace WIDESEAWCS_Tasks { [DisallowConcurrentExecution] public partial class CommonDeleteLogJob : JobBase, IJob { private readonly ISys_DelLogRepository _logRepository; public CommonDeleteLogJob(ISys_DelLogRepository logRepository) { _logRepository = logRepository; } public Task Execute(IJobExecutionContext context) { try { Task.Run(() => { while (true) { try { var logfileName = _logRepository.QueryData(x => true); foreach (var item in logfileName) { string folderPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, item.FileName); DateTime intervalTime = DateTime.Now.AddDays(-item.IntervalTime); CleanDirectory(folderPath, intervalTime); } Thread.Sleep(1000 * 60 * 60 * 24); } catch { Thread.Sleep(1000 * 60 * 60); } } }); return Task.CompletedTask; } catch (Exception) { throw; } } public static void CleanDirectory(string rootPath, DateTime cutoffDate, bool deleteEmptyDirs = true) { var rootDir = new DirectoryInfo(rootPath); ValidateRootDirectory(rootDir); // 验证根目录有效性 CleanDirectoryRecursive(rootDir, cutoffDate, deleteEmptyDirs); } private static void CleanDirectoryRecursive(DirectoryInfo dir, DateTime cutoffDate, bool deleteEmptyDirs) { // 第一步:处理当前目录下的所有子项 foreach (var item in dir.GetFileSystemInfos()) { if (item is FileInfo file) { if (file.LastWriteTime < cutoffDate) { DeleteWithRetry(file.FullName, maxRetries: 5); } } else if (item is DirectoryInfo subDir) { CleanDirectoryRecursive(subDir, cutoffDate, deleteEmptyDirs); // 递归处理子目录 } } // 第二步:处理空目录(可选) if (deleteEmptyDirs && dir.LastWriteTime < cutoffDate && !dir.EnumerateFileSystemInfos().Any()) // 关键空置检测 { try { if (IsRootDirectory(dir)) // 防止删除根目录 { Console.WriteLine($"跳过根目录删除: {dir.FullName}"); return; } dir.Delete(true); // 强制删除目录(含只读文件) Console.WriteLine($"已删除空目录: {dir.FullName}"); } catch (Exception ex) when (ex is UnauthorizedAccessException or IOException) { Console.WriteLine($"无法删除目录: {dir.FullName} | 错误: {ex.Message}"); } } } // 辅助方法:带重试的删除操作 private static void DeleteWithRetry(string path, int maxRetries) { for (int i = 0; i <= maxRetries; i++) { try { if (File.Exists(path)) { File.Delete(path); } else if (Directory.Exists(path)) { Directory.Delete(path, true); } break; } catch (IOException ex) when (ex.HResult == -2147024894) // 文件被占用 { if (i == maxRetries) throw; Thread.Sleep(100); } catch { if (i == maxRetries) throw; Thread.Sleep(50); } } } // 验证根目录有效性 private static void ValidateRootDirectory(DirectoryInfo dir) { if (!dir.Exists) throw new DirectoryNotFoundException($"目录不存在: {dir.FullName}"); if (IsSystemDirectory(dir)) throw new InvalidOperationException("禁止清理系统目录"); } // 判断是否系统目录(示例) private static bool IsSystemDirectory(DirectoryInfo dir) => dir.FullName.Contains("System32", StringComparison.OrdinalIgnoreCase) || dir.FullName.Contains("ProgramData", StringComparison.OrdinalIgnoreCase); // 判断是否根目录(防止误删) private static bool IsRootDirectory(DirectoryInfo dir) => Path.GetPathRoot(dir.FullName) == dir.FullName; } }