Commit e76b511841ab3d83d20a74db6ffb58cbb75bce30

Authored by Schwirg László
1 parent 0b366b5a

FileCleanerManager és MaintenanceToolManager/RegexTester elkészítése

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
... ...