huangxiaoqiang
2026-04-02 8cf9d378ad17a59b1b18067bd18280dd6b02719f
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
 
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;
 
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;
    }
}