huangxiaoqiang
2025-09-25 3dd51bc3ddd00cc0c8b901ad039f877d510a61ff
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
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;
    }
}