Commit e76b511841ab3d83d20a74db6ffb58cbb75bce30
1 parent
0b366b5a
FileCleanerManager és MaintenanceToolManager/RegexTester elkészítése
Showing
12 changed files
with
1037 additions
and
11 deletions
Show diff stats
Vrh.Log4Pro.MaintenanceConsole/App.config
1 | 1 | <?xml version="1.0" encoding="utf-8"?> |
2 | 2 | <configuration> |
3 | + <configSections> | |
4 | + <!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 --> | |
5 | + <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" /> | |
6 | + </configSections> | |
3 | 7 | <startup> |
4 | 8 | <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.2" /> |
5 | 9 | </startup> |
6 | 10 | <appSettings> |
7 | - <add key="VRH.XmlParser:root" value="XmlParser.xml"/> | |
11 | + <add key="VRH.XmlParser:root" value="XmlParser.xml" /> | |
8 | 12 | </appSettings> |
9 | 13 | <runtime> |
10 | 14 | <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> |
... | ... | @@ -14,4 +18,9 @@ |
14 | 18 | </dependentAssembly> |
15 | 19 | </assemblyBinding> |
16 | 20 | </runtime> |
21 | + <entityFramework> | |
22 | + <providers> | |
23 | + <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" /> | |
24 | + </providers> | |
25 | + </entityFramework> | |
17 | 26 | </configuration> |
18 | 27 | \ No newline at end of file | ... | ... |
Vrh.Log4Pro.MaintenanceConsole/Config.xml
... | ... | @@ -70,11 +70,11 @@ |
70 | 70 | |
71 | 71 | <XmlVar Name="DIR_ROOTBAK">C:\Log4ProISBackups</XmlVar> |
72 | 72 | <XmlVar Name="MSMQTEST">@DIR_ROOTBAK@\MSMQtests</XmlVar> |
73 | - <XmlVar Name="ILOG">@DIR_ROOTBAK@\VRH.Logfiles</XmlVar> | |
74 | - <XmlVar Name="REDISLOG">@ILOG@\RedisLog</XmlVar> | |
75 | - <XmlVar Name="WINEVENTLOGS">@ILOG@\WindowsEventLogs</XmlVar> | |
76 | - <XmlVar Name="DUMPFOLDER">@ILOG@\WindowsEventLogs</XmlVar> | |
77 | - <XmlVar Name="SRVLOG">@ILOG@\ServiceScriptLogs</XmlVar> | |
73 | + <XmlVar Name="DIR_ILOG">@DIR_ROOTBAK@\VRH.Logfiles</XmlVar> | |
74 | + <XmlVar Name="REDISLOG">@DIR_ILOG@\RedisLog</XmlVar> | |
75 | + <XmlVar Name="DIR_WINEVENTLOGS">@DIR_ILOG@\WindowsEventLogs</XmlVar> | |
76 | + <XmlVar Name="DUMPFOLDER">@DIR_ILOG@\WindowsEventLogs</XmlVar> | |
77 | + <XmlVar Name="SRVLOG">@DIR_ILOG@\ServiceScriptLogs</XmlVar> | |
78 | 78 | <XmlVar Name="DIR_SYSBAK">@DIR_ROOTBAK@\SystemBackups</XmlVar> |
79 | 79 | <XmlVar Name="DIR_DBBAK">@DIR_ROOTBAK@\BackupDBOnly</XmlVar> |
80 | 80 | <XmlVar Name="DIR_BAKTMP">@DIR_ROOTBAK@\TEMP</XmlVar> |
... | ... | @@ -157,4 +157,34 @@ |
157 | 157 | <WebApplication Id="WEBAPP_CP" Name="WebPack" Description="@WEBPACKDESC@" AppPool="WebPack" Website="Default Web Site" InstallDir="@DIR_WEBAPPWEBPACK@" SiteRootDir="@DIR_WEBAPPWEBPACK@" IdentityConfigFile="@WEBPACKIDENTITYCONFIG@" AppPoolUsername="" AppPoolPassword="" AppPoolPipeLineMode="" RecreateSite="false" RecreatePool="true" RecreateApp="true"/> |
158 | 158 | <WebApplication Id="WEBAPP_LOG4PROIS" Name="Log4ProIS" Description="@WEBLOG4PROISDESC@" AppPool="Log4ProIS" Website="Default Web Site" InstallDir="@DIR_WEBAPPLOG4PROIS@" SiteRootDir="@DIR_WEBAPPLOG4PROIS@" IdentityConfigFile="@LOG4PROISIDENTITYCONFIG@" AppPoolUsername="" AppPoolPassword="" AppPoolPipeLineMode="" RecreateSite="false" RecreatePool="true" RecreateApp="true"/> |
159 | 159 | </WebApplications> |
160 | + | |
161 | + <FileCleaner CleanupDays="7"> | |
162 | + <FolderToClean Directory="@DIR_ILOG@" Recurse="True" RemoveEmptyFolder="False" IncludeMask="L_*"> | |
163 | + <IncludeFullpathRegexp>^.*\\L_.*_(?'YEAR'\d\d\d\d)(?'MONTH'\d\d)(?'DAY'\d\d)_(?'HOUR'\d\d)(?'MINUTE'\d\d)(?'SECOND'\d\d)$</IncludeFullpathRegexp> | |
164 | + <Conditions OrConditionList="True"> | |
165 | + <Condition Type="TimeStampInName" TimestampConstructor="{YEAR}.{MONTH}.{DAY} {HOUR}:{MINUTE}:{SECOND}" Limit="3" /> | |
166 | + <Condition Type="Length" Limit="80000000" /> | |
167 | + </Conditions> | |
168 | + </FolderToClean> | |
169 | + <FolderToClean Directory="@DIR_WINEVENTLOGS@" Recurse="True" RemoveEmptyFolder="False" IncludeMask="*.dmp"> | |
170 | + <IncludeFullpathRegexp>^.*\\VRH.Log4Pro.DataController.WindowsService.exe.*\.dmp$</IncludeFullpathRegexp> | |
171 | + <Conditions OrConditionList="False"> | |
172 | + <Condition Type="LastWriteTime" Limit="2" /> | |
173 | + </Conditions> | |
174 | + </FolderToClean> | |
175 | + <FolderToClean Directory="@DIR_DBBAK@" Recurse="False" RemoveEmptyFolder="False" IncludeMask="SQLDBBackup_Lear*.*"> | |
176 | + <IncludeFullpathRegexp>^.*\\SQLDBBackup_Lear.*_.*_(?'YEAR'\d\d\d\d)(?'MONTH'\d\d)(?'DAY'\d\d)(?'HOUR'\d\d)(?'MINUTE'\d\d)(?'SECOND'\d\d)\.(bak|zip)$</IncludeFullpathRegexp> | |
177 | + <Conditions> | |
178 | + <Condition Type="TimeStampInName" TimestampConstructor="{YEAR}.{MONTH}.{DAY} {HOUR}:{MINUTE}:{SECOND}" Limit="7" /> | |
179 | + </Conditions> | |
180 | + </FolderToClean> | |
181 | + <FolderToClean Directory="@DIR_SYSBAK@" Recurse="True" RemoveEmptyFolder="True" IncludeMask="Lear*.exe"> | |
182 | + <IncludeFullpathRegexp>^.*\\\d\d\d\d\d\d\d\d\\LearALM_.*_BackupPackage.*(?'YEAR'\d\d\d\d)(?'MONTH'\d\d)(?'DAY'\d\d)(?'HOUR'\d\d)(?'MINUTE'\d\d)(?'SECOND'\d\d).*\.exe$</IncludeFullpathRegexp> | |
183 | + <Conditions> | |
184 | + <Condition Type="TimeStampInName" TimestampConstructor="{YEAR}.{MONTH}.{DAY} {HOUR}:{MINUTE}:{SECOND}" Limit="7" /> | |
185 | + </Conditions> | |
186 | + </FolderToClean> | |
187 | + <FolderToClean Directory="@DIR_BAKTMP@" Recurse="True" RemoveEmptyFolder="False" IncludeMask="*.*" /> | |
188 | + </FileCleaner> | |
189 | + | |
160 | 190 | </Configuration> |
161 | 191 | \ No newline at end of file | ... | ... |
Vrh.Log4Pro.MaintenanceConsole/ConsoleFunction - ColorConsole.cs
... | ... | @@ -48,7 +48,7 @@ namespace Vrh.Log4Pro.MaintenanceConsole |
48 | 48 | Console.ForegroundColor = savecolorF; |
49 | 49 | Console.BackgroundColor = savecolorB; |
50 | 50 | if (!string.IsNullOrEmpty(bracket)) { Console.Write($"{bracket[1]}"); } |
51 | - if (!string.IsNullOrEmpty(prefix)) { Write(suffix); } | |
51 | + if (!string.IsNullOrEmpty(suffix)) { Write(suffix); } | |
52 | 52 | } |
53 | 53 | } |
54 | 54 | #endregion ColorConsole | ... | ... |
Vrh.Log4Pro.MaintenanceConsole/ConsoleFunction - Menu.cs
... | ... | @@ -31,7 +31,7 @@ namespace Vrh.Log4Pro.MaintenanceConsole |
31 | 31 | |
32 | 32 | #region public properties |
33 | 33 | public List<Item> MenuItemList { get; private set; } = new List<Item>(); |
34 | - List<string> MenuKeyList { get { return MenuItemList.Select(x => x.Key).ToList(); } } | |
34 | + List<string> MenuKeyList { get { return MenuItemList.Where(x=> !x.Separator).Select(x => x.Key).ToList(); } } | |
35 | 35 | #endregion public properties |
36 | 36 | |
37 | 37 | #region public tools |
... | ... | @@ -85,6 +85,17 @@ namespace Vrh.Log4Pro.MaintenanceConsole |
85 | 85 | Console.SetCursorPosition(0, Console.CursorTop); |
86 | 86 | foreach (var menuitem in MenuItemList) |
87 | 87 | { |
88 | + if (menuitem.Separator && columns == 1) | |
89 | + { | |
90 | + Console.SetCursorPosition(columnlength * columncounter + HeaderWidth, Console.CursorTop); | |
91 | + var seplen = menuitem.SeparatorLength; | |
92 | + if (menuitem.SeparatorLength==0) | |
93 | + { | |
94 | + foreach (var mi in MenuItemList.Where(x=>!x.Separator)) { if (mi.Text.Length > seplen) { seplen = mi.Text.Length; } } | |
95 | + } | |
96 | + ColorConsole.WriteLine(new string(menuitem.SeparatorChar, seplen)); | |
97 | + continue; | |
98 | + } | |
88 | 99 | ColorConsole.Write($"["); |
89 | 100 | ColorConsole.Write($"{i}"); |
90 | 101 | if (!string.IsNullOrEmpty(menuitem.Key) && !menuitem.Key.StartsWith("#$KEY")) |
... | ... | @@ -249,7 +260,15 @@ namespace Vrh.Log4Pro.MaintenanceConsole |
249 | 260 | } |
250 | 261 | private Menu.Item GetItem(int ix) |
251 | 262 | { |
252 | - return MenuItemList.ElementAt(ix); | |
263 | + var i = 0; | |
264 | + foreach (var mi in MenuItemList) | |
265 | + { | |
266 | + if (mi.Separator) { continue; } | |
267 | + if (i == ix) return mi; | |
268 | + i++; | |
269 | + } | |
270 | + return null; | |
271 | + //return MenuItemList.ElementAt(ix); | |
253 | 272 | } |
254 | 273 | private int GetItemIx(string itemkey) |
255 | 274 | { |
... | ... | @@ -271,8 +290,18 @@ namespace Vrh.Log4Pro.MaintenanceConsole |
271 | 290 | } |
272 | 291 | } |
273 | 292 | #endregion private tools |
293 | + public class ItemSeparator : Item | |
294 | + { | |
295 | + public ItemSeparator(char c = '-', int length = 0) : base() | |
296 | + { | |
297 | + Separator = true; | |
298 | + SeparatorChar = c; | |
299 | + SeparatorLength = length; | |
300 | + } | |
301 | + } | |
274 | 302 | public class Item |
275 | 303 | { |
304 | + public Item() { } | |
276 | 305 | public Item(string key, string text, MenuItemExecutorFunc executor = null, object parameters = null) |
277 | 306 | { |
278 | 307 | Key = key; |
... | ... | @@ -284,6 +313,10 @@ namespace Vrh.Log4Pro.MaintenanceConsole |
284 | 313 | public string Text; |
285 | 314 | public MenuItemExecutorFunc Executor; |
286 | 315 | public object Parameters; |
316 | + | |
317 | + public bool Separator = false; | |
318 | + public char SeparatorChar = '-'; | |
319 | + public int SeparatorLength = 0; | |
287 | 320 | } |
288 | 321 | } |
289 | 322 | } | ... | ... |
Vrh.Log4Pro.MaintenanceConsole/Manager - FileCleanerManager.cs
0 → 100644
... | ... | @@ -0,0 +1,504 @@ |
1 | +using System; | |
2 | +using System.IO; | |
3 | +using System.Configuration.Install; | |
4 | +using System.Collections.Generic; | |
5 | +using System.Linq; | |
6 | +using System.ServiceProcess; | |
7 | +using System.Text; | |
8 | +using System.Threading; | |
9 | +using System.Threading.Tasks; | |
10 | + | |
11 | +using Microsoft.Web.Administration; | |
12 | +using System.Management; | |
13 | +using System.Diagnostics; | |
14 | + | |
15 | +using Vrh.XmlProcessing; | |
16 | +using System.Xml.Linq; | |
17 | +using System.Text.RegularExpressions; | |
18 | + | |
19 | +namespace Vrh.Log4Pro.MaintenanceConsole | |
20 | +{ | |
21 | + #region FileCleanerManager class | |
22 | + public static class FileCleanerManager | |
23 | + { | |
24 | + #region Execute | |
25 | + public static object Execute(object o1 = null, object o2 = null) | |
26 | + { | |
27 | + string xmlcs = "file=Config.Xml;element=FileCleaner;"; | |
28 | + var config = new FileCleanerManagerCoreXmlProcessor(xmlcs, "", "hu-HU"); | |
29 | + | |
30 | + var menufunctions = new Menu("Manage Folders To Clean", "Select the management function!") | |
31 | + .AddMenuItem(new Menu.Item("CLN", "Clean folder", CleanFolder)) | |
32 | + .SetSelectionMode(Menu.SelectionMode.Single); | |
33 | + | |
34 | + while (true) | |
35 | + { | |
36 | + Menu.Selection sr; | |
37 | + | |
38 | + menufunctions.DisplayTitle(); | |
39 | + var menuservices = DisplayFolders(config); | |
40 | + menufunctions.DisplayItems(); | |
41 | + sr = menufunctions.Select(); | |
42 | + if (sr.Result == Menu.SelectionResult.Exit) { break; } | |
43 | + else if (sr.Result == Menu.SelectionResult.None) { continue; } | |
44 | + else if (sr.Result == Menu.SelectionResult.Error) { continue; } | |
45 | + menufunctions.SetParameters(sr,config); | |
46 | + menufunctions.Execute(sr.SelectedKeyList); | |
47 | + } | |
48 | + return null; | |
49 | + } | |
50 | + #endregion Execute | |
51 | + | |
52 | + #region First level Executors with UI | |
53 | + private static object CleanFolder(object parameter, object o) | |
54 | + { | |
55 | + var config = parameter as FileCleanerManagerCoreXmlProcessor; | |
56 | + | |
57 | + var menufolders = DisplayFolders(config, $"Select the folder(s) to manage with function '{nameof(CleanFolder)}'!", silent: true); | |
58 | + | |
59 | + Menu.Selection sr = menufolders.Select(); | |
60 | + if (sr.Result == Menu.SelectionResult.Exit) { return o; } | |
61 | + else if (sr.Result == Menu.SelectionResult.None) { return o; } | |
62 | + else if (sr.Result == Menu.SelectionResult.Error) { return o; } | |
63 | + else if (sr.Result == Menu.SelectionResult.Ok) { } | |
64 | + else { } | |
65 | + foreach (var p in sr.SelectedParameterList) | |
66 | + { | |
67 | + FolderToClean ftc = p as FolderToClean; | |
68 | + try | |
69 | + { | |
70 | + var di = new DirectoryInfo(ftc.Xml_DirectoryPath); | |
71 | + var success = FileCleanerManagerCore.CleanFolderFiles(di,ftc, delete: true); | |
72 | + ColorConsole.WriteLine($"Folder cleaned. Name:{ftc.Xml_DirectoryPath}", ConsoleColor.Green); | |
73 | + } | |
74 | + catch (Exception ex) | |
75 | + { | |
76 | + ColorConsole.WriteLine(ex.Message, ConsoleColor.Red); | |
77 | + } | |
78 | + } | |
79 | + return o; | |
80 | + } | |
81 | + #endregion First level Executors with UI | |
82 | + | |
83 | + #region private methods | |
84 | + #region private DisplayFolders | |
85 | + private static Menu DisplayFolders(FileCleanerManagerCoreXmlProcessor config,string prompt = null,bool silent=false) | |
86 | + { | |
87 | + List<FolderToClean> fctdefList = config.GetDefinitionList(); | |
88 | + var menufct = new Menu("Folder to clean",prompt) | |
89 | + .SetMenuItemDisplayer(DisplayFolderInfo) | |
90 | + .SetSelectionMode(Menu.SelectionMode.Multi) | |
91 | + .SetHeaderWidth(4); | |
92 | + menufct.ClearMenuItemList(); | |
93 | + foreach (var fctdef in fctdefList) | |
94 | + { | |
95 | + var fi = CollectFolderInfo(fctdef); | |
96 | + menufct.AddMenuItem(new Menu.Item(null, null, null, fi)); | |
97 | + } | |
98 | + if (!silent) { menufct.DisplayItems(1); } | |
99 | + return menufct; | |
100 | + } | |
101 | + #endregion private DisplayFolders | |
102 | + #region private method: DisplayFolderInfo | |
103 | + private static object DisplayFolderInfo(object obj, int lineix) | |
104 | + { | |
105 | + FolderToClean ws = obj as FolderToClean; | |
106 | + if (lineix == 0) | |
107 | + { | |
108 | + ColorConsole.Write($"{ws.Xml_DirectoryPath}", ConsoleColor.Black, ConsoleColor.White); | |
109 | + var existscolor = ws.FolderExists ? ConsoleColor.Green : ConsoleColor.Red; | |
110 | + var existstext = ws.FolderExists ? "Exists" : "Missing"; | |
111 | + ColorConsole.WriteLine(existstext, existscolor, bracket: "[]", prefix: " ", suffix: ". "); | |
112 | + return " "; | |
113 | + } | |
114 | + else if (lineix == 1) | |
115 | + { | |
116 | + if (ws.FolderExists) | |
117 | + { | |
118 | + ColorConsole.Write(ws.SizeSelectedBeforeClean.ToString(), ConsoleColor.Yellow, prefix: "Size of filtered files now:"); | |
119 | + ColorConsole.Write(ws.SizeSelectedAfterClean.ToString(), ConsoleColor.Yellow, prefix: ", after cleaning:", suffix: ". "); | |
120 | + ColorConsole.Write(ws.SizeSelectedCleaned.ToString(), ConsoleColor.Red, prefix: "To clean:", suffix: "."); | |
121 | + ColorConsole.WriteLine(" "); | |
122 | + return " "; | |
123 | + } | |
124 | + return ""; | |
125 | + } | |
126 | + else if (lineix == 2) | |
127 | + { | |
128 | + ColorConsole.Write($"{ws.Xml_CleanupDays}", ConsoleColor.Yellow, prefix: "Cleanup days:", bracket: "[]"); | |
129 | + var fc2 = ws.Xml_Recurse ? ConsoleColor.Green : ConsoleColor.Yellow; | |
130 | + ColorConsole.Write($"{ws.Xml_Recurse}", fc2, prefix: ", Recurse:", bracket: "[]"); | |
131 | + var fc0 = ws.Xml_RemoveEmptyFolder ? ConsoleColor.Green : ConsoleColor.Yellow; | |
132 | + ColorConsole.Write($"{ws.Xml_RemoveEmptyFolder}", fc0, prefix: ", Remove empty folder:", bracket: "[]"); | |
133 | + ColorConsole.WriteLine(ws.Xml_IncludeMask, ConsoleColor.Yellow, prefix: ", Include mask:"); | |
134 | + return " "; | |
135 | + } | |
136 | + else // if (lineix == INDEXBASE) | |
137 | + { | |
138 | + const int INDEXBASE = 3; // a linex következő indexe kerüljön ide !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
139 | + if (ws.Xml_ConditionList.Count <= lineix - INDEXBASE) { return null; } | |
140 | + var c = ws.Xml_ConditionList.ElementAt(lineix- INDEXBASE); | |
141 | + if (c != null) | |
142 | + { | |
143 | + if (lineix != INDEXBASE) { ColorConsole.Write(ws.Xml_OrConditionList ? "OR" : "AND", ConsoleColor.Yellow,suffix:" "); } | |
144 | + ColorConsole.Write("Condition:"); | |
145 | + ColorConsole.Write(c.Type.ToString(),ConsoleColor.Yellow, prefix: " Type:"); | |
146 | + if (c.Type==FolderToClean.ConditionType.TimeStampInName) { ColorConsole.Write(c.TimestampConstructor, ConsoleColor.Yellow, prefix: ", TS constructor:"); } | |
147 | + ColorConsole.Write(c.Limit.ToString(), ConsoleColor.Yellow, prefix: ", Limit:",suffix: c.Type == FolderToClean.ConditionType.Length ? "bytes" : "days"); | |
148 | + ColorConsole.WriteLine(); | |
149 | + return " "; | |
150 | + } | |
151 | + } | |
152 | + return null; | |
153 | + } | |
154 | + #endregion private method: DisplayFolderInfo | |
155 | + #region private CollectFolderInfo | |
156 | + private static FolderToClean CollectFolderInfo(FolderToClean ftc) | |
157 | + { | |
158 | + ftc.SizeFolderTotal= 0; | |
159 | + ftc.SizeSelectedBeforeClean = 0; | |
160 | + ftc.SizeSelectedCleaned = 0; | |
161 | + ftc.FolderExists = Directory.Exists(ftc.Xml_DirectoryPath); | |
162 | + if (ftc.FolderExists) | |
163 | + { | |
164 | + var di = new DirectoryInfo(ftc.Xml_DirectoryPath); | |
165 | + ftc.SizeFolderTotal = FileCleanerManagerCore.DirSize(di,"*","",ftc.Xml_Recurse); | |
166 | + ftc.SizeSelectedBeforeClean = FileCleanerManagerCore.DirSize(di, ftc.Xml_IncludeMask, ftc.Xml_IncludeFullpathRegexp, ftc.Xml_Recurse); | |
167 | + ftc.SizeSelectedCleaned = FileCleanerManagerCore.CleanFolderFiles(di,ftc,delete:false); | |
168 | + } | |
169 | + return ftc; | |
170 | + } | |
171 | + #endregion private CollectFolderInfo | |
172 | + #endregion private methods | |
173 | + } | |
174 | + #endregion FileCleanerManager class | |
175 | + | |
176 | + #region class FileCleanerManagerCore | |
177 | + public static class FileCleanerManagerCore | |
178 | + { | |
179 | + #region public GetDirSize | |
180 | + public static long DirSize(DirectoryInfo d, string filenamemask, string filefullpathregex, bool recurse) | |
181 | + { | |
182 | + long size = 0; | |
183 | + // Add file sizes. | |
184 | + FileInfo[] fis = d.GetFiles(filenamemask, SearchOption.TopDirectoryOnly); | |
185 | + foreach (FileInfo fi in fis) { if (Regex.Match(fi.FullName, filefullpathregex).Success) { size += fi.Length; } } | |
186 | + // Add subdirectory sizes. | |
187 | + if (recurse) | |
188 | + { | |
189 | + DirectoryInfo[] dis = d.GetDirectories(); | |
190 | + foreach (DirectoryInfo di in dis) { size += DirSize(di, filenamemask, filefullpathregex, recurse); } | |
191 | + } | |
192 | + return size; | |
193 | + } | |
194 | + #endregion public GetDirSize | |
195 | + #region public FileIsToDelete | |
196 | + public static bool FileIsToDelete(FileInfo fi, FolderToClean ftc) | |
197 | + { | |
198 | + var rgx = new Regex(ftc.Xml_IncludeFullpathRegexp); | |
199 | + var rgxmatch = rgx.Match(fi.FullName); | |
200 | + if (rgxmatch.Success) | |
201 | + { | |
202 | + var daystodelete = ftc.Xml_CleanupDays; | |
203 | + var conditionlist = ftc.Xml_ConditionList; | |
204 | + if (conditionlist == null || !conditionlist.Any()) { return true; } | |
205 | + | |
206 | + bool fileistodeleteResult = !ftc.Xml_OrConditionList; | |
207 | + | |
208 | + var groupnames = rgx.GetGroupNames(); | |
209 | + var groupnamevalues = new Dictionary<string, string>(); | |
210 | + foreach (var rgxgn in groupnames) { groupnamevalues.Add(rgxgn, rgxmatch.Groups[rgxgn].Value); } | |
211 | + | |
212 | + foreach (var c in ftc.Xml_ConditionList) | |
213 | + { | |
214 | + bool conditionresult = false; | |
215 | + if (c.Type == FolderToClean.ConditionType.TimeStampInName) | |
216 | + { | |
217 | + var fileTSstr = VRH.Common.StringConstructor.ResolveConstructor<string>(groupnamevalues, c.TimestampConstructor, "{}"); | |
218 | + try { var fileTS = DateTime.Parse(fileTSstr); conditionresult = DateTime.Now.Subtract(fileTS).TotalDays > c.Limit; } | |
219 | + catch | |
220 | + { | |
221 | + var tscn = nameof(FolderToClean.XmlStructure.FolderToClean.Conditions.Condition.Attributes.TimestampConstructor); | |
222 | + var fprn = nameof(FolderToClean.XmlStructure.FolderToClean.IncludeFullpathRegexp); | |
223 | + throw new Exception( | |
224 | + $"Error in condition, type {FolderToClean.ConditionType.TimeStampInName}. {tscn} or {fprn} value incorrect!" | |
225 | + + $"\n Folder: {ftc.Xml_DirectoryPath}" | |
226 | + + $"\n {tscn} : {c.TimestampConstructor}" | |
227 | + + $"\n {tscn} after substitution: {fileTSstr}"); | |
228 | + } | |
229 | + } | |
230 | + else if (c.Type == FolderToClean.ConditionType.CreationTime) | |
231 | + { | |
232 | + conditionresult = DateTime.Now.Subtract(fi.CreationTime).TotalDays > c.Limit; | |
233 | + } | |
234 | + else if (c.Type == FolderToClean.ConditionType.LastAccessTime) | |
235 | + { | |
236 | + conditionresult = DateTime.Now.Subtract(fi.LastAccessTime).TotalDays > c.Limit; | |
237 | + } | |
238 | + else if (c.Type == FolderToClean.ConditionType.LastWriteTime) | |
239 | + { | |
240 | + conditionresult = DateTime.Now.Subtract(fi.LastWriteTime).TotalDays > c.Limit; | |
241 | + } | |
242 | + else if (c.Type == FolderToClean.ConditionType.Length) | |
243 | + { | |
244 | + conditionresult = fi.Length > c.Limit; | |
245 | + } | |
246 | + | |
247 | + fileistodeleteResult = ftc.Xml_OrConditionList ? fileistodeleteResult || conditionresult : fileistodeleteResult = fileistodeleteResult && conditionresult; | |
248 | + if ((ftc.Xml_OrConditionList && fileistodeleteResult) || (!ftc.Xml_OrConditionList && !fileistodeleteResult)) { break; } | |
249 | + } | |
250 | + return fileistodeleteResult; | |
251 | + } | |
252 | + return false; | |
253 | + } | |
254 | + #endregion public FileIsToDelete | |
255 | + #region public CleanFiles | |
256 | + public static long CleanFolderFiles(DirectoryInfo d,FolderToClean ftc, bool delete) | |
257 | + { | |
258 | + int daystodelete = ftc.Xml_CleanupDays; | |
259 | + long cleanedsize = 0; | |
260 | + // Add file sizes. | |
261 | + FileInfo[] fis = d.GetFiles(ftc.Xml_IncludeMask, SearchOption.TopDirectoryOnly); | |
262 | + foreach (FileInfo fi in fis) | |
263 | + { | |
264 | + if (FileIsToDelete(fi, ftc)) | |
265 | + { | |
266 | + var fl = fi.Length; | |
267 | + try | |
268 | + { | |
269 | + if (delete) { File.Delete(fi.FullName); } | |
270 | + cleanedsize += fl; | |
271 | + } | |
272 | + catch { } | |
273 | + } | |
274 | + } | |
275 | + // Add subdirectory sizes. | |
276 | + if (ftc.Xml_Recurse) | |
277 | + { | |
278 | + foreach (DirectoryInfo di in d.GetDirectories()) { cleanedsize += CleanFolderFiles(di, ftc, delete); } | |
279 | + } | |
280 | + if (ftc.Xml_RemoveEmptyFolder && DirSize(d, ftc.Xml_IncludeMask, ftc.Xml_IncludeFullpathRegexp, ftc.Xml_Recurse) == 0) | |
281 | + { | |
282 | + try { Directory.Delete(d.FullName, ftc.Xml_Recurse); } catch { } | |
283 | + } | |
284 | + return cleanedsize; | |
285 | + } | |
286 | + #endregion public CleanFiles | |
287 | + } | |
288 | + #endregion class FileCleanerManagerCore | |
289 | + | |
290 | + #region FileCleanerManagerCoreXmlProcessor class | |
291 | + public class FileCleanerManagerCoreXmlProcessor : XmlParser | |
292 | + { | |
293 | + private List<FolderToClean> _foldertocleanlist; | |
294 | + private int commoncleanupdays; | |
295 | + #region constructor | |
296 | + public FileCleanerManagerCoreXmlProcessor(string xmlcs, string basefolder, string lcid) : base(xmlcs, basefolder, lcid, null) | |
297 | + { | |
298 | + _foldertocleanlist = new List<FolderToClean>(); | |
299 | + commoncleanupdays = GetValue(nameof(FolderToClean.XmlStructure.Attributes.CleanupDays),this.RootElement, FolderToClean.XmlStructure.Attributes.CleanupDays.Values.DEFAULT); | |
300 | + var ftcxmllist = GetAllXElements(nameof(FolderToClean.XmlStructure.FolderToClean)); | |
301 | + if (ftcxmllist != null && ftcxmllist.Any()) | |
302 | + { | |
303 | + foreach (var ftcxml in ftcxmllist) { var ws = new FolderToClean(ftcxml, commoncleanupdays); if (ws.Valid) { _foldertocleanlist.Add(ws); } } | |
304 | + } | |
305 | + } | |
306 | + #endregion constructor | |
307 | + #region GetDefinitionList | |
308 | + public List<FolderToClean> GetDefinitionList() { return _foldertocleanlist; } | |
309 | + #endregion GetDefinitionList | |
310 | + } | |
311 | + #endregion FileCleanerManagerCoreXmlProcessor class | |
312 | + #region WindowsService class | |
313 | + public class FolderToClean : XmlLinqBase | |
314 | + { | |
315 | + #region fields | |
316 | + public bool Valid = true; | |
317 | + public string Xml_DirectoryPath; | |
318 | + public bool Xml_Recurse; | |
319 | + public bool Xml_RemoveEmptyFolder; | |
320 | + public string Xml_IncludeMask; | |
321 | + public string Xml_IncludeFullpathRegexp; | |
322 | + public bool Xml_OrConditionList = true; | |
323 | + public List<Condition> Xml_ConditionList; | |
324 | + public int Xml_CleanupDays; | |
325 | + | |
326 | + public bool FolderExists; | |
327 | + public long SizeFolderTotal; | |
328 | + public long SizeSelectedBeforeClean; | |
329 | + public long SizeSelectedAfterClean { get { return SizeSelectedBeforeClean - SizeSelectedCleaned; } } | |
330 | + public long SizeSelectedCleaned; | |
331 | + #endregion fields | |
332 | + | |
333 | + #region basic constructor | |
334 | + public FolderToClean() { } | |
335 | + #endregion basic constructor | |
336 | + #region xml constructor | |
337 | + public FolderToClean(XElement foldertocleanxml,int commoncleanupdays) | |
338 | + { | |
339 | + Valid = true; | |
340 | + string ATTRIBUTEMANDATORY = nameof(XmlStructure.FolderToClean) + " attribute is mandatory! Name: {0}"; | |
341 | + Xml_DirectoryPath = foldertocleanxml.Attribute(XName.Get(nameof(XmlStructure.FolderToClean.Attributes.Directory)))?.Value; | |
342 | + if (string.IsNullOrWhiteSpace(Xml_DirectoryPath)) { throw new ApplicationException(string.Format(ATTRIBUTEMANDATORY, nameof(XmlStructure.FolderToClean.Attributes.Directory))); } | |
343 | + Xml_Recurse = GetValue(nameof(XmlStructure.FolderToClean.Attributes.Recurse), foldertocleanxml, XmlStructure.FolderToClean.Attributes.Recurse.Values.DEFAULT); | |
344 | + Xml_RemoveEmptyFolder = GetValue(nameof(XmlStructure.FolderToClean.Attributes.RemoveEmptyFolder), foldertocleanxml, XmlStructure.FolderToClean.Attributes.RemoveEmptyFolder.Values.DEFAULT); | |
345 | + Xml_IncludeMask = GetValue(nameof(XmlStructure.FolderToClean.Attributes.IncludeMask), foldertocleanxml, XmlStructure.FolderToClean.Attributes.IncludeMask.Values.DEFAULT); | |
346 | + Xml_IncludeFullpathRegexp = GetValue(GetXElement(foldertocleanxml,nameof(XmlStructure.FolderToClean.IncludeFullpathRegexp)), XmlStructure.FolderToClean.IncludeFullpathRegexp.Values.DEFAULT); | |
347 | + Xml_CleanupDays = GetValue(GetXElement(foldertocleanxml,nameof(XmlStructure.FolderToClean.Attributes.CleanupDays)), commoncleanupdays); | |
348 | + Xml_ConditionList = new List<Condition>(); | |
349 | + //var conditionxmlList = GetAllXElements(foldertocleanxml, nameof(XmlStructure.FolderToClean.Conditions), nameof(XmlStructure.FolderToClean.Conditions.Condition)); | |
350 | + var conditionsxml = foldertocleanxml.Element(XName.Get(nameof(XmlStructure.FolderToClean.Conditions))); | |
351 | + var conditionxmlList = conditionsxml?.Elements(XName.Get(nameof(XmlStructure.FolderToClean.Conditions.Condition))); | |
352 | + if (conditionxmlList!=null && conditionxmlList.Any()) | |
353 | + { | |
354 | + Xml_OrConditionList = GetValue(nameof(XmlStructure.FolderToClean.Conditions.Attributes.OrConditionList), conditionsxml, XmlStructure.FolderToClean.Conditions.Attributes.OrConditionList.Values.DEFAULT); | |
355 | + foreach (var conditionxml in conditionxmlList) { Xml_ConditionList.Add(new Condition(conditionxml)); } | |
356 | + } | |
357 | + } | |
358 | + #endregion xml constructor | |
359 | + #region cloner constructor | |
360 | + public FolderToClean(FolderToClean ftc) | |
361 | + { | |
362 | + Valid = ftc.Valid; | |
363 | + Xml_DirectoryPath = ftc.Xml_DirectoryPath; | |
364 | + Xml_Recurse = ftc.Xml_Recurse; | |
365 | + Xml_RemoveEmptyFolder = ftc.Xml_RemoveEmptyFolder; | |
366 | + Xml_IncludeMask = ftc.Xml_IncludeMask; | |
367 | + Xml_IncludeFullpathRegexp = ftc.Xml_IncludeFullpathRegexp; | |
368 | + Xml_OrConditionList = ftc.Xml_OrConditionList; | |
369 | + Xml_CleanupDays = ftc.Xml_CleanupDays; | |
370 | + Xml_ConditionList = ftc.Xml_ConditionList.Select(c=>new Condition(c)).ToList(); ; | |
371 | + } | |
372 | + #endregion cloner constructor | |
373 | + #region Condition | |
374 | + public enum ConditionType { Length, TimeStampInName, LastWriteTime, LastAccessTime, CreationTime, } | |
375 | + public class Condition: XmlLinqBase | |
376 | + { | |
377 | + #region cloner constructor | |
378 | + public Condition(Condition c) | |
379 | + { | |
380 | + Type = c.Type; | |
381 | + TimestampConstructor = c.TimestampConstructor; | |
382 | + Limit = c.Limit; | |
383 | + } | |
384 | + #endregion cloner constructor | |
385 | + #region constructor | |
386 | + public Condition(XElement cxml) | |
387 | + { | |
388 | + var typestr = GetValue(nameof(XmlStructure.FolderToClean.Conditions.Condition.Attributes.Type), cxml, XmlStructure.FolderToClean.Conditions.Condition.Attributes.Type.Values.DEFAULT); | |
389 | + this.Type = (ConditionType)Enum.Parse(typeof(ConditionType),typestr); | |
390 | + TimestampConstructor = GetValue(nameof(XmlStructure.FolderToClean.Conditions.Condition.Attributes.TimestampConstructor), cxml, XmlStructure.FolderToClean.Conditions.Condition.Attributes.TimestampConstructor.Values.DEFAULT); | |
391 | + Limit = GetValue(nameof(XmlStructure.FolderToClean.Conditions.Condition.Attributes.Limit), cxml, XmlStructure.FolderToClean.Conditions.Condition.Attributes.Limit.Values.DEFAULT); | |
392 | + } | |
393 | + #endregion constructor | |
394 | + public ConditionType Type; | |
395 | + public string TimestampConstructor; | |
396 | + public int Limit; | |
397 | + } | |
398 | + #endregion Condition | |
399 | + #region XmlStructure | |
400 | + public static class XmlStructure | |
401 | + { | |
402 | + public static class Attributes | |
403 | + { | |
404 | + public static class CleanupDays | |
405 | + { | |
406 | + public static class Values | |
407 | + { | |
408 | + public const int DEFAULT = 7; | |
409 | + } | |
410 | + } | |
411 | + } | |
412 | + public static class FolderToClean | |
413 | + { | |
414 | + public static class Attributes | |
415 | + { | |
416 | + public static class Directory { } | |
417 | + public static class CleanupDays | |
418 | + { | |
419 | + public static class Values | |
420 | + { | |
421 | + public const int DEFAULT = XmlStructure.Attributes.CleanupDays.Values.DEFAULT; | |
422 | + } | |
423 | + } | |
424 | + public static class Recurse | |
425 | + { | |
426 | + public static class Values | |
427 | + { | |
428 | + public const bool DEFAULT = false; | |
429 | + } | |
430 | + } | |
431 | + public static class RemoveEmptyFolder | |
432 | + { | |
433 | + public static class Values | |
434 | + { | |
435 | + public const bool DEFAULT = false; | |
436 | + } | |
437 | + } | |
438 | + public static class IncludeMask | |
439 | + { | |
440 | + public static class Values | |
441 | + { | |
442 | + public const string DEFAULT = "*.*"; | |
443 | + } | |
444 | + } | |
445 | + } | |
446 | + public static class IncludeFullpathRegexp | |
447 | + { | |
448 | + public static class Values | |
449 | + { | |
450 | + public const string DEFAULT = ""; | |
451 | + } | |
452 | + } | |
453 | + public static class Conditions | |
454 | + { | |
455 | + public static class Attributes | |
456 | + { | |
457 | + public static class OrConditionList | |
458 | + { | |
459 | + public static class Values | |
460 | + { | |
461 | + public const bool DEFAULT = true; | |
462 | + } | |
463 | + } | |
464 | + } | |
465 | + public static class Condition | |
466 | + { | |
467 | + public static class Attributes | |
468 | + { | |
469 | + public static class Type | |
470 | + { | |
471 | + public static class Values | |
472 | + { | |
473 | + public const string DEFAULT = nameof(ConditionType.LastWriteTime); | |
474 | + public static class TimeStampInName { } | |
475 | + public static class Length { } | |
476 | + public static class LastWriteTime { } | |
477 | + public static class LastAccessTime { } | |
478 | + public static class CreationTime { } | |
479 | + } | |
480 | + } | |
481 | + public static class TimestampConstructor | |
482 | + { | |
483 | + public static class Values | |
484 | + { | |
485 | + public const string DEFAULT = "{YEAR}.{MONTH}.{DAY} {HOUR}:{MINUTE}:{SECOND}"; | |
486 | + } | |
487 | + } | |
488 | + public static class Limit | |
489 | + { | |
490 | + public static class Values | |
491 | + { | |
492 | + public const int DEFAULT = XmlStructure.Attributes.CleanupDays.Values.DEFAULT; | |
493 | + } | |
494 | + } | |
495 | + } | |
496 | + } | |
497 | + } | |
498 | + } | |
499 | + } | |
500 | + #endregion XmlStructure | |
501 | + } | |
502 | + #endregion WindowsService class | |
503 | + | |
504 | +} | ... | ... |
Vrh.Log4Pro.MaintenanceConsole/Manager - MaintenanceToolManager.cs
0 → 100644
... | ... | @@ -0,0 +1,124 @@ |
1 | +using System; | |
2 | +using System.IO; | |
3 | +using System.Configuration.Install; | |
4 | +using System.Collections.Generic; | |
5 | +using System.Linq; | |
6 | +using System.ServiceProcess; | |
7 | +using System.Text; | |
8 | +using System.Threading; | |
9 | +using System.Threading.Tasks; | |
10 | + | |
11 | +using Microsoft.Web.Administration; | |
12 | +using System.Management; | |
13 | +using System.Diagnostics; | |
14 | + | |
15 | +using Vrh.XmlProcessing; | |
16 | +using System.Xml.Linq; | |
17 | +using System.Text.RegularExpressions; | |
18 | + | |
19 | +namespace Vrh.Log4Pro.MaintenanceConsole | |
20 | +{ | |
21 | + #region MaintenanceTools class | |
22 | + public static class MaintenanceToolManager | |
23 | + { | |
24 | + #region Execute | |
25 | + public static object Execute(object o1 = null, object o2 = null) | |
26 | + { | |
27 | + string xmlcs = "file=Config.Xml;element=WindowsServices;"; | |
28 | + var config = new MaintenanceToolsXmlProcessor(xmlcs, "", "hu-HU"); | |
29 | + | |
30 | + var menufunctions = new Menu("Maintenance Tools", "Select function!") | |
31 | + .AddMenuItem(new Menu.Item("RGX", "Regex tester", RegexTester)) | |
32 | + .AddMenuItem(new Menu.Item("TL1", "Tool #1", Tool1)) | |
33 | + .AddMenuItem(new Menu.Item("TL2", "Tool #2", Tool2)) | |
34 | + .SetSelectionMode(Menu.SelectionMode.Single); | |
35 | + | |
36 | + while (true) | |
37 | + { | |
38 | + Menu.Selection sr; | |
39 | + | |
40 | + menufunctions.DisplayTitle(); | |
41 | + menufunctions.DisplayItems(); | |
42 | + sr = menufunctions.Select(); | |
43 | + if (sr.Result == Menu.SelectionResult.Exit) { break; } | |
44 | + else if (sr.Result == Menu.SelectionResult.None) { continue; } | |
45 | + else if (sr.Result == Menu.SelectionResult.Error) { continue; } | |
46 | + menufunctions.SetParameters(sr,config); | |
47 | + menufunctions.Execute(sr.SelectedKeyList); | |
48 | + } | |
49 | + return null; | |
50 | + } | |
51 | + #endregion Execute | |
52 | + | |
53 | + #region First level Executors with UI | |
54 | + #region RegexTester | |
55 | + private static object RegexTester(object parameter, object o) | |
56 | + { | |
57 | + var config = parameter as MaintenanceToolsXmlProcessor; | |
58 | + var regexptesterconfig = config.RegexpTesterConfig; | |
59 | + while(true) | |
60 | + { | |
61 | + var regexstr = ColorConsole.ReadLine($"Enter REGEX to test with:", ConsoleColor.Yellow); | |
62 | + if (regexstr == "EX") { break; } | |
63 | + var teststr = ColorConsole.ReadLine($"Enter STRING to test:", ConsoleColor.Yellow); | |
64 | + if (teststr == "EX") { break; } | |
65 | + | |
66 | + var rgx = new Regex(regexstr, RegexOptions.None); | |
67 | + var regexmatch = rgx.Match(teststr); | |
68 | + if (!regexmatch.Success) | |
69 | + { | |
70 | + ColorConsole.WriteLine($"No match.", ConsoleColor.Red); | |
71 | + } | |
72 | + else | |
73 | + { | |
74 | + ColorConsole.WriteLine($"Match.", ConsoleColor.Green); | |
75 | + ColorConsole.WriteLine($"Named groups:"); | |
76 | + var groups = new Dictionary<string, string>(); | |
77 | + foreach (var groupname in rgx.GetGroupNames()) | |
78 | + { | |
79 | + ColorConsole.Write(groupname,bracket:"[]", suffix: " = "); | |
80 | + ColorConsole.WriteLine(regexmatch.Groups[groupname].Value, ConsoleColor.Yellow); | |
81 | + } | |
82 | + } | |
83 | + ColorConsole.ReadLine($"Press any key to continue..."); | |
84 | + } | |
85 | + return o; | |
86 | + } | |
87 | + #endregion RegexTester | |
88 | + #region Tool templates | |
89 | + private static object Tool1(object parameter, object o) | |
90 | + { | |
91 | + var config = parameter as MaintenanceToolsXmlProcessor; | |
92 | + ColorConsole.ReadLine($"{nameof(Tool1)} is not ready yet...",ConsoleColor.Yellow); | |
93 | + return o; | |
94 | + } | |
95 | + private static object Tool2(object parameter, object o) | |
96 | + { | |
97 | + var config = parameter as MaintenanceToolsXmlProcessor; | |
98 | + ColorConsole.ReadLine($"{nameof(Tool2)} is not ready yet...", ConsoleColor.Yellow); | |
99 | + return o; | |
100 | + } | |
101 | + #endregion Tool templates | |
102 | + #endregion First level Executors with UI | |
103 | + } | |
104 | + #endregion MaintenanceTools class | |
105 | + | |
106 | + #region MaintenanceToolsXmlProcessor class | |
107 | + public class MaintenanceToolsXmlProcessor : XmlParser | |
108 | + { | |
109 | + public XElement RegexpTesterConfig; | |
110 | + #region constructor | |
111 | + public MaintenanceToolsXmlProcessor(string xmlcs, string basefolder, string lcid) : base(xmlcs, basefolder, lcid, null) | |
112 | + { | |
113 | + RegexpTesterConfig = GetXElement(nameof(XmlStructure.RegexpTester)); | |
114 | + } | |
115 | + #endregion constructor | |
116 | + #region XmlStructure | |
117 | + public static class XmlStructure | |
118 | + { | |
119 | + public static class RegexpTester { } | |
120 | + } | |
121 | + #endregion XmlStructure | |
122 | + } | |
123 | + #endregion MaintenanceToolsXmlProcessor class | |
124 | +} | ... | ... |
Vrh.Log4Pro.MaintenanceConsole/WebApplicationManager.cs renamed to Vrh.Log4Pro.MaintenanceConsole/Manager - WebApplicationManager.cs
Vrh.Log4Pro.MaintenanceConsole/WindowsServiceManager.cs renamed to Vrh.Log4Pro.MaintenanceConsole/Manager - WindowsServiceManager.cs
Vrh.Log4Pro.MaintenanceConsole/Program.cs
... | ... | @@ -28,6 +28,9 @@ namespace Vrh.Log4Pro.MaintenanceConsole |
28 | 28 | var mm = new Menu("Log4ProIS Maintenance Console") |
29 | 29 | .AddMenuItem(new Menu.Item("WAM", "Web Application Manager", WebApplicationManager.Execute)) |
30 | 30 | .AddMenuItem(new Menu.Item("WSM", "Windows Service Manager", WindowsServiceManager.Execute)) |
31 | + .AddMenuItem(new Menu.Item("FCL", "File Cleaner Manager", FileCleanerManager.Execute)) | |
32 | + .AddMenuItem(new Menu.ItemSeparator('-')) | |
33 | + .AddMenuItem(new Menu.Item("TOL", "Maintenance tools", MaintenanceToolManager.Execute)) | |
31 | 34 | .SetSelectionMode(Menu.SelectionMode.Single); |
32 | 35 | |
33 | 36 | mm.ExecuteMenu(); | ... | ... |
Vrh.Log4Pro.MaintenanceConsole/Vrh.Log4Pro.MaintenanceConsole.csproj
1 | 1 | <?xml version="1.0" encoding="utf-8"?> |
2 | 2 | <Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> |
3 | + <Import Project="..\packages\EntityFramework.6.4.0\build\EntityFramework.props" Condition="Exists('..\packages\EntityFramework.6.4.0\build\EntityFramework.props')" /> | |
3 | 4 | <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" /> |
4 | 5 | <PropertyGroup> |
5 | 6 | <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> |
... | ... | @@ -12,6 +13,8 @@ |
12 | 13 | <FileAlignment>512</FileAlignment> |
13 | 14 | <AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects> |
14 | 15 | <Deterministic>true</Deterministic> |
16 | + <NuGetPackageImportStamp> | |
17 | + </NuGetPackageImportStamp> | |
15 | 18 | </PropertyGroup> |
16 | 19 | <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> |
17 | 20 | <PlatformTarget>AnyCPU</PlatformTarget> |
... | ... | @@ -33,6 +36,12 @@ |
33 | 36 | <WarningLevel>4</WarningLevel> |
34 | 37 | </PropertyGroup> |
35 | 38 | <ItemGroup> |
39 | + <Reference Include="EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL"> | |
40 | + <HintPath>..\packages\EntityFramework.6.4.0\lib\net45\EntityFramework.dll</HintPath> | |
41 | + </Reference> | |
42 | + <Reference Include="EntityFramework.SqlServer, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL"> | |
43 | + <HintPath>..\packages\EntityFramework.6.4.0\lib\net45\EntityFramework.SqlServer.dll</HintPath> | |
44 | + </Reference> | |
36 | 45 | <Reference Include="Microsoft.Web.Administration, Version=10.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL"> |
37 | 46 | <HintPath>..\packages\Microsoft.Web.Administration.11.1.0\lib\netstandard1.5\Microsoft.Web.Administration.dll</HintPath> |
38 | 47 | </Reference> |
... | ... | @@ -47,6 +56,7 @@ |
47 | 56 | <HintPath>..\packages\System.AppContext.4.1.0\lib\net46\System.AppContext.dll</HintPath> |
48 | 57 | </Reference> |
49 | 58 | <Reference Include="System.ComponentModel.Composition" /> |
59 | + <Reference Include="System.ComponentModel.DataAnnotations" /> | |
50 | 60 | <Reference Include="System.Configuration.Install" /> |
51 | 61 | <Reference Include="System.Console, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"> |
52 | 62 | <HintPath>..\packages\System.Console.4.0.0\lib\net46\System.Console.dll</HintPath> |
... | ... | @@ -135,6 +145,9 @@ |
135 | 145 | <Reference Include="Microsoft.CSharp" /> |
136 | 146 | <Reference Include="System.Data" /> |
137 | 147 | <Reference Include="System.Xml" /> |
148 | + <Reference Include="VRH.Common, Version=2.19.0.0, Culture=neutral, processorArchitecture=MSIL"> | |
149 | + <HintPath>..\packages\VRH.Common.2.19.0\lib\net45\VRH.Common.dll</HintPath> | |
150 | + </Reference> | |
138 | 151 | <Reference Include="Vrh.XmlProcessing, Version=1.23.0.0, Culture=neutral, processorArchitecture=MSIL"> |
139 | 152 | <HintPath>..\packages\Vrh.XmlProcessing.1.23.0\lib\net45\Vrh.XmlProcessing.dll</HintPath> |
140 | 153 | </Reference> |
... | ... | @@ -143,8 +156,10 @@ |
143 | 156 | <Compile Include="ConsoleFunction - CommandLineParser.cs" /> |
144 | 157 | <Compile Include="ConsoleFunction - ColorConsole.cs" /> |
145 | 158 | <Compile Include="ConsoleFunction - Menu.cs" /> |
146 | - <Compile Include="WindowsServiceManager.cs" /> | |
147 | - <Compile Include="WebApplicationManager.cs" /> | |
159 | + <Compile Include="Manager - WindowsServiceManager.cs" /> | |
160 | + <Compile Include="Manager - FileCleanerManager.cs" /> | |
161 | + <Compile Include="Manager - MaintenanceToolManager.cs" /> | |
162 | + <Compile Include="Manager - WebApplicationManager.cs" /> | |
148 | 163 | <Compile Include="Program.cs" /> |
149 | 164 | <Compile Include="Properties\AssemblyInfo.cs" /> |
150 | 165 | </ItemGroup> |
... | ... | @@ -153,6 +168,7 @@ |
153 | 168 | <CopyToOutputDirectory>Always</CopyToOutputDirectory> |
154 | 169 | </None> |
155 | 170 | <None Include="packages.config" /> |
171 | + <None Include="Vrh.NugetModuls.Documentations\VRH.Common\ReadMe.md" /> | |
156 | 172 | <None Include="Vrh.NugetModuls.Documentations\Vrh.XmlProcessing\ReadMe.md" /> |
157 | 173 | </ItemGroup> |
158 | 174 | <ItemGroup> |
... | ... | @@ -164,4 +180,12 @@ |
164 | 180 | </Content> |
165 | 181 | </ItemGroup> |
166 | 182 | <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> |
183 | + <Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild"> | |
184 | + <PropertyGroup> | |
185 | + <ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText> | |
186 | + </PropertyGroup> | |
187 | + <Error Condition="!Exists('..\packages\EntityFramework.6.4.0\build\EntityFramework.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\EntityFramework.6.4.0\build\EntityFramework.props'))" /> | |
188 | + <Error Condition="!Exists('..\packages\EntityFramework.6.4.0\build\EntityFramework.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\EntityFramework.6.4.0\build\EntityFramework.targets'))" /> | |
189 | + </Target> | |
190 | + <Import Project="..\packages\EntityFramework.6.4.0\build\EntityFramework.targets" Condition="Exists('..\packages\EntityFramework.6.4.0\build\EntityFramework.targets')" /> | |
167 | 191 | </Project> |
168 | 192 | \ No newline at end of file | ... | ... |
Vrh.Log4Pro.MaintenanceConsole/Vrh.NugetModuls.Documentations/VRH.Common/ReadMe.md
0 → 100644
... | ... | @@ -0,0 +1,297 @@ |
1 | +# Vrh.Common | |
2 | +A modul a Vonalkód Rendszerház fejlesztési környezetében szabványosított és | |
3 | +hasznosan alkalmazható eszközeinek gyűjtőhelye. | |
4 | + | |
5 | +> Igényelt minimális framework verzió: **4.5** | |
6 | + | |
7 | +> Teljes funkcionalitás és hatékonyság kihasználásához szükséges legalacsonyabb framework verzió: **4.5** | |
8 | + | |
9 | +# Főbb összetevők | |
10 | +### Interfészek | |
11 | +* **[IManage](##IManage)** | |
12 | + | |
13 | +### Standard osztályok | |
14 | +* **[CheckListJSON](##CheckListJSON)** | |
15 | +* **[ReturnInfoJSON](##ReturnInfoJSON)** | |
16 | +* **[SelectListJSON](##SelectListJSON)** | |
17 | + | |
18 | +## IManage | |
19 | +Generikus interfész, melyben azt a típust kell megadni, amely menedzselését végzi. | |
20 | +```javascript | |
21 | +/// <summary> | |
22 | +/// Meghatározza és előírja egy karbantartást és hozzáférést | |
23 | +/// biztosító osztály elvárt tulajdonságait és módszereit. | |
24 | +/// </summary> | |
25 | +public interface IManage<T> | |
26 | +{ | |
27 | + /// <summary> | |
28 | + /// A kezelt típust össze egyedét szolgáltató tulajdonság. | |
29 | + /// </summary> | |
30 | + List<T> All { get; } | |
31 | + | |
32 | + /// <summary> | |
33 | + /// A kezelt típus egy elemét adja vissza az egyedi azonosító segítségével. | |
34 | + /// </summary> | |
35 | + /// <param name="id">Az elem egyedi azonosítója.</param> | |
36 | + /// <returns></returns> | |
37 | + T Get(int id); | |
38 | + /// <summary> | |
39 | + /// A kezelt típus egy elemét adja vissza a megadott név segítségével. | |
40 | + /// </summary> | |
41 | + /// <param name="name">Az elem egyedi neve.</param> | |
42 | + /// <returns></returns> | |
43 | + T Get(string name); | |
44 | + | |
45 | + /// <summary> | |
46 | + /// Létrehozza a kezelt típus egy elemét. | |
47 | + /// </summary> | |
48 | + /// <param name="item">A kezelt típus egy eleme, amit hozzá kell adni.</param> | |
49 | + void Create(T item); | |
50 | + | |
51 | + /// <summary> | |
52 | + /// A kezelt típus egy elemét törli az egyedi azonosító alapján. | |
53 | + /// </summary> | |
54 | + /// <param name="id">A törlendő elem egyedi azonosítója.</param> | |
55 | + void Delete(int id); | |
56 | + /// <summary> | |
57 | + /// A kezelt típus egy elemét törli az egyedi neve alapján. | |
58 | + /// </summary> | |
59 | + /// <param name="name">A törlendő elem egyedi neve.</param> | |
60 | + void Delete(string name); | |
61 | + | |
62 | + /// <summary> | |
63 | + /// A kezelt típus egy elemének módosítása. | |
64 | + /// Ha nem létezik az hiba. | |
65 | + /// </summary> | |
66 | + /// <param name="item">A kezelt típus egy eleme.</param> | |
67 | + void Update(T item); | |
68 | +} | |
69 | +``` | |
70 | + | |
71 | +## CheckListJSON | |
72 | +```javascript | |
73 | +/// <summary> | |
74 | +/// Egy meghívott akció válaszüzenetének egy lehetséges meghatározott szerkezete. | |
75 | +/// Valamely lista ellenőrzéshez használható, amelyben a Checked oszlopban jelölhető az ellenőrzés eredménye. | |
76 | +/// </summary> | |
77 | +public class CheckListJSON | |
78 | +{ | |
79 | + /// <summary> | |
80 | + /// Az ellenőrzendő illetve ellenőrzött azonosító. | |
81 | + /// </summary> | |
82 | + public string Value { get; set; } | |
83 | + | |
84 | + /// <summary> | |
85 | + /// Az ellenőrzéskor megtalált név vagy leíró. | |
86 | + /// </summary> | |
87 | + public string Text { get; set; } | |
88 | + | |
89 | + /// <summary> | |
90 | + /// Az ellenőrzés eredményét jelző logikai érték, mely a felhasználáskor | |
91 | + /// az üzleti logikától függ. | |
92 | + /// </summary> | |
93 | + public bool Checked { get; set; } | |
94 | +} | |
95 | +``` | |
96 | + | |
97 | +## ReturnInfoJSON | |
98 | +```javascript | |
99 | +/// <summary> | |
100 | +/// Egy meghívott akció válaszüzenetének egy lehetséges meghatározott szerkezete. | |
101 | +/// A válasz érték (ReturnValue) és üzenet (ReturnMessage) formájú. | |
102 | +/// Sikeres végrehajtás esetén mindig 0 legyen a ReturnValue. | |
103 | +/// Sikertelen esetben ettől eltérő, de ha nincs egyéb ok, akkor hiba esetén legyen -1. | |
104 | +/// Alapértelmezett érték: 0, "Az indított akció sikeresen lezajlott!" } | |
105 | +/// </summary> | |
106 | +public class ReturnInfoJSON | |
107 | +{ | |
108 | + /// <summary> | |
109 | + /// Egy reprezentatív értéke, mely a sikerességtől függ. | |
110 | + /// Ha nincs hiba az akció végrehajtásában, akkor 0 legyen az értéke. | |
111 | + /// Alapértelmezett értéke: 0 | |
112 | + /// </summary> | |
113 | + public int ReturnValue { get; set; } = 0; | |
114 | + | |
115 | + /// <summary> | |
116 | + /// Az akció üzenete. Hiba esetén a hibaüzenet szövege. | |
117 | + /// Alapértelmezett értéke: "Az indított akció sikeresen lezajlott!" | |
118 | + /// </summary> | |
119 | + public string ReturnMessage { get; set; } = "Az indított akció sikeresen lezajlott!"; | |
120 | +} | |
121 | +``` | |
122 | + | |
123 | +## SelectListJSON | |
124 | +```javascript | |
125 | +/// <summary> | |
126 | +/// Egy meghívott akció válaszüzenetének egy lehetséges meghatározott szerkezete. | |
127 | +/// Egy listához használható, mely értékeit és azonosítóit fel lehet használni. | |
128 | +/// </summary> | |
129 | +/// <remarks> | |
130 | +/// Egyenértékű a System.Web.Mvc.SelectListItem osztállyal, de nem onnan származik. | |
131 | +/// Az ott szereplő leírás: | |
132 | +/// "Represents the selected item in an instance of the System.Web.Mvc.SelectList class." | |
133 | +/// </remarks> | |
134 | +public class SelectListJSON | |
135 | +{ | |
136 | + /// <summary> | |
137 | + /// Jelzi, hogy ez az elem a listában letiltott. | |
138 | + /// </summary> | |
139 | + public bool Disabled { get; set; } | |
140 | + | |
141 | + /// <summary> | |
142 | + /// A csoport jelölése. Alapértelmezett értéke: null | |
143 | + /// </summary> | |
144 | + public SelectListGroup Group { get; set; } | |
145 | + | |
146 | + /// <summary> | |
147 | + /// Jelzi, hogy ez az elem a listában kiválasztott. | |
148 | + /// </summary> | |
149 | + public bool Selected { get; set; } | |
150 | + | |
151 | + /// <summary> | |
152 | + /// A listelem szövege, ami megjelenik. | |
153 | + /// </summary> | |
154 | + public string Text { get; set; } | |
155 | + | |
156 | + /// <summary> | |
157 | + /// A listelem értéke. | |
158 | + /// </summary> | |
159 | + public string Value { get; set; } | |
160 | +} | |
161 | + | |
162 | +#region SelectListGroup public class | |
163 | +/// <summary> | |
164 | +/// Represents the optgroup HTML element and its attributes. In a select list, | |
165 | +/// multiple groups with the same name are supported. | |
166 | +/// They are compared with reference equality. | |
167 | +/// </summary> | |
168 | +/// <remarks> | |
169 | +/// A System.Mvc.SelectListItem-mel való kompatibilitás miatt van itt. | |
170 | +/// A 'summary' szövege is onnan másolt. | |
171 | +/// </remarks> | |
172 | +public class SelectListGroup | |
173 | +{ | |
174 | + /// <summary> | |
175 | + /// Beállítja, hogy az adott csoport engedélyezett-e. | |
176 | + /// </summary> | |
177 | + public bool Disabled { get; set; } | |
178 | + | |
179 | + /// <summary> | |
180 | + /// A csoport neve. | |
181 | + /// </summary> | |
182 | + public string Name { get; set; } | |
183 | +} | |
184 | +#endregion SelectListGroup public class | |
185 | +``` | |
186 | + | |
187 | + | |
188 | +## Version History: | |
189 | +#### 2.13.2 (2020.03.27) Patches: | |
190 | +- NuGet csomag módosítása úgy, hogy a modul ReadMe.md "Build Action" tulajdonsága "None" legyen a telepítés után. Install.ps1 hozzáadása. | |
191 | + | |
192 | +#### 2.13.1 (2020.03.26) Patches: | |
193 | +- Felesleges függések törlése. | |
194 | +- XML comment dokumentáció pontosítása. | |
195 | + | |
196 | +#### 2.13.0 (2020.03.19) Compatible changes: | |
197 | +- Vrh.Web.Common.Lib egyes elemeinek átemelése ide | |
198 | + | |
199 | +#### 2.12.1 (2020.02.13) Patches: | |
200 | +- SelectListJSON egyenlőség vizsgálat javítása | |
201 | + | |
202 | +#### 2.12.0 (2020.02.13) Compatible changes: | |
203 | +- SelectListJSON struktúrába beépítésre került egy speciális egyenlőség vizsgálat, amely a Value, a Text és a Group mezők értékének egyenlősége | |
204 | +esetén ad igaz értéket; a Disabled és a Selected mezők értéke az egyenlőség vizsgálatban nem játszik szerepet | |
205 | +- CheckListJSON és ReturnInfoJSON strukturákhoz analóg módon, mely ugyanezekkel a feltételekkel dolgozik. | |
206 | + | |
207 | +#### 2.11.1-3 (2019.12.19) Compatible changes: | |
208 | +- CommandLine class hibák javítása. | |
209 | + | |
210 | +#### 2.11.0 (2019.12.17) Compatible changes: | |
211 | +- Topshelf formátumú parancssori paraméterek kezelése: -NAME:value | |
212 | + | |
213 | +#### 2.10.1 (2019.12.17) Patches: | |
214 | +- CommandLine osztályban egy javítás | |
215 | + | |
216 | +#### 2.10.1 (2019.12.05) Patches: | |
217 | +- SerializeObject metódusban a string-ek külön kezelése. | |
218 | + | |
219 | +#### 2.10.0 (2019.10.08) Compatible changes: | |
220 | +- ToEnum string extension hozzáadása, amelyik egy stringből megadott tipusú enumra konvertál, vagy a típus (Enum) defaultját adja | |
221 | + | |
222 | +#### 2.9.0 (2019.09.12) Compatible changes: | |
223 | +- EntryAsseblyFixer static class hozzáadása, ami beállítja amegfelelő EntryAssembly-t, ha az alakalmazás tér dinamikus hostolású, ahol null, vagy dynamic az EntryAssembly | |
224 | +- EntryAsseblyFixer egység tesztjei | |
225 | + | |
226 | +## 2.8.1 (2019.09.07): | |
227 | +### Patch: | |
228 | +- Name property típusa javítva. | |
229 | + | |
230 | +## v2.8.0 (2019.09.06): | |
231 | +### Compatibility API changes: | |
232 | +- ReturnDictJSON adatstruktúra hozzáadva. | |
233 | + | |
234 | +## 2.7.0 (2019.08.15) Compatible changes: | |
235 | +### Compatibility API changes: | |
236 | +- Az EntityFramework extension bővítése az AlreadyOrdered függvénynel, amely megmondja egy IQueryable-ről, hogy rendezett-e már (tehát a további rendezéséhez az OrderBy, vagy a ThenBy-t kell-e használni) | |
237 | + | |
238 | +## 2.6.0 (2019.08.01) Compatible changes: | |
239 | +### Compatibility API changes: | |
240 | +- Extensions bővítése az EntityFramework extension-nel, EntityFrameworkQueryHelper bővítő osztály, SmartOrder bővítő metódus (IQueryable típusra) | |
241 | + | |
242 | +## 2.5.0 (2019.07.10) Compatible changes: | |
243 | +### Compatibility API changes: | |
244 | +- ExtensionMethods bővítése az Enum extensionssel, Enumdata attribútum osztály | |
245 | + | |
246 | +## 2.3.0 (2019.05.14) Compatible changes: | |
247 | +- IManage interfész áthelyezése Vrh.Web.Common.Lib 1.18.1-es változatából. | |
248 | +- Standard osztályok (CheckListJSON, ReturnInfoJSON, SelectListJSON) áthelyezése Vrh.Web.Common.Lib 1.18.1-es változatából. | |
249 | + | |
250 | +## 2.2.0 (2018.12.17) | |
251 | +### Compatible changes: | |
252 | +- VrhConvert.SerializeObject Private metódus publikussá tétele. | |
253 | + | |
254 | +## 2.1.0 (2018.12.17) | |
255 | +### Compatible changes: | |
256 | +- Új függvények beillesztése a conversion részbe. | |
257 | + | |
258 | +## 2.0.1 (2018.12.12) | |
259 | +### Patches: | |
260 | +- ConnandLine osztály metóduasdinak kommentezése és egy apró javítás: a GetCommandLineArgument lekezeli, ha az argumentname paramétere üres string. | |
261 | + | |
262 | +## 2.0.0 (2018.11.28) | |
263 | +### Braking change: | |
264 | +- 3.5-ös .Net framwork verzi támogatásának megszüntetése új target verzió: 4.5 | |
265 | +### Compatibility API changes: | |
266 | +- CommandLine static segéd osztály hozzáadása | |
267 | + | |
268 | +## 1.13.0 (2017.04.04) | |
269 | +### Compatibility API changes: | |
270 | +- String Extension method: FromHexOrThis | |
271 | + | |
272 | +## 1.12.0 (2017.03.29) | |
273 | +### Compatibility API changes: | |
274 | +- FixStack class hozzáadása | |
275 | +### Patches: | |
276 | +- UnitTest method elnevezések javítása (konvenció kidolgozása) | |
277 | + | |
278 | +## 1.11.0 (2017.03.28) | |
279 | +### Compatibility API changes: | |
280 | +- Assembly Extension methodok: Version, AssemblyAttribute | |
281 | + | |
282 | +## 1.10.0 (2017.03.16) | |
283 | +### Compatibility API changes: | |
284 | +- StringBuilder Extension methodok: AppendWithSeparator, Reverse | |
285 | +### Patches: | |
286 | +- Extension methodok helyének hozzáadása. | |
287 | +- Test projekt hozzáadása | |
288 | + | |
289 | +## V1.9.2 (2017.02.21) | |
290 | +### Patches: | |
291 | +- Projekt könyvrtárszerkezet rendbetétele. | |
292 | +- AutoBuild Vrh Nuget csomaggá alakítás (összes Nuget-tel kapcsolatos elvárás átvezetése) | |
293 | +- MinFramweork meghatározás | |
294 | + | |
295 | + | |
296 | + | |
297 | + | |
0 | 298 | \ No newline at end of file | ... | ... |
Vrh.Log4Pro.MaintenanceConsole/packages.config
1 | 1 | <?xml version="1.0" encoding="utf-8"?> |
2 | 2 | <packages> |
3 | + <package id="EntityFramework" version="6.4.0" targetFramework="net462" /> | |
3 | 4 | <package id="Microsoft.NETCore.Platforms" version="1.0.1" targetFramework="net462" /> |
4 | 5 | <package id="Microsoft.Web.Administration" version="11.1.0" targetFramework="net462" /> |
5 | 6 | <package id="Microsoft.Win32.Primitives" version="4.0.1" targetFramework="net462" /> |
... | ... | @@ -54,5 +55,6 @@ |
54 | 55 | <package id="System.Threading.Timer" version="4.0.1" targetFramework="net462" /> |
55 | 56 | <package id="System.Xml.ReaderWriter" version="4.0.11" targetFramework="net462" /> |
56 | 57 | <package id="System.Xml.XDocument" version="4.0.11" targetFramework="net462" /> |
58 | + <package id="VRH.Common" version="2.19.0" targetFramework="net462" /> | |
57 | 59 | <package id="Vrh.XmlProcessing" version="1.23.0" targetFramework="net462" /> |
58 | 60 | </packages> |
59 | 61 | \ No newline at end of file | ... | ... |