From 8e8a7bf0599696f5cfbbbefcc547a9a03a41edef Mon Sep 17 00:00:00 2001 From: Schwirg László Date: Tue, 12 Jan 2021 13:59:36 +0100 Subject: [PATCH] jelentős fejleszetések --- Vrh.Log4Pro.MaintenanceConsole/App.config | 14 +++++++++++--- Vrh.Log4Pro.MaintenanceConsole/Config.xml | 22 ++++++++++++++++++---- Vrh.Log4Pro.MaintenanceConsole/ConsoleFunction - ColorConsole.cs | 12 +++++++++--- Vrh.Log4Pro.MaintenanceConsole/ConsoleFunction - CommandLineParser.cs | 127 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---- Vrh.Log4Pro.MaintenanceConsole/ConsoleFunction - Menu.cs | 376 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------------------------------------------------------------------------------------- Vrh.Log4Pro.MaintenanceConsole/ConsoleFunction - Tools - Membership.cs | 1081 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Vrh.Log4Pro.MaintenanceConsole/ConsoleFunction - Tools.cs | 104 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- Vrh.Log4Pro.MaintenanceConsole/Icon_Log4ProService.ico | Bin 0 -> 9662 bytes Vrh.Log4Pro.MaintenanceConsole/Manager - BackupPackageManager.cs | 513 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Vrh.Log4Pro.MaintenanceConsole/Manager - FileCleanerManager.cs | 100 ++++++++++++++++++++++++++++++++++++++++++++++++++++------------------------------------------------ Vrh.Log4Pro.MaintenanceConsole/Manager - MaintenanceToolManager.cs | 35 +++++++++++++++-------------------- Vrh.Log4Pro.MaintenanceConsole/Manager - SQLDataBaseManager.cs | 1113 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Vrh.Log4Pro.MaintenanceConsole/Manager - ScheduledTaskManager.cs | 195 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------------------------------------------------------------------------------------------------------- Vrh.Log4Pro.MaintenanceConsole/Manager - UserManager.cs | 236 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Vrh.Log4Pro.MaintenanceConsole/Manager - WebApplicationManager.cs | 755 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Vrh.Log4Pro.MaintenanceConsole/Manager - WindowsServiceManager.cs | 726 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Vrh.Log4Pro.MaintenanceConsole/Program.cs | 127 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------------- Vrh.Log4Pro.MaintenanceConsole/Vrh.Log4Pro.MaintenanceConsole.csproj | 155 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------ Vrh.Log4Pro.MaintenanceConsole/XmlParser.xml | 150 +++++++++++++++--------------------------------------------------------------------------------------------------------------------------------------- Vrh.Log4Pro.MaintenanceConsole/packages.config | 31 ++++++++++++++++++++++++------- Vrh.Log4Pro.MaintenanceConsole/servicelogo.ico | Bin 0 -> 105678 bytes Vrh.Log4Pro.MaintenanceConsole/system.web.membership.config | 12 ++++++++++++ Vrh.Log4Pro.MaintenanceConsole/system.web.rolemanager.config | 12 ++++++++++++ 23 files changed, 4869 insertions(+), 1027 deletions(-) create mode 100644 Vrh.Log4Pro.MaintenanceConsole/ConsoleFunction - Tools - Membership.cs create mode 100644 Vrh.Log4Pro.MaintenanceConsole/Icon_Log4ProService.ico create mode 100644 Vrh.Log4Pro.MaintenanceConsole/Manager - BackupPackageManager.cs create mode 100644 Vrh.Log4Pro.MaintenanceConsole/Manager - SQLDataBaseManager.cs create mode 100644 Vrh.Log4Pro.MaintenanceConsole/Manager - UserManager.cs create mode 100644 Vrh.Log4Pro.MaintenanceConsole/servicelogo.ico create mode 100644 Vrh.Log4Pro.MaintenanceConsole/system.web.membership.config create mode 100644 Vrh.Log4Pro.MaintenanceConsole/system.web.rolemanager.config diff --git a/Vrh.Log4Pro.MaintenanceConsole/App.config b/Vrh.Log4Pro.MaintenanceConsole/App.config index dedbba6..dec5bbc 100644 --- a/Vrh.Log4Pro.MaintenanceConsole/App.config +++ b/Vrh.Log4Pro.MaintenanceConsole/App.config @@ -5,7 +5,7 @@
- + @@ -16,11 +16,19 @@ + + + + - + + + + + - \ No newline at end of file + diff --git a/Vrh.Log4Pro.MaintenanceConsole/Config.xml b/Vrh.Log4Pro.MaintenanceConsole/Config.xml index 123bb84..16dc8cd 100644 --- a/Vrh.Log4Pro.MaintenanceConsole/Config.xml +++ b/Vrh.Log4Pro.MaintenanceConsole/Config.xml @@ -152,10 +152,10 @@ - - - - + + + + @@ -197,4 +197,18 @@ + + + + + + + + + + ^(T|t)est.*$ + ^(Operator|Lineleader)$ + + + \ No newline at end of file diff --git a/Vrh.Log4Pro.MaintenanceConsole/ConsoleFunction - ColorConsole.cs b/Vrh.Log4Pro.MaintenanceConsole/ConsoleFunction - ColorConsole.cs index 074c2f3..91e91a5 100644 --- a/Vrh.Log4Pro.MaintenanceConsole/ConsoleFunction - ColorConsole.cs +++ b/Vrh.Log4Pro.MaintenanceConsole/ConsoleFunction - ColorConsole.cs @@ -11,7 +11,7 @@ using System.Diagnostics; using Vrh.XmlProcessing; using System.Xml.Linq; -namespace Vrh.Log4Pro.MaintenanceConsole +namespace Vrh.Log4Pro.MaintenanceConsole.ColorConsoleNS { #region ColorConsole public static class ColorConsole @@ -101,7 +101,7 @@ namespace Vrh.Log4Pro.MaintenanceConsole /// /// /// - public static string ReadLine(string text = null, ConsoleColor? f = null, ConsoleColor? b = null, string bracket = null, string prefix = "") + public static string ReadLine(string text = null, ConsoleColor? f = null, ConsoleColor? b = null, string bracket = null, string prefix = "",string suffix = "") { if (silentMode) { @@ -115,7 +115,7 @@ namespace Vrh.Log4Pro.MaintenanceConsole } else { - Write(text, f, b, bracket, prefix); + Write(text, f, b, bracket, prefix,suffix); return Console.ReadLine(); } } @@ -133,6 +133,12 @@ namespace Vrh.Log4Pro.MaintenanceConsole public static int CursorLeft { get { return Console.CursorLeft; } } public static int CursorTop { get { return Console.CursorTop; } } + public static int WindowWidth { get { return Console.WindowWidth; } } + public static int BufferWidth { get { return Console.BufferWidth; } } + public static int WindowHeight { get { return Console.WindowHeight; } } + public static int BufferHeight { get { return Console.BufferHeight; } } + public static int WindowLeft { get { return Console.WindowLeft; } } + public static int WindowTop { get { return Console.WindowTop; } } public static void Clear() { Console.Clear(); } diff --git a/Vrh.Log4Pro.MaintenanceConsole/ConsoleFunction - CommandLineParser.cs b/Vrh.Log4Pro.MaintenanceConsole/ConsoleFunction - CommandLineParser.cs index 942b44d..1b0d388 100644 --- a/Vrh.Log4Pro.MaintenanceConsole/ConsoleFunction - CommandLineParser.cs +++ b/Vrh.Log4Pro.MaintenanceConsole/ConsoleFunction - CommandLineParser.cs @@ -8,10 +8,12 @@ using Microsoft.Web.Administration; using System.Management; using System.Diagnostics; +using Vrh.Log4Pro.MaintenanceConsole.ColorConsoleNS; + using Vrh.XmlProcessing; using System.Xml.Linq; -namespace Vrh.Log4Pro.MaintenanceConsole +namespace Vrh.Log4Pro.MaintenanceConsole.CommandLineParserNS { #region CommandLineParser public static class CommandLineParser @@ -74,7 +76,7 @@ namespace Vrh.Log4Pro.MaintenanceConsole } else if (chr == ' ' && !quoted) { - if (started) yield return result.ToString(); + if (started) { yield return result.ToString(); } result.Clear(); started = false; } @@ -85,7 +87,7 @@ namespace Vrh.Log4Pro.MaintenanceConsole } } - if (started) yield return result.ToString(); + if (started) { yield return result.ToString(); } } public static void UnitTest() { @@ -156,6 +158,7 @@ namespace Vrh.Log4Pro.MaintenanceConsole return; } for (int i = 0; i < r.Length; i++) + { if (r[i] != sr[i]) { ColorConsole.WriteLine($"ERROR:{id}"); @@ -164,8 +167,9 @@ namespace Vrh.Log4Pro.MaintenanceConsole ColorConsole.WriteLine($" expected: {sexp}"); return; } + } } - catch (Exception ex) + catch { ColorConsole.WriteLine($"EXCEP:{id}"); ColorConsole.WriteLine($" cmdline : {cmd}"); @@ -176,4 +180,119 @@ namespace Vrh.Log4Pro.MaintenanceConsole } } #endregion CommandLineParser + #region Commandline parameter definition class + public static class CLP + { + public const string CMD_MODULE = "-MODULE"; + public const string CMD_FUNCTION = "-FUNCTION"; + public const string CMD_SILENT = "-SILENT"; + public const string CMD_APPCONFIG = "-APPCONFIG"; + public static class Module + { + public static class Log4ProUserManager + { + public const string KEY = "LUM"; + public static class Functions + { + public static class CreateSuperuser { public const string KEY = "CSU"; } + public static class CreateAdminusers { public const string KEY = "CAU"; } + public static class DeleteUsers { public const string KEY = "DEU"; } + } + } + public static class WebApplicationManager + { + public const string KEY = "WAM"; + public static class Function + { + public const string CMD_WEBAPPS = "-WEBAPPS"; + public static class Register { public const string KEY = "WAR"; } + public static class Unregister { public const string KEY = "WAU"; } + public static class SetImpersonateIdentity { public const string KEY = "WAI"; } + public static class PoolStart { public const string KEY = "APS"; } + public static class PoolStop { public const string KEY = "APF"; } + public static class PoolRecycle { public const string KEY = "APR"; } + public static class SiteStart { public const string KEY = "WSS"; } + public static class SiteStop { public const string KEY = "WSF"; } + public static class PoolSetUserAccount { public const string KEY = "APU"; } + public static class Restart { public const string KEY = "R"; } + } + } + public static class WindowsServiceManager + { + public const string KEY = "WSM"; + public static class Function + { + public const string CMD_SERVICES = "-SERVICES"; + public static class Register { public const string KEY = "WSR"; } + public static class Unregister { public const string KEY = "WSU"; } + public static class SetUserAccount { public const string KEY = "WSA"; } + public static class Start { public const string KEY = "WSS"; } + public static class Stop { public const string KEY = "WSX"; } + public static class Kill { public const string KEY = "WSK"; } + public static class Purge { public const string KEY = "WSP"; } + } + } + public static class FileCleanerManager + { + public const string KEY = "FCL"; + public static class Functions + { + public const string CMD_FOLDERS = "-FOLDERS"; + public static class FolderClean { public const string KEY = "CLN"; } + } + } + public static class ScheduledTaskManager + { + public const string KEY = "SCH"; + public static class Function + { + public const string CMD_TASKS = "-TASKS"; + public static class Install { public const string KEY = "INS"; } + public static class Uninstall { public const string KEY = "UIN"; } + public static class Run { public const string KEY = "RUN"; } + public static class End { public const string KEY = "END"; } + public static class Enable { public const string KEY = "ENA"; } + public static class Disable { public const string KEY = "DIS"; } + public static class ChangePriority { public const string KEY = "CHP"; } + } + } + public static class BackupPackageManager + { + public const string KEY = "BAK"; + public static class Functions + { + public const string CMD_PACKAGES = "-PACKAGES"; + public static class CreateBackupPackage + { + public const string KEY = "CRE"; + } + } + } + public static class SQLDataBaseManager + { + public const string KEY = "SQL"; + public static class Function + { + public const string CMD_DATABASES = "-DATABASES"; + public static class BackupDataBase { public const string KEY = "BAK"; } + public static class CreateCodeScripts { public const string KEY = "CCS"; } + public static class CreateDataScripts { public const string KEY = "CDS"; } + public static class RestoreDataBase { public const string KEY = "RES"; public const string CMD_RESTOREFIRST = "-RESTOREFIRST"; + } + public static class RelocatePhysicalFiles { public const string KEY = "COP"; } + } + } + public static class MaintenanceToolManager + { + public const string KEY = "TOL"; + public static class Functions + { + public static class RegexTester { public const string KEY = "RGX"; } + public static class Tool1 { public const string KEY = "TL1"; } + public static class Tool2 { public const string KEY = "TL2"; } + } + } + } + } + #endregion Commandline parameter definition class } diff --git a/Vrh.Log4Pro.MaintenanceConsole/ConsoleFunction - Menu.cs b/Vrh.Log4Pro.MaintenanceConsole/ConsoleFunction - Menu.cs index a4854be..ce2d4f3 100644 --- a/Vrh.Log4Pro.MaintenanceConsole/ConsoleFunction - Menu.cs +++ b/Vrh.Log4Pro.MaintenanceConsole/ConsoleFunction - Menu.cs @@ -10,31 +10,44 @@ using Microsoft.Web.Administration; using System.Management; using System.Diagnostics; +using Vrh.Log4Pro.MaintenanceConsole.ColorConsoleNS; + using Vrh.XmlProcessing; using VRH.Common; using System.Xml.Linq; -namespace Vrh.Log4Pro.MaintenanceConsole +namespace Vrh.Log4Pro.MaintenanceConsole.MenuNS { public class Menu { - public delegate Object MenuItemExecutorFunc(Object p, Object o); + /// + /// Egy menupont executor függvény prototípusa + /// + /// az executor paramétereit tartalmazó osztály + /// + /// több menupont kiválasztásakor ezt a paramétert az első menuponthoz tartozó executor tölti fel, + /// majd ezt az értéket megkapja a második, aki módosíthatja, majd megkapja a harmadik, és így tovább... + /// + /// + public delegate Object MenuItemExecutorFunc(Menu.ExecutorParameter p, Object o); public delegate Object MenuItemDisplayerFunc(Object p, int i); + public delegate void MenuHeaderDisplayerFunc(); + public Menu(string title, string selectionprompt = null) { Title = title; if (!string.IsNullOrWhiteSpace(selectionprompt)) { SelectionPrompt = selectionprompt; } } #region private fields private string title; private string Title { get { return ColorConsole.WideString(title); } set { title = value; } } private MenuItemDisplayerFunc MenuItemDisplayer; + private MenuHeaderDisplayerFunc MenuHeaderDisplayer; private SelectionMode selectionMode = Menu.SelectionMode.Multi; - private static bool commandModeAllMenus = false; - private bool commandMode = false; - private int HeaderWidth = 9; + private static bool commandMode = false; + private int MenuItemIndentWidth = 0; private string SelectionPrompt = "Make Your selection!"; #endregion private fields #region public properties public List MenuItemList { get; private set; } = new List(); - List MenuKeyList { get { return MenuItemList.Where(x => !x.Separator).Select(x => x.Key).ToList(); } } + List MenuItemKeyList { get { return MenuItemList.Where(x => !x.Separator).Select(x => x.Key).ToList(); } } #endregion public properties #region public tools @@ -45,7 +58,7 @@ namespace Vrh.Log4Pro.MaintenanceConsole /// public static void IncorrectSelection(string partxt = "") { - if (GetCommandModeAllMenus()) { return; } + if (IsCommandMode()) { return; } ColorConsole.WriteLine(); ColorConsole.WriteLine($"Incorrect selection! {partxt} Make a new selection!", ConsoleColor.Red); @@ -59,51 +72,90 @@ namespace Vrh.Log4Pro.MaintenanceConsole /// public static ConsoleKeyInfo PressAnykeyToContinue(string text = null) { - if (GetCommandModeAllMenus()) { return ColorConsole.GetConsoleKey(ConsoleKey.Enter); } + if (IsCommandMode()) { return ColorConsole.GetConsoleKey(ConsoleKey.Enter); } ColorConsole.WriteLine(text ?? "Press any key to continue...", ConsoleColor.Yellow); return ColorConsole.ReadKey(); } + /// + /// Beállítja a parancs módot a menükezelő számára + /// + /// + public static void SetCommandMode(bool commandmode=true) { commandMode = commandmode; } - public static void SetCommandModeAllMenus() { commandModeAllMenus = true; } + /// + /// true= a menükezelő parancs módban van + /// + /// + public static bool IsCommandMode() { return commandMode; } + /// + /// Beállítja a menükezelő számára a displayer metódust, amelynek feladata + /// az egyes menüpontok információjának soronkénti előállítása + /// + /// + /// public Menu SetMenuItemDisplayer(MenuItemDisplayerFunc displayer) { MenuItemDisplayer = displayer; return this; } + + /// + /// Beállítja a menükezelő számára a header displayer metódust, amelynek feladata + /// a menu címe alatti terület információjának előállítása + /// + /// + /// + public Menu SetMenuHeaderDisplayer(MenuHeaderDisplayerFunc displayer) + { + MenuHeaderDisplayer = displayer; + return this; + } + + /// + /// Beállítja, hogy egy, vagy több menüpont választható + /// + /// + /// public Menu SetSelectionMode(SelectionMode sm) { selectionMode = sm; return this; } - public Menu SetCommandMode(bool commandmode = false) { commandMode = true; return this; } - public static bool GetCommandModeAllMenus() { return commandModeAllMenus; } - public bool GetCommandMode() { return commandMode || commandModeAllMenus; } - public Menu SetHeaderWidth(int hw) { HeaderWidth = hw; return this; } + + /// + /// Létrehoz egy menüpontot + /// + /// + /// public Menu AddMenuItem(Item mi) { MenuItemList.Add(mi); if (string.IsNullOrWhiteSpace(mi.Key)) { mi.Key = $"#$KEY{MenuItemList.IndexOf(mi)}"; } return this; } + + /// + /// Törli a menüpontok listáját + /// public void ClearMenuItemList() { MenuItemList.Clear(); } - public void ExecuteCmd(string[] args) - { - var module = CommandLine.GetCommandLineArgument(args, "-MODULE"); - var sr = new Menu.Selection(module, args); - ExecuteSelection(sr); - } - public void ExecuteMenu() + /// + /// Végrehajtja a menüt, azaz választási lehetőséget biztosít, majd végrehajtja a kiválasztott menupontokhoz tartozó executor metódusokat + /// + /// + public void ExecuteMenu(string forcedselectionkeylist=null) { try { while (true) { DisplayTitle(); + MenuHeaderDisplayer?.Invoke(); DisplayItems(); - var sr = Select(); + var sr = Select(forcedselectionkeylist); if (sr.Result == Menu.SelectionResult.Exit) { return; } else if (sr.Result == Menu.SelectionResult.None) { continue; } else if (sr.Result == Menu.SelectionResult.Error) { continue; } ExecuteSelection(sr.SelectedKeyList); + if (Menu.IsCommandMode()) { return; } } } catch (Exception ex) @@ -113,33 +165,70 @@ namespace Vrh.Log4Pro.MaintenanceConsole Menu.PressAnykeyToContinue(); } } + + + /// + /// Megjeleníti a menő fejlécét + /// public void DisplayTitle() { - if (GetCommandMode()) { return; } + if (Menu.IsCommandMode()) { return; } ColorConsole.Clear(); ColorConsole.WriteLine(Title, ConsoleColor.White); ColorConsole.WriteLine(new string('-', Title.Length)); } + + private static int SetMenuItemHeaderWidth(List MenuItemList,int columns) + { + var menuItemmaxwidth = 0; + var i = 1; + foreach (var menuitem in MenuItemList) + { + var len = 0; + len += 1;//ColorConsole.Write($"["); + len += $"{i}".Length;// ColorConsole.Write($"{i}"); + if (menuitem.Separator) { continue; } + if (!string.IsNullOrEmpty(menuitem.Key) && !menuitem.Key.StartsWith("#$KEY")) + { + len += 1;//ColorConsole.Write($":"); + len += $"{menuitem.Key}".Length;//ColorConsole.Write(menuitem.Key, ConsoleColor.Yellow); + } + len += 1;//ColorConsole.Write($"]"); + if (columns == 1) + { + if (menuItemmaxwidth == 0 || len > menuItemmaxwidth) { menuItemmaxwidth = len+1; } + } + i++; + } + return menuItemmaxwidth; + } + + /// + /// Megjeleníti a menüpontokat + /// + /// + /// public void DisplayItems(int columns = 1, int columnlength = 0) { - if (GetCommandMode()) { return; } + if (Menu.IsCommandMode()) { return; } int columncounter = 0; ColorConsole.WriteLine(); var i = 1; ColorConsole.SetCursorPosition(0, ColorConsole.CursorTop); + MenuItemIndentWidth = SetMenuItemHeaderWidth(MenuItemList, columns); foreach (var menuitem in MenuItemList) { if (menuitem.Separator && columns == 1) { - ColorConsole.SetCursorPosition(columnlength * columncounter + HeaderWidth, ColorConsole.CursorTop); + ColorConsole.SetCursorPosition(MenuItemIndentWidth, ColorConsole.CursorTop); var seplen = menuitem.SeparatorLength; if (menuitem.SeparatorLength == 0) { - foreach (var mi in MenuItemList.Where(x => !x.Separator)) { if (mi.Text.Length > seplen) { seplen = mi.Text.Length; } } + foreach (var mi in MenuItemList.Where(x => !x.Separator)) { if (!string.IsNullOrWhiteSpace(mi.Text) && mi.Text.Length > seplen) { seplen = mi.Text.Length; } } } - ColorConsole.WriteLine(new string(menuitem.SeparatorChar, seplen)); + ColorConsole.WriteLine(new string(menuitem.SeparatorChar, seplen==0?20:seplen)); continue; } ColorConsole.Write($"["); @@ -150,21 +239,18 @@ namespace Vrh.Log4Pro.MaintenanceConsole ColorConsole.Write(menuitem.Key, ConsoleColor.Yellow); } ColorConsole.Write($"]"); - ColorConsole.SetCursorPosition(columnlength * columncounter + HeaderWidth, ColorConsole.CursorTop); - - if (!string.IsNullOrEmpty(menuitem.Text)) - { - ColorConsole.Write(menuitem.Text); - } - if (columns == 1) + if (columns == 1) { + if (MenuItemIndentWidth == 0) { MenuItemIndentWidth = ColorConsole.CursorLeft + 1; } + ColorConsole.SetCursorPosition(MenuItemIndentWidth, ColorConsole.CursorTop); + if (!string.IsNullOrEmpty(menuitem.Text)) { ColorConsole.Write(menuitem.Text); } if (!string.IsNullOrEmpty(menuitem.Text)) { ColorConsole.WriteLine(); } if (MenuItemDisplayer != null) { for (var li = 0; li < 100; li++) { - if (li > 0) { ColorConsole.Write(new string(' ', HeaderWidth)); } - var str = (string)MenuItemDisplayer(menuitem.Parameters, li); + if (li > 0) { ColorConsole.Write(new string(' ', MenuItemIndentWidth)); } + var str = (string)MenuItemDisplayer.Invoke(menuitem.Parameters, li); if (string.IsNullOrEmpty(str)) { ColorConsole.SetCursorPosition(0, ColorConsole.CursorTop); } if (str == null) { break; } } @@ -172,6 +258,8 @@ namespace Vrh.Log4Pro.MaintenanceConsole } else { + ColorConsole.SetCursorPosition(columnlength * columncounter, ColorConsole.CursorTop); + if (!string.IsNullOrEmpty(menuitem.Text)) { ColorConsole.Write(menuitem.Text); } columncounter++; if (columncounter == columns) { ColorConsole.WriteLine(); columncounter = 0; } else @@ -189,28 +277,61 @@ namespace Vrh.Log4Pro.MaintenanceConsole } ColorConsole.Write("EX", ConsoleColor.Red, bracket: "()"); ColorConsole.WriteLine(" Exit"); } + public static Selection SelectFromItemList(string listtitle, string selectionprompt, Dictionary items, Menu.SelectionMode mode = SelectionMode.Single,bool getconfirmation=false) + { + var menubackupfiles = new Menu(listtitle, selectionprompt) + .SetSelectionMode(mode); + + foreach (var i in items) + { + menubackupfiles.AddMenuItem(new Item(null, i.Key, null, new ExecutorParameter(pars: i.Value))); + } + Menu.Selection ms; + while (true) + { + menubackupfiles.DisplayItems(1); + ms = menubackupfiles.Select(); + if (ms.Result == SelectionResult.None) { continue; } + else if (ms.Result == SelectionResult.Error) { continue; } + else if (ms.Result == SelectionResult.Exit) { return null; } + else + { + if (!getconfirmation || getconfirmation && ColorConsole.ReadLine("Enter [CONFIRM] to confirm!", ConsoleColor.Yellow,suffix:" --> ").ToUpper() == "CONFIRM") { return ms; } + else { continue; } + } + } + } + + + /// + /// A Menuből való választás eredményét tartalmazza + /// public class Selection { public Selection() { } - public Selection(string selectedkey,object parameter) + public Selection(string selectedkey, Menu.ExecutorParameter parameter) { Result = SelectionResult.Ok; SelectedKeyList = new List() { { selectedkey } }; - SelectedParameterList = new List() { { parameter } }; + SelectedParameterList = new List() { { parameter } }; } public List SelectedKeyList = null; public SelectionResult Result; - public List SelectedParameterList; + public List SelectedParameterList; } public enum SelectionResult { Exit, None, Error, Ok, } public enum SelectionMode { Single, Multi, } + + /// + /// A menüből való választás lebonyolítása + /// + /// + /// public Selection Select(string forcedselectionkeylist=null) { - List selectionKeyList; - List selectionParList; string selectionliststr; var result = new Selection(); - if (GetCommandMode()) + if (Menu.IsCommandMode()) { selectionliststr = forcedselectionkeylist??"EX"; } @@ -246,47 +367,81 @@ namespace Vrh.Log4Pro.MaintenanceConsole result.SelectedKeyList = null; return result; } - else if (selectionMode == SelectionMode.Multi && selectionliststr == "*") + else if (selectionMode == SelectionMode.Single && selectionliststr == "*") { - selectionKeyList = new List(); - selectionParList = new List(); - var i = 1; - foreach (var mi in MenuItemList) - { - selectionKeyList.Add(mi.Key); - selectionParList.Add(mi.Parameters); - } - result.Result = SelectionResult.Ok; - result.SelectedKeyList = selectionKeyList; - result.SelectedParameterList = selectionParList; + result.Result = SelectionResult.Error; + result.SelectedKeyList = null; return result; } - selectionKeyList = new List(); - selectionParList = new List(); - foreach (var selection in selectionliststr.Split(',').ToList()) + else if (selectionliststr == "*") { return ProcessOKSelection(MenuItemKeyList); } // all keys + else { return ProcessOKSelection(selectionliststr.Split(',').ToList()); } // selected list list + } + #region ProcessOKSelection + private Selection ProcessOKSelection(List selectionKeyList) + { + var result = new Selection(); + var return_selectionParList = new List(); + List return_selectionKeyList = new List(); + foreach (var selectedkeyorindex in selectionKeyList) { - string _selection = selection; - object _parameters = null; - if (!MenuKeyList.Contains(_selection)) + string _selectedkey; + Item _selectedmenuitem; + if (MenuItemKeyList.Contains(selectedkeyorindex)) { _selectedkey = selectedkeyorindex; } + else { - if (!int.TryParse(_selection, out int indexselection) || indexselection < 1 || indexselection > MenuItemList.Count()) + if (!int.TryParse(selectedkeyorindex, out int _selectedindex) || _selectedindex < 1 || _selectedindex > MenuItemList.Count()) { - Menu.IncorrectSelection($"Selected item {_selection} is not valid!"); + Menu.IncorrectSelection($"Selected item {selectedkeyorindex} is not valid!"); result.Result = SelectionResult.Error; result.SelectedKeyList = null; return result; } - _selection = GetItemKey(indexselection - 1); - _parameters = GetItem(indexselection - 1).Parameters; + _selectedkey = GetItemKey(_selectedindex - 1); } - selectionKeyList.Add(_selection); - selectionParList.Add(_parameters); + _selectedmenuitem = GetItem(_selectedkey); + ResolvemenuItemGroup(_selectedmenuitem, return_selectionKeyList, return_selectionParList); } result.Result = SelectionResult.Ok; - result.SelectedKeyList = selectionKeyList; - result.SelectedParameterList = selectionParList; + result.SelectedKeyList = return_selectionKeyList; + result.SelectedParameterList = return_selectionParList; return result; } + #endregion ProcessOKSelection + #region ResolveGroup + private void ResolvemenuItemGroup(Menu.Item _selectedmenuitem,List selectionKeyList,List selectionParList) + { + if (_selectedmenuitem.Group) + { + List keysinmenuitemgroup; + if (_selectedmenuitem.GroupKeyList.Contains("*")) { keysinmenuitemgroup = MenuItemList.Where(x=>!x.Group && !x.Separator).Select(x=>x.Key).ToList(); } + else { keysinmenuitemgroup = _selectedmenuitem.GroupKeyList.Select(x => x).ToList(); } + + foreach (var ikey in keysinmenuitemgroup) + { + var mikey = GetItem(ikey); + if (mikey!=null && !mikey.Group) + { + if (selectionKeyList.Contains(ikey)) { continue; } + selectionKeyList.Add(ikey); + selectionParList.Add(mikey.Parameters); + } + else + { + throw new Exception($"MenuItem '{ikey}' referred by MenuItemGroup '{_selectedmenuitem.Key}' does not exist or is a group!"); + } + } + } + else + { + selectionKeyList.Add(_selectedmenuitem.Key); + selectionParList.Add(_selectedmenuitem.Parameters); + } + } + #endregion ResolveGroup + /// + /// A menuből való választás alapján végrehajtja a kiválasztott menüpontokhoz rendelt executorokat + /// + /// public void ExecuteSelection(List selectedkeylist) { object o = null; @@ -300,18 +455,11 @@ namespace Vrh.Log4Pro.MaintenanceConsole Menu.PressAnykeyToContinue(); } - public void ExecuteSelection(Menu.Selection sr) - { - object o = null; - foreach (var mi in MenuItemList) - { - if (sr.SelectedKeyList.Contains(mi.Key)) - { - o = mi.Executor(sr.SelectedParameterList.ElementAt(sr.SelectedKeyList.IndexOf(mi.Key)), o); - } - } - Menu.PressAnykeyToContinue(); - } + /// + /// Visszadja a menupont kulcsához tartozó executor metódust + /// + /// + /// public MenuItemExecutorFunc GetExecutor(string key) { return MenuItemList.ElementAt(GetItemIx(key)).Executor; @@ -319,31 +467,57 @@ namespace Vrh.Log4Pro.MaintenanceConsole #endregion public tools #region private tools + /// + /// visszadja a megadott kulcsú menupont leíróját + /// + /// + /// private Menu.Item GetItem(string itemkey) { return MenuItemList.FirstOrDefault(x => x.Key == itemkey); } + /// + /// visszadja a megadott indexű menupont leíróját + /// + /// + /// private Menu.Item GetItem(int ix) { var i = 0; foreach (var mi in MenuItemList) { if (mi.Separator) { continue; } - if (i == ix) return mi; + if (i == ix) { return mi; } i++; } return null; //return MenuItemList.ElementAt(ix); } + /// + /// Visszadja a megadott kulcsú menüpont indexét + /// + /// + /// private int GetItemIx(string itemkey) { - return MenuKeyList.IndexOf(itemkey); + return MenuItemKeyList.IndexOf(itemkey); } - private string GetItemKey(int ix) + /// + /// Visszadja a megadott indexű menüpont kulcsát + /// + /// + /// + string GetItemKey(int ix) { - return MenuKeyList.ElementAt(ix); + return MenuItemKeyList.ElementAt(ix); } - public void SetExecutorParameters(Menu.Selection r, object p=null) + /// + /// A kiválasztott menupontokhoz beállítja a megadott paramétereket a metódus paramétereként megadott paraméterre, + /// vagy ennek híján a Selection objektumban levő paraméterekre + /// + /// a Selection objektum + /// a beállítandó paraméter + public void SetExecutorParameters(Menu.Selection r, ExecutorParameter p =null) { foreach (var mi in this.MenuItemList) { @@ -355,6 +529,33 @@ namespace Vrh.Log4Pro.MaintenanceConsole } } #endregion private tools + + public class ExecutorParameter + { + public ExecutorParameter(object cfg=null, string[] args=null, object pars=null) + { + _config = cfg; Args = args;Parameters = pars; + } + public TXMLPROCESSORTYPE GetConfig() + where TXMLPROCESSORTYPE : XmlParser + { + return _config as TXMLPROCESSORTYPE; + } + + private object _config; + public object Parameters; + public string[] Args { get; set; } + } + public class ItemGroup: Item + { + public ItemGroup(string key, string text, List keylist) : base() + { + Key = key; + Text = text; + Group = true; + GroupKeyList = keylist; + } + } public class ItemSeparator : Item { public ItemSeparator(char c = '-', int length = 0) : base() @@ -367,7 +568,7 @@ namespace Vrh.Log4Pro.MaintenanceConsole public class Item { public Item() { } - public Item(string key, string text, MenuItemExecutorFunc executor = null, object parameters = null) + public Item(string key, string text, MenuItemExecutorFunc executor = null, Menu.ExecutorParameter parameters = null) { Key = key; Text = text; @@ -377,7 +578,10 @@ namespace Vrh.Log4Pro.MaintenanceConsole public string Key; public string Text; public MenuItemExecutorFunc Executor; - public object Parameters; + public Menu.ExecutorParameter Parameters; + + public bool Group = false; + public List GroupKeyList; public bool Separator = false; public char SeparatorChar = '-'; diff --git a/Vrh.Log4Pro.MaintenanceConsole/ConsoleFunction - Tools - Membership.cs b/Vrh.Log4Pro.MaintenanceConsole/ConsoleFunction - Tools - Membership.cs new file mode 100644 index 0000000..8e80f48 --- /dev/null +++ b/Vrh.Log4Pro.MaintenanceConsole/ConsoleFunction - Tools - Membership.cs @@ -0,0 +1,1081 @@ +using System; +using System.Data.Linq.SqlClient; +using System.IO; +using System.IO.Compression; +using System.Collections.Generic; +using System.Linq; +using System.Security.Principal; +using System.Text; +using System.Text.RegularExpressions; +using System.Threading.Tasks; +using System.Threading; + +using Microsoft.Web.Administration; +using System.Management; +using System.Diagnostics; + +using Vrh.XmlProcessing; +using System.Xml.Linq; +using Vrh.Log4Pro.MaintenanceConsole.ColorConsoleNS; +using VRH.Common; + +using System.Data.Entity; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; + +namespace Vrh.Log4Pro.MaintenanceConsole.ToolsNS +{ + using System.Web.Security; + + public static class MembershipTools + { + public static void SetConnectionString(string sqlcs) + { + MembershipDBContext = new DAL.MembershipContext(sqlcs); + m_MembershipProvider = System.Web.Security.Membership.Provider; + m_roleProvider = System.Web.Security.Roles.Provider; + } + private static MembershipProvider m_MembershipProvider; + private static RoleProvider m_roleProvider; + private static DAL.MembershipContext MembershipDBContext; + + #region Constants + public class Constants + { + public const string SCHEMA_NAME = "UAdmin"; + + public const string ROLENAME_ADMINISTRATOR = "Administrator"; + public const string ROLENAME_ADMIN = "Admin"; + public const string USERNAME_ADMINISTRATOR = "Administrator"; + public const string PASSWORD_ADMINISTRATOR = "Admin123"; + public const string USERNAME_ADMIN = "Admin"; + public const string PASSWORD_ADMIN = "Admin123"; + public static readonly string[] SYSTEMUSERNAMELIST = new string[] { ROLENAME_ADMIN, USERNAME_ADMINISTRATOR }; + public static readonly DateTime NEVERONLINE = new DateTime(2000, 1, 1); + } + #endregion Constants + + #region Users + public static class Users + { + #region IsSecondaryUser + /// + /// true-val tér vissza, ha léteznek ehhez az elsődleges userhez másodlagos user-ek + /// + /// + /// + public static bool IsSecondaryUserOfUser(string primaryusername) + { + var sUserList = MembershipDBContext.SecondaryUsers.Where(x => x.User != null && x.User.UserName == primaryusername); + return (sUserList != null && sUserList.Any()); + } + #endregion IsSecondaryUser + #region DeleteSecondaryUsersOfUser methods + /// + /// Másodlagos felhasználó törlése a funkció nevének és a felhasználó nevének megadásával. + /// + /// Elsődleges felhasználó neve. + /// Ha nem található a törlendő másodlagos felhasználó. + public static void DeleteSecondaryUsersOfUser(string primaryusername) + { + var sUserList = MembershipDBContext.SecondaryUsers.Where(x => x.User!=null && x.User.UserName == primaryusername); + if (sUserList == null || !sUserList.Any()) + { + throw new ApplicationException($"Secondary users for primary user '{primaryusername}' not found!"); + } + else + { + foreach (var suser in sUserList) + { + var sllist = MembershipDBContext.SecondaryLogins.Where(sl => sl.SecondaryUserId == suser.Id); + if (sllist != null && sllist.Any()) { foreach (var sl in sllist) { MembershipDBContext.SecondaryLogins.Remove(sl); } } + MembershipDBContext.SecondaryUsers.Remove(suser); + } + MembershipDBContext.SaveChanges(); + } + } + #endregion DeleteSecondaryUsersOfUser methods + #region Create + /// + /// Felhasználó létrehozása a paraméterlistában felsorolt paraméterek megadásával. + /// + /// Felhasználó neve. + /// Felhasználó jelszava. + /// hozzárendeli a usert az Admin és az Administrator szerepekhez + /// hozzárendeli a usert minden létező szerephez és szerepkörhöz + /// a felhasználóhoz hozzárendelendő role nevek listája; ha a lista tartalmazza a * tagot, akkor minden role. + /// a felhasználóhoz hozzárendelendő rolegroup nevek listája; ha a lista tartalmazza a * tagot, akkor minden rolegroup. + /// A létrehozott felhasználó MembershipUser objektuma. + public static MembershipUser Create(string username, string password, bool administrator=false,bool superuser=false, string[] rolenames=null,string[]rolegroupnames=null) + { + #region ellenőrzések + if (String.IsNullOrWhiteSpace(username)) { throw new MembershipCreateUserException("Username is required!"); } + + string wrPrefix = "WebReq_"; + string adPrefix = "AD_"; + if (username.StartsWith(wrPrefix, StringComparison.OrdinalIgnoreCase) || username.StartsWith(adPrefix, StringComparison.OrdinalIgnoreCase)) + { + throw new MembershipCreateUserException($"Username format is incorrect, it can not start with {wrPrefix}, {adPrefix}"); + } + #endregion ellenőrzések + + CreateAdminRolesAndUsers(); + MembershipUser user = Membership.GetUser(username); + if (user == null) + { + user = Membership.CreateUser(username, password); + user.LastActivityDate = Constants.NEVERONLINE; + user.LastLoginDate = Constants.NEVERONLINE; + user.Comment = ""; + user.Email = ""; + user.IsApproved = true; + Membership.UpdateUser(user); + //user.ChangePasswordQuestionAndAnswer(password, "", ""); + } + if (superuser) + { + string rgnamelist = string.Join(",", MembershipDBContext.RoleGroups.Select(rg => rg.Name).ToArray()); + if (!string.IsNullOrWhiteSpace(rgnamelist)) { Assign.RoleGroupsToUsers(rgnamelist, username); } + foreach (var rn in Roles.GetAllRoles()) + { + if (!Users.IsInRole(username, rn)) { Roles.AddUserToRole(username, rn); } + } + } + else if (administrator) + { + if (!Roles.IsUserInRole(username, Constants.ROLENAME_ADMINISTRATOR)) { Roles.AddUserToRole(username, Constants.ROLENAME_ADMINISTRATOR); } + if (!Roles.IsUserInRole(username, Constants.ROLENAME_ADMIN)) { Roles.AddUserToRole(username, Constants.ROLENAME_ADMIN); } + } + + string[] selectedrolenames; + if (rolenames != null) + { + selectedrolenames = rolenames.Contains("*") ? Roles.GetAllRoles() : rolenames; + if (selectedrolenames != null && selectedrolenames.Any()) + { + foreach (var rname in selectedrolenames) { if (!Roles.IsUserInRole(username, rname)) { Roles.AddUserToRole(username, rname); } } + } + } + string[] selectedrolegroupnames; + if (rolegroupnames != null) + { + selectedrolegroupnames = rolegroupnames.Contains("*") ? RoleGroups.GetAllNames().ToArray() : rolegroupnames; + if (selectedrolegroupnames != null && selectedrolegroupnames.Any()) + { + foreach (var rgname in selectedrolegroupnames) { if (!RoleGroups.IsUserInRoleGroup(username, rgname)) { Assign.RoleGroupsToUsers(rgname, username); } } + } + } + return user; + } + #endregion Create + #region CreateAdminRolesAndUsers + public static void CreateAdminRolesAndUsers() + { + MembershipUser user; + if (!Roles.RoleExists(Constants.ROLENAME_ADMINISTRATOR)) { Roles.CreateRole(Constants.ROLENAME_ADMINISTRATOR); } + if (!Roles.RoleExists(Constants.ROLENAME_ADMIN)) { Roles.CreateRole(Constants.ROLENAME_ADMIN); } + + user = Membership.GetUser(Constants.USERNAME_ADMIN); + if (user == null) + { + user = Membership.CreateUser(Constants.USERNAME_ADMIN, Constants.PASSWORD_ADMIN); + } + if (!Roles.IsUserInRole(Constants.USERNAME_ADMIN, Constants.ROLENAME_ADMINISTRATOR)) { Roles.AddUserToRole(Constants.USERNAME_ADMIN, Constants.ROLENAME_ADMINISTRATOR); } + if (!Roles.IsUserInRole(Constants.USERNAME_ADMIN, Constants.ROLENAME_ADMIN)) { Roles.AddUserToRole(Constants.USERNAME_ADMIN, Constants.ROLENAME_ADMIN); } + + user = Membership.GetUser(Constants.USERNAME_ADMINISTRATOR); + if (user == null) + { + user = Membership.CreateUser(Constants.USERNAME_ADMINISTRATOR, Constants.PASSWORD_ADMINISTRATOR); + } + if (!Roles.IsUserInRole(Constants.USERNAME_ADMINISTRATOR, Constants.ROLENAME_ADMINISTRATOR)) { Roles.AddUserToRole(Constants.USERNAME_ADMINISTRATOR, Constants.ROLENAME_ADMINISTRATOR); } + if (!Roles.IsUserInRole(Constants.USERNAME_ADMINISTRATOR, Constants.ROLENAME_ADMIN)) { Roles.AddUserToRole(Constants.USERNAME_ADMINISTRATOR, Constants.ROLENAME_ADMIN); } + } + #endregion CreateAdminRolesAndUsers + #region IsInRole public method + /// + /// Annak jelzése, hogy a -ben megadott nevű felhasználó + /// rendelkezik-e a -ben megadott nevű szereppel. + /// + /// A felhasználó neve. + /// A szerep neve. + /// Igaz, ha a felhasználó rendelekezik a megadott szereppel. + public static bool IsInRole(string userName, string roleName) + { + return m_roleProvider.IsUserInRole(userName, roleName); + } + #endregion IsInRole public method + #region Get + public static MembershipUser Get(string userName) + { + return m_MembershipProvider.GetUser(userName, false); + } + #endregion Get + #region GetNameList + /// + /// A maszknak megfelelő felhasználónevek listáját adja vissza. + /// + /// SQL LIKE-ba illeszhető maszk + /// + public static List GetNameList(string usernamemask) + { + if (usernamemask == null) { usernamemask = "%"; } + usernamemask = usernamemask.Replace("%", ".*").Replace("?", "."); + return MembershipDBContext.Users + .Select(u=>u.UserName) + .ToList() + .Where(un => Regex.Match(un, usernamemask).Success) + .ToList(); + } + #endregion GetNameList + #region GetList + /// + /// Az összes felhasználót tartalmazó listát ad vissza. + /// + /// Ha hamis, akkor az ideiglenes felhasználók nincsenek a listában. + /// + public static List GetList(string usernamemask,bool includetempuser = false) + { + var result = new List(); + if (!includetempuser) + { // az ideiglenes felhasználók nélkül + var qry = MembershipDBContext.Users // primary + .Where(u => SqlMethods.Like(u.UserName, usernamemask)) + .GroupJoin(MembershipDBContext.UserSupplements, //foreign + pk => pk.UserId, // primary key + fk => fk.UserId, // foreign key + (pka, fkb) => new { u = pka, us = fkb }) + .SelectMany(sm => sm.us.DefaultIfEmpty(), (sm, d) => new { User = sm.u, UserSupplement = d }) + .Where(x => x.UserSupplement == null || x.UserSupplement.IsTemporary == false) + .Select(s => s.User); + if (qry != null && qry.Any()) + { + foreach (var dbuser in qry) + { + MembershipUser user = m_MembershipProvider.GetUser(dbuser.UserId, false); + if (user != null) + { + result.Add(user); + } + } + } + } + else + { // itt mehet mind, nem kell szűrögetni + foreach (MembershipUser user in m_MembershipProvider.GetAllUsers(0, int.MaxValue, out int totalRecords)) + { + result.Add(user); + } + } + return result; + } + #endregion GetList + #region CheckPassword + public static bool CheckPassword(string username, string userpassword) + { + var user = Membership.GetUser(username); + return user.GetPassword()==userpassword; + } + #endregion CheckPassword + #region Remove + /// + /// Törli a megadott nevű user-t és minden kapcsolatát + /// + /// + /// + /// + /// + public static void Remove(string username) + { + if (string.IsNullOrWhiteSpace(username)) { throw new Exception("Username can not be null or empty or whitespace!"); } + if (Get(username) == null) { throw new ApplicationException($"User {username} does not exist!"); } + if (Constants.SYSTEMUSERNAMELIST.Contains(username)) { throw new MembershipCreateUserException($"System user {username} are not allowed to delete!"); } + Assign.RemoveOfUser(username); + if (Users.IsSecondaryUserOfUser(username)) { Users.DeleteSecondaryUsersOfUser(username); } + m_MembershipProvider.DeleteUser(username, true); + } + #endregion Remove + } + #endregion Users + #region RoleGroups + public static class RoleGroups + { + #region Get methods + /// + /// Szerepkör lekérése az egyedi azonosítója alapján. + /// + /// A keresett funkció azonosítója. + /// A kért szerepkör, egyébként null. + public static DAL.RoleGroup Get(int id) + { + return MembershipDBContext.RoleGroups.FirstOrDefault(x => x.Id == id); + } + /// + /// Szerepkör lekérése az egyedi neve alapján. + /// + /// A keresett szerepkör egyedi neve. + /// A kért szerepkör, egyébként null. + public static DAL.RoleGroup Get(string name) + { + return MembershipDBContext.RoleGroups.FirstOrDefault(x => x.Name == name); + } + /// + /// Szerepkör lekérése az egyedi neve alapján. + /// + /// A keresett szerepkör egyedi neve. + /// A kért szerepkör, egyébként null. + public static List GetAllNames() + { + return MembershipDBContext.RoleGroups.Select(rg=>rg.Name).ToList(); + } + public static bool IsUserInRoleGroup(string username,string rolegroupname) + { + return MembershipDBContext.RoleGroupUsers.Select(rguass => rguass.User.UserName == username && rguass.RoleGroup.Name == rolegroupname).ToList().Any(); + } + #endregion Get methods + + #region Create method + /// + /// Szerepkör létrehozása. + /// + /// A létrehozandó szerepkör. + /// + /// Ha üres vagy null a szerepkör neve. + /// Ha már létezik a megadott név. + /// + public static void Create(DAL.RoleGroup roleGroup) + { + if (String.IsNullOrWhiteSpace(roleGroup.Name)) { throw new ApplicationException("RoleGroup név megadása kötelező!"); } + + if (MembershipDBContext.RoleGroups.Any(x => x.Name == roleGroup.Name)) { throw new ApplicationException($"RoleGroup {roleGroup.Name} already exist!"); } + + MembershipDBContext.RoleGroups.Add(roleGroup); + MembershipDBContext.SaveChanges(); + } + /// + /// Szerepkör létrehozása. + /// + /// A létrehozandó szerepkör. + /// + /// Ha üres vagy null a szerepkör neve. + /// Ha már létezik a megadott név. + /// + public static void Create(string name) + { + if (String.IsNullOrWhiteSpace(name)) { throw new ApplicationException("RoleGroup név megadása kötelező!"); } + if (MembershipDBContext.RoleGroups.Any(x => x.Name == name)) { throw new ApplicationException($"RoleGroup {name} already exist!"); } + MembershipDBContext.RoleGroups.Add(new DAL.RoleGroup { Name = name, }); + MembershipDBContext.SaveChanges(); + } + #endregion Create method + + #region Remove methods + /// + /// Szerepkör törlése az egyedi azonosítója megadásával. + /// A szerepkörhöz tartozó összerendelések is megszűnnek! + /// + /// Törlendő szerep egyedi azonosítója. + /// Ha nem található a törlendő szerepkör. + public static void Remove(int id) + { + var row = MembershipDBContext.RoleGroups.Find(id); + if (row == null) { throw new ApplicationException("RoleGroup does not exist!!"); } + else { MembershipDBContext.RoleGroups.Remove(row); MembershipDBContext.SaveChanges(); } + } + /// + /// Szerepkör törlése az egyedi név megadásával. + /// A szerepkörhöz tartozó összerendelések is megszűnnek! + /// + /// Törlendő szerepkör egyedi neve. + /// Ha nem található a törlendő szerepkör. + public static void Remove(string name) + { + var row = MembershipDBContext.RoleGroups.FirstOrDefault(x => x.Name == name); + if (row == null) { Remove(-1); } + else { Remove(row.Id); } + } + #endregion Remove methods + } + #endregion RoleGroups + #region Assign + public static class Assign + { + #region RemoveOfUser + public static void RemoveOfUser(string username) + { + if (string.IsNullOrWhiteSpace(username)) { throw new Exception("Username can not be empty!"); } + var user = MembershipDBContext.Users.FirstOrDefault(u => u.UserName == username); + if (user==null) { throw new Exception($"User '{username}' does not exist!"); } + var rguasslist = MembershipDBContext.RoleGroupUsers.Where(rg => rg.UserId == user.UserId); + if (rguasslist == null || !rguasslist.Any()) { return; } + foreach (var rguass in rguasslist) { MembershipDBContext.RoleGroupUsers.Remove(rguass); } + } + #endregion RemoveOfUser + #region RolesToUser public method + /// + /// Role-RoleGroup-User összerendelések + /// + /// az összerendelés módját határozza meg + /// ezeket kell összerendelni... + /// ...ezekkel + /// + public static VRH.Common.ReturnInfoJSON RolesToUser(string rolenamecommalist, string usernamecommalist) + { + DAL.RoleGroup urg; + ReturnInfoJSON result = new ReturnInfoJSON() { ReturnMessage = "Assignment was successful!" }; + try + { + if (m_roleProvider != null) { throw new Exception("RoleService is not enabled!"); } + var rolenamelist = rolenamecommalist != null ? new List(rolenamecommalist.Split(',')) : new List(); + var usernamelist = usernamecommalist != null ? new List(usernamecommalist.Split(',')) : new List(); + foreach (var rolename in rolenamelist) + { + CheckRoleExists(rolename); + foreach (var username in usernamelist) + { + CheckUsersExists(username); + if (!Users.IsInRole(username, rolename)) { Roles.AddUserToRole(username, rolename); } + } + } + } + catch (Exception ex) + { + result.ReturnValue = -1; + result.ReturnMessage = ex.Message; + } + return result; + } + #endregion RolesToUser public method + #region RolesToRoleGroups public method + public static VRH.Common.ReturnInfoJSON RolesToRoleGroups(string rolenamecommalist, string rolegroupnamecommalist) + { + DAL.RoleGroup urg; + ReturnInfoJSON result = new ReturnInfoJSON() { ReturnMessage = "Assignment was successful!" }; + try + { + if (m_roleProvider != null) { throw new Exception("RoleService is not enabled!"); } + var rolenamelist = rolenamecommalist != null ? new List(rolenamecommalist.Split(',')) : new List(); + var rolegroupnamelist = rolegroupnamecommalist != null ? new List(rolegroupnamecommalist.Split(',')) : new List(); + foreach (var rolename in rolenamelist) + { + CheckRoleExists(rolename); + foreach (var rolegroupname in rolegroupnamelist) + { + CheckRoleGroupExists(rolegroupname); + DAL.Role role = MembershipDBContext.Roles.FirstOrDefault(x => x.RoleName == rolename); + urg = MembershipDBContext.RoleGroups.FirstOrDefault(x => x.Name == rolegroupname); + if (role != null && urg != null) + { + if (!urg.Roles.Any(x => x.Role.RoleName == rolename)) + { + urg.Roles.Add(new DAL.RoleGroupRole { Role = role }); + MembershipDBContext.SaveChanges(); + UpdateUsersForUserRoleGroup(urg.Id); + } + } + } + } + } + catch (Exception ex) + { + result.ReturnValue = -1; + result.ReturnMessage = ex.Message; + } + return result; + } + #endregion RolesToRoleGroups public method + #region RoleGroupsToUsers public method + public static VRH.Common.ReturnInfoJSON RoleGroupsToUsers(string rolegroupnamecommalist, string usernamecommalist) + { + DAL.RoleGroup urg; + ReturnInfoJSON result = new ReturnInfoJSON() { ReturnMessage = "Assignment was successful!" }; + try + { + if (m_roleProvider != null) { throw new Exception("RoleService is not enabled!"); } + var rolegroupnamelist = rolegroupnamecommalist != null ? new List(rolegroupnamecommalist.Split(',')) : new List(); + var usernamelist = usernamecommalist != null ? new List(usernamecommalist.Split(',')) : new List(); + foreach (var rolegroupname in rolegroupnamelist) + { + CheckRoleGroupExists(rolegroupname); + foreach (var username in usernamelist) + { + CheckUsersExists(username); + Guid userId = Guid.Empty; + if (Guid.TryParse(Users.Get(username).ProviderUserKey.ToString(), out userId)) + { + urg = MembershipDBContext.RoleGroups.FirstOrDefault(x => x.Name == rolegroupname); + DAL.User u = MembershipDBContext.Users.FirstOrDefault(x => x.UserId == userId); + if (u != null && urg != null) + { + if (!urg.Users.Any(x => x.UserId == userId)) + { + urg.Users.Add(new DAL.RoleGroupUser { User = u }); + MembershipDBContext.SaveChanges(); + UpdateRolesForUser(u.UserId); + } + } + } + } + } + } + catch (Exception ex) + { + result.ReturnValue = -1; + result.ReturnMessage = ex.Message; + } + return result; + } + #endregion RoleGroupsToUsers public method + #region private CheckRoleGroupExists,CheckRoleExists,CheckUsersExists + /// + /// Ellenőrzi, van-e ilyen role group + /// + /// ellenőrizendő role group + private static void CheckRoleGroupExists(string roleGroup) + { + if (!MembershipDBContext.RoleGroups.Any(x => x.Name == roleGroup)) { throw new Exception($"RoleGroup {roleGroup} does not exist!"); } + } + /// + /// Ellenőrzi, van-e ilyen role + /// + /// az ellenőrizendő role + private static void CheckRoleExists(string role) + { + if (!System.Web.Security.Roles.GetAllRoles().ToList().ConvertAll(r => r.ToUpper()).Contains(role.ToUpper())) + { + throw new Exception($"Role {role} does not exist!"); + } + } + /// + /// Ellenőrzi van-e ilyen usernevű user + /// + /// Ellenőrizendő user userneve + private static void CheckUsersExists(string userName) + { + bool exists = false; + foreach (MembershipUser user in System.Web.Security.Membership.GetAllUsers()) + { + if (user.UserName.ToUpper() == userName.ToUpper()) { exists = true; break; } + } + if (!exists) { throw new Exception($"User {userName} does not exist!"); } + } + #endregion private CheckRoleGroupExists,CheckRoleExists,CheckUsersExists + + #region private UpdateRolesForUser + /// + /// Frissíti a megadott felhasználó szerepeit a felhasználó szerepkörei alapján + /// + /// felhasználó UserID-ja + private static void UpdateRolesForUser(Guid userId) + { + MembershipUser user = System.Web.Security.Membership.GetUser(userId, false); + if (user != null) + { + // eltávolítjuk az összes szerepkörét a felhasználónak, majd a felhasználóhoz tartozó UserRoleGroup-okban lévő Roles-okat adjuk hozzá a felhasználóhoz + if (Roles.GetRolesForUser(user.UserName).Any()) + { + Roles.RemoveUserFromRoles(user.UserName, Roles.GetRolesForUser(user.UserName)); + } + foreach (DAL.RoleGroup urg in MembershipDBContext.RoleGroups.Where(x => x.Users.Any(y => y.UserId == userId))) + { + foreach (string roleName in urg.Roles.Select(x => x.Role.RoleName)) + { + if (!Roles.IsUserInRole(user.UserName, roleName)) + { + Roles.AddUserToRole(user.UserName, roleName); + } + } + } + } + } + #endregion private UpdateRolesForUser + #region private UpdateUsersForUserRoleGroup + /// + /// Frissíti a megadott szerepkörhöz tartozó felhasználók szerepeit a szerepkörök alapján + /// + /// UserRoleGroup Id-ja + private static void UpdateUsersForUserRoleGroup(int userRoleGroupId) + { + DAL.RoleGroup urg = MembershipDBContext.RoleGroups.SingleOrDefault(x => x.Id == userRoleGroupId); + if (urg != null) + { + foreach (Guid userId in urg.Users.Select(x => x.UserId)) + { + UpdateRolesForUser(userId); + } + } + } + #endregion private UpdateUsersForUserRoleGroup + } + #endregion Assign + #region DAL + public static class DAL + { + #region tables + #region table-User + /// + /// DefaultMembershipProvider által létrehozott User tábla. + /// Ha változik az aktuális verzió, és emiatt a tábla szerkezete, akkor ezt módosítani kell. + /// + [Table("Users", Schema = "dbo")] + public partial class User + { + /// + /// Felhasználó egyedi azonosítója. + /// + [Key, DatabaseGenerated(DatabaseGeneratedOption.None)] + public Guid UserId { get; set; } + + /// + /// Melyik alkalmazás felhasználója. + /// + public Guid ApplicationId { get; set; } + + /// + /// Felhasználó neve. + /// + [Required, MaxLength(50)] + public string UserName { get; set; } + + /// + /// Felhasználó névtelenül bejelentjezhet-e. + /// + public bool IsAnonymous { get; set; } + + /// + /// Felhasználó utolsó aktivitésénak időpontja. + /// + public DateTime LastActivityDate { get; set; } + + #region Virtual Collections + + /// + /// A felhasználó szerepkörei. + /// + public virtual ICollection UserRoleGroupUsers { get; set; } + + #endregion Virtual Collections + + } + #endregion table-User + #region table-RoleGroupUser + /// + /// Szerepkörök és felhasználók összerendelése. + /// + [Table(nameof(MembershipContext.RoleGroupUsers), Schema = Constants.SCHEMA_NAME)] + public partial class RoleGroupUser + { + /// + /// Szerepkör egyedi azonosítója. + /// + [Key, Column(Order = 0), DatabaseGenerated(DatabaseGeneratedOption.None)] + public int RoleGroupId { get; set; } + + /// + /// Felhasználó egyedi azonosítója. + /// + [Key, Column(Order = 1), DatabaseGenerated(DatabaseGeneratedOption.None)] + public Guid UserId { get; set; } + + #region Virtual foreignkeys + + [ForeignKey(nameof(RoleGroupId))] + public virtual RoleGroup RoleGroup { get; set; } + + [ForeignKey(nameof(UserId))] + public virtual User User { get; set; } + + #endregion Virtual foreignkeys + } + #endregion table-RoleGroupUser + #region table-RoleGroupRole + /// + /// Szerepkörök és szerepek összerendelése. + /// + [Table(nameof(MembershipContext.RoleGroupRoles), Schema = Constants.SCHEMA_NAME)] + public partial class RoleGroupRole + { + /// + /// Szerepkör egyedi azonosítója. + /// + [Key, Column(Order = 0), DatabaseGenerated(DatabaseGeneratedOption.None)] + public int RoleGroupId { get; set; } + + /// + /// Szerep egyedi azonosítója. + /// + [Key, Column(Order = 1), DatabaseGenerated(DatabaseGeneratedOption.None)] + public Guid RoleId { get; set; } + + #region Virtual foreignkeys + + [ForeignKey(nameof(RoleGroupId))] + public virtual RoleGroup RoleGroup { get; set; } + + [ForeignKey(nameof(RoleId))] + public virtual Role Role { get; set; } + + #endregion Virtual foreignkeys + } + #endregion table-RoleGroupRole + #region table-RoleGroup + /// + /// Szerepkörök táblázata. + /// + [Table(nameof(MembershipContext.RoleGroups), Schema = Constants.SCHEMA_NAME)] + public partial class RoleGroup + { + #region Properties + + /// + /// Szerepkör egyedi azonosítója. + /// + [Key] + public int Id { get; set; } + + /// + /// Szerepkör egyedi megnevezése. + /// + [Required, MaxLength(256), Index(IsUnique = true)] + public string Name { get; set; } + + #endregion Properties + + #region Virtual Collections + + /// + /// A szerepkörhöz ezek a szerepek tartoznak. + /// + public virtual ICollection Roles { get; set; } + + /// + /// A szerepkörhöz ezek a felhasználók tartoznak. + /// + public virtual ICollection Users { get; set; } + + #endregion Virtual Collections + + #region Constructor + public RoleGroup() + { + Roles = new HashSet(); + Users = new HashSet(); + } + #endregion Constructor + } + #endregion table-RoleGroup + #region table-Role + /// + /// DefaultMembershipProvider által létrehozott User tábla. + /// + [Table("Roles", Schema = "dbo")] + public partial class Role + { + /// + /// Szerep egyedi azonosítója. + /// + [Key, DatabaseGenerated(DatabaseGeneratedOption.None)] + public Guid RoleId { get; set; } + + /// + /// Melyik alkalmazás szerepe. + /// + public Guid ApplicationId { get; set; } + + /// + /// Szerep neve. + /// + [Required, MaxLength(256)] + public string RoleName { get; set; } + + /// + /// Alkalmazás rövid leírása. + /// + [MaxLength(256)] + public string Description { get; set; } + } + #endregion table-Role + #region table-SecondaryFunction + /// + /// Lehetséges funkciókat tartalmazó táblázat, mely funkciókhoz + /// tartozhat a másodlagos felhasználó. + /// + [Table(nameof(MembershipContext.SecondaryFunctions), Schema = Constants.SCHEMA_NAME)] + public partial class SecondaryFunction + { + #region Properties + + /// + /// A funkció egyedi azonosítója. + /// + [Key] + public int Id { get; set; } + + /// + /// A funkció egyedi megnevezése. + /// + [Required, MaxLength(30), Index(IsUnique = true)] + public string Name { get; set; } + + #endregion Properties + + #region Virtual Collections + + /// + /// A funkcióhoz ezek a másodlagos felhasználók tartoznak tartoznak. + /// + public virtual ICollection SecondaryUsers { get; set; } + + #endregion Virtual Collections + + #region Constructor + public SecondaryFunction() + { + SecondaryUsers = new HashSet(); + } + #endregion Constructor + } + #endregion table-SecondaryFunction + #region table-SecondaryUser + /// + /// Másodlagos felhasználók adatait tartalmazó táblázat. + /// + [Table(nameof(MembershipContext.SecondaryUsers), Schema = Constants.SCHEMA_NAME)] + public partial class SecondaryUser + { + private const string INDEX_FUNCTION_NAME = "IX_SecondaryUser_SecondaryFunctionId_Name"; + + #region Properties + + /// + /// Másodlagos felhasználó belső egyedi azonosítója. + /// + [Key, Index(IsClustered = false)] + public int Id { get; set; } + + /// + /// Az elsődleges felhasználó egyedi azonosítója a dbo.Users táblából. + /// Ő hozzá tartozik a másodlagos felhasználó. + /// + public Guid UserId { get; set; } + + /// + /// Melyik funkcióhoz tartozik a másodlagos felhasználó. + /// + [Index(INDEX_FUNCTION_NAME, 1, IsUnique = true, IsClustered = true)] + public int SecondaryFunctionId { get; set; } + + /// + /// Másodlagos felhasználó neve. + /// + [Required, MaxLength(255)] + [Index(INDEX_FUNCTION_NAME, 2, IsUnique = true, IsClustered = true)] + public string Name { get; set; } + + /// + /// Másodlagos felhasználó jelszava. + /// + [MaxLength(255)] + public string Password { get; set; } + + /// + /// Másodlagos felhasználó érvényes-e jelenleg. + /// + public bool Active { get; set; } = true; + + #endregion Properties + + #region Virtual foreignkeys + + /// + /// A másodlagos felhasználó ehhez az elsődleges felhasználóhoz tartozik. + /// + [ForeignKey(nameof(UserId))] + public virtual User User { get; set; } + + /// + /// A másodlagos felhasználó ehhez a funkcióhoz tartozik. + /// + [ForeignKey(nameof(SecondaryFunctionId))] + public virtual SecondaryFunction SecondaryFunction { get; set; } + + #endregion Virtual foreignkeys + + #region Constructor + public SecondaryUser() + { + } + #endregion Constructor + + public override string ToString() + { + return String.Concat("{", + nameof(Id), "=", this.Id.ToString(), "; ", + nameof(UserId), "=", this.UserId, "; ", + nameof(SecondaryFunctionId), "=", this.SecondaryFunctionId.ToString(), "; ", + nameof(Name), "=", this.Name, "; ", + nameof(Password), "=", this.Password, "; ", + nameof(Active), "=", this.Active.ToString(), + "}" + ); + } + } + #endregion table-SecondaryUser + #region table-SecondaryLogin + /// + /// Másodlagos felhasználók bejelentkezéseit nyilvántartó táblázat. + /// Egy másodlagos felhasználónak egy bejelentkezése tartozhat egy célhoz. + /// Vagyis a UserID+TargetId együtt egyedi kulcsot alkot. + /// + [Table(nameof(MembershipContext.SecondaryLogins), Schema = Constants.SCHEMA_NAME)] + public partial class SecondaryLogin + { + private const string INDEX_USER_TARGET = "IX_SecondaryLogin_UserId_TargetKey"; + + #region Properties + + /// + /// A bejelentkezés belső egyedi azonosítója. + /// + [Key] + public int Id { get; set; } + + /// + /// Másodlagos felhasználó azonosítója, akinek a nevében történt a bejelentkezés. + /// + [Index(INDEX_USER_TARGET, 1, IsUnique = true)] + public int SecondaryUserId { get; set; } + + /// + /// A bejelentkezéshez tartozó azonosító. Értelmezése: + /// Mi célból történt a bejelentkezés? + /// + [MaxLength(20), Index(INDEX_USER_TARGET, 2, IsUnique = true)] + public string TargetKey { get; set; } + + /// + /// Bejelentkezés időpontja. + /// + public DateTime LoginTime { get; set; } + + /// + /// A legutóbbi aktivitás időpontja. + /// + public DateTime LastActivityTime { get; set; } + + #endregion Properties + + #region Virtual foreignkeys + + /// + /// A másodlagos felhasználóra mutató tulajdonság. + /// + [ForeignKey(nameof(SecondaryUserId))] + public virtual SecondaryUser SecondaryUser { get; set; } + + #endregion Virtual foreignkeys + + public override string ToString() + { + return String.Concat("{", + nameof(Id), "=", this.Id.ToString(), "; ", + nameof(SecondaryUserId), "=", this.SecondaryUserId.ToString(), "; ", + nameof(DAL.SecondaryUser.Name), "=", this.SecondaryUser.Name, "; ", + nameof(TargetKey), "=", this.TargetKey ?? "null", "; ", + nameof(LoginTime), "=", this.LoginTime.ToString("G"), "; ", + nameof(LastActivityTime), "=", this.LastActivityTime.ToString("G"), + "}" + ); + } + + } + #endregion table-SecondaryLogin + #region table-UserSupplement + /// + /// A DefaultMembershipProvider 'User' táblájában nem szabad változtatásokat eszközölni + /// a jövőbeni esetleges Microsoft fejlesztések miatt. + /// Ez a tábla arra való, hogy a felhasználóra vonatkozó egyéb kiegészítő adatokat + /// legyen hol tárolni. + /// + /// + /// Ha nincsenek a felhasználónak kiegészítő adatai akkor nem lesz itt rekordja. + /// + [Table(nameof(MembershipContext.UserSupplements), Schema = Constants.SCHEMA_NAME)] + public partial class UserSupplement + { + #region Properties + + /// + /// A felhasználó egyedi azonosítója a 'User' táblából. + /// Itt is csak 1 db azonosító lehet. + /// + [Key, DatabaseGenerated(DatabaseGeneratedOption.None)] + public Guid UserId { get; set; } + + /// + /// Annak jelzése, hogy a felhasználó ideiglenesen létrehozott felhasználó. + /// Ha igaz, akkor ideiglenes, egyébként hamis. Ha nem létezik a felhasználónak + /// itt rekordja, akkor nem ideiglenes felhasználó. + /// Alapértelmezett érték: true. + /// + public bool IsTemporary { get; set; } = true; + + #endregion Properties + + #region Virtual foreignkeys + + [ForeignKey(nameof(UserId))] + public virtual User User { get; set; } + + #endregion Virtual foreignkeys + } + #endregion table-UserSupplement + #endregion tables + + #region MembershipContext + public class MembershipContext : DbContext + { + #region Constructors + // Your context has been configured to use a 'VrhWebMembership' connection string from your application's + // configuration file (App.config or Web.config). + public MembershipContext(string sqlcs) : base(sqlcs) + { + } + #endregion Constructors + + #region DbSets + + #region !!! A migrációból kivett két tábla. Ezeket a DefaultMembershipProvider kezeli és hozza létre. !!! + public virtual DbSet Roles { get; set; } + public virtual DbSet Users { get; set; } + #endregion !!! A migrációból kivett két tábla. Ezeket a DefaultMembershipProvider kezeli és hozza létre. !!! + + // Saját táblák, melyek a Global.SCHEMA_NAME állandó szerinti sémában vannak. + public virtual DbSet RoleGroups { get; set; } + public virtual DbSet RoleGroupRoles { get; set; } + public virtual DbSet RoleGroupUsers { get; set; } + public virtual DbSet SecondaryFunctions { get; set; } + public virtual DbSet SecondaryLogins { get; set; } + public virtual DbSet SecondaryUsers { get; set; } + public virtual DbSet UserSupplements { get; set; } + #endregion DbSets + + #region OnModelCreating + protected override void OnModelCreating(DbModelBuilder modelBuilder) + { + //modelBuilder.HasDefaultSchema("GoodBill"); + + //WA20160124: Sajnos az EF a kötelező idegen kulcsnál alapértelmezésként cascadeDelete értékét true-ra állítja, + // ami sok esetben nem megfelelő (nem is értem, miért true a default :(( ) + // Ahol ez előfordul, ott a ForeignKey-eket itt kell definiálni. + // HasRequired = many oldal virtual property + // WithMany = ha a one oldalon lett definiálva ICollection a many-ra, akkor azt kell ide írni, egyébként üres + // HasForeignKey = many oldalon a foreign key mező + } + #endregion OnModelCreating + } + #endregion MembershipContext + } + #endregion DAL + } +} \ No newline at end of file diff --git a/Vrh.Log4Pro.MaintenanceConsole/ConsoleFunction - Tools.cs b/Vrh.Log4Pro.MaintenanceConsole/ConsoleFunction - Tools.cs index 44dc1bc..28ab78e 100644 --- a/Vrh.Log4Pro.MaintenanceConsole/ConsoleFunction - Tools.cs +++ b/Vrh.Log4Pro.MaintenanceConsole/ConsoleFunction - Tools.cs @@ -1,9 +1,11 @@ using System; using System.IO; +using System.IO.Compression; using System.Collections.Generic; using System.Linq; using System.Security.Principal; using System.Text; +using System.Text.RegularExpressions; using System.Threading.Tasks; using System.Threading; @@ -13,11 +15,101 @@ using System.Diagnostics; using Vrh.XmlProcessing; using System.Xml.Linq; +using Vrh.Log4Pro.MaintenanceConsole.ColorConsoleNS; +using VRH.Common; -namespace Vrh.Log4Pro.MaintenanceConsole +namespace Vrh.Log4Pro.MaintenanceConsole.ToolsNS { + public static class ZipTools + { + public static void Extract1stFileFromZIP(string targetfilefullpath, string ZIPfilefullpath) + { + if (File.Exists(targetfilefullpath)) { File.Delete(targetfilefullpath); } + using (ZipArchive archive = ZipFile.Open(ZIPfilefullpath, ZipArchiveMode.Read)) + { + foreach (var zipentry in archive.Entries) + { + zipentry.ExtractToFile(targetfilefullpath); + return; + } + } + } + public static void ExtractAllFileFromZIP(string targetdirectorypath, string ZIPfilefullpath) + { + if (!Directory.Exists(targetdirectorypath)) { Directory.CreateDirectory(targetdirectorypath); } + using (ZipArchive archive = ZipFile.Open(ZIPfilefullpath, ZipArchiveMode.Read)) + { + foreach (var zipentry in archive.Entries) + { + zipentry.ExtractToFile(Path.Combine(targetdirectorypath, zipentry.FullName)); + } + } + } + + public static void CreateEntriesFromDirectoryContent(string sourcefolderpath, string ZIPfilefullpath, string includefilenamemask, string includefullpathregex, bool removearchivedfiles = false,bool storepathinzip = true) + { + if (File.Exists(ZIPfilefullpath)) { File.Delete(ZIPfilefullpath); } + DirectoryInfo di = new DirectoryInfo(sourcefolderpath); + var rgx = new Regex(includefullpathregex??""); + var archivedfiles = new List(); + using (ZipArchive archive = ZipFile.Open(ZIPfilefullpath, ZipArchiveMode.Create)) + { + ColorConsole.WriteLine($"ZIP-ping directory '{sourcefolderpath}'...", ConsoleColor.Yellow); + FileInfo[] fis = di.GetFiles(includefilenamemask, SearchOption.AllDirectories); + int maxfilefullpathlength = 0; + int cpt = ColorConsole.CursorTop; + int cpl = ColorConsole.CursorLeft; + foreach (var fi in fis) + { + var entryname = storepathinzip + ? fi.FullName.Substring((Path.GetPathRoot(fi.FullName)?.Length) ?? 0) + : fi.Name; + if (rgx.Match(fi.FullName).Success) + { + try + { + archive.CreateEntryFromFile(fi.FullName, entryname, CompressionLevel.Optimal); + ColorConsole.Write(fi.FullName, ConsoleColor.Yellow); + if (maxfilefullpathlength > fi.FullName.Length) + { + ColorConsole.Write(new string(' ', maxfilefullpathlength - fi.FullName.Length)); + } + else { maxfilefullpathlength = fi.FullName.Length; } + ColorConsole.SetCursorPosition(cpl, cpt); + archivedfiles.Add(fi.FullName); + } + catch (Exception ex) + { + ColorConsole.WriteLine($"Error when accessing/zipping file '{fi.FullName}'!", ConsoleColor.Red); + ColorConsole.WriteLine(ex.Message, ConsoleColor.Red,prefix: "Exception message: ", bracket:"[]"); + } + } + cpt = ColorConsole.CursorTop; + cpl = ColorConsole.CursorLeft; + } + ColorConsole.Write(new string(' ', maxfilefullpathlength)); + ColorConsole.SetCursorPosition(cpl, cpt); + } + if (removearchivedfiles) + { + archivedfiles.ForEach(x => File.Delete(x)); + string[] dirs = System.IO.Directory.GetDirectories(sourcefolderpath); + string[] files = System.IO.Directory.GetFiles(sourcefolderpath); + if (dirs.Length + files.Length == 0) { Directory.Delete(sourcefolderpath); } + } + } + } public static class Tools { + public static T GetPropertyValue(object obj, string propName) { return (T)obj.GetType().GetProperty(propName).GetValue(obj, null); } + + public static Dictionary Merge(IEnumerable> dictionaries) + { + return dictionaries.SelectMany(x => x) + .GroupBy(d => d.Key) + .ToDictionary(x => x.Key, y => y.First().Value); + } + public static bool IsElevated { get @@ -72,5 +164,15 @@ namespace Vrh.Log4Pro.MaintenanceConsole return outputBuilder.ToString(); } } + + public static string GetTemporaryFoldername(string directorypath) + { + return Path.Combine(directorypath, DateTime.Now.ToString($"TMP_yyyyMMddHHmmssfffffff")); + } + public static string GetTemporaryfilename(string directorypath, string extension) + { + if (extension == null) { extension = ".tmp"; } + return Path.Combine(directorypath, DateTime.Now.ToString($"TMP_yyyyMMddHHmmssfffffff.{extension}")); + } } } diff --git a/Vrh.Log4Pro.MaintenanceConsole/Icon_Log4ProService.ico b/Vrh.Log4Pro.MaintenanceConsole/Icon_Log4ProService.ico new file mode 100644 index 0000000..5c4ab8b Binary files /dev/null and b/Vrh.Log4Pro.MaintenanceConsole/Icon_Log4ProService.ico differ diff --git a/Vrh.Log4Pro.MaintenanceConsole/Manager - BackupPackageManager.cs b/Vrh.Log4Pro.MaintenanceConsole/Manager - BackupPackageManager.cs new file mode 100644 index 0000000..97a8fe3 --- /dev/null +++ b/Vrh.Log4Pro.MaintenanceConsole/Manager - BackupPackageManager.cs @@ -0,0 +1,513 @@ +using System; +using System.IO; +using System.IO.Compression; +using System.Configuration.Install; +using System.Collections.Generic; +using System.Linq; +using System.ServiceProcess; +using System.Text; +using System.Threading; +using System.Threading.Tasks; + +using Microsoft.Web.Administration; +using System.Management; +using System.Diagnostics; + +using Vrh.Log4Pro.MaintenanceConsole.MenuNS; +using Vrh.Log4Pro.MaintenanceConsole.ColorConsoleNS; +using Vrh.Log4Pro.MaintenanceConsole.ToolsNS; +using Vrh.Log4Pro.MaintenanceConsole.CommandLineParserNS; + +using Vrh.XmlProcessing; +using VRH.Common; +using System.Xml.Linq; +using System.Text.RegularExpressions; + +namespace Vrh.Log4Pro.MaintenanceConsole.BackupPackageManagerNS +{ + #region BackupPackageManager class + public static class BackupPackageManager + { + private const string XMLCONNECTIONSTRING = "config=MAINTENANCECONSOLE_BACKUPMANAGER;"; + private const string XMLCONNECTIONSTRING_DEFAULT = "file=Config.Xml;element=BackupPackages;"; + private const string PACKAGESELECTIONPROMPT = "Select the backup package(s) to manage with function '{0}'!"; + + #region Execute + public static object Execute(object o1 = null, object o2 = null) + { + var args = (o1 as Menu.ExecutorParameter).Args; + var functionkey = CommandLine.GetCommandLineArgument(args, CLP.CMD_FUNCTION); + var config = new BackupPackageManagerXmlProcessor(XMLCONNECTIONSTRING, "", "hu-HU"); + var ep = new Menu.ExecutorParameter(config, args); + + var menufunctions = new Menu("Manage Backup Packages", "Select the management function!") + .AddMenuItem(new Menu.Item(CLP.Module.BackupPackageManager.Functions.CreateBackupPackage.KEY, "Create backup package", CreateBackupPackage,ep)) + .SetSelectionMode(Menu.SelectionMode.Single) + .SetMenuHeaderDisplayer(BackupPackageListDisplayer); + menufunctions.ExecuteMenu(functionkey); + return o2; + } + #endregion Execute + + #region First level Executors with UI + private static object CreateBackupPackage(object parameter, object o) + { + var config = (parameter as Menu.ExecutorParameter).GetConfig< BackupPackageManagerXmlProcessor>(); + var args = (parameter as Menu.ExecutorParameter).Args; + + var selectedtaskindexes = CommandLine.GetCommandLineArgument(args, CLP.Module.BackupPackageManager.Functions.CMD_PACKAGES); + + var menufolders = DisplayBackupPackageMenu(config, string.Format(PACKAGESELECTIONPROMPT,nameof(CreateBackupPackage)), silent:true); + + Menu.Selection sr = menufolders.Select(selectedtaskindexes); + if (sr.Result == Menu.SelectionResult.Exit) { return o; } + else if (sr.Result == Menu.SelectionResult.None) { return o; } + else if (sr.Result == Menu.SelectionResult.Error) { return o; } + else if (sr.Result == Menu.SelectionResult.Ok) { } + else { } + + var TS = DateTime.Now; + foreach (var p in sr.SelectedParameterList) { OnePackageToCreate(p.Parameters as BackupPackage,TS); } + return o; + } + private static void OnePackageToCreate(BackupPackage bp,DateTime? timestamp=null) + { + try + { + //packaget + var packagets = (timestamp.HasValue ? timestamp.Value : DateTime.Now).ToString("yyyyMMddHHmmss"); + var vars = new Dictionary(); + vars.Add("PACKAGENAME", bp.Xml_PackageName); + vars.Add("PACKAGETS", packagets); + + var destinationfolder = Path.GetDirectoryName(bp.Xml_PackageFilePath); + if (!Path.IsPathRooted(destinationfolder)) { destinationfolder = Path.Combine(Directory.GetCurrentDirectory(), destinationfolder); } + if (!Directory.Exists(destinationfolder)) { Directory.CreateDirectory(destinationfolder); } + + var destinationfilename = Path.GetFileNameWithoutExtension(bp.Xml_PackageFilePath); + //string tempfolderpath = Tools.GetTemporaryFoldername(destinationfolder); + string tempfolderpath = StringConstructor.ResolveConstructor(vars, Path.Combine(destinationfolder,destinationfilename), "{}@@"); + if (Directory.Exists(tempfolderpath)) { Directory.Delete(tempfolderpath, true); } + + if (!Directory.Exists(tempfolderpath)) { Directory.CreateDirectory(tempfolderpath); } + + foreach (var bf in bp.Xml_BackupFolderList) + { + BackupPackageManagerCore.FolderZipBackup(bf, tempfolderpath, vars); + } + foreach (var sqldb in bp.Xml_BackupSQLDataBaseList) + { + SQLDataBaseManagerNS.SQLDataBaseManager.Execute(sqldb.Xml_Key,sqldb.Xml_DBBackup,sqldb.Xml_ScriptBackup,sqldb.Xml_TableDataBackup, tempfolderpath, timestamp); + } + + BackupPackageManagerCore.CreatePackageFile(bp, tempfolderpath, vars); + if (Directory.Exists(tempfolderpath)) { Directory.Delete(tempfolderpath,true); } + } + catch (Exception ex) { ColorConsole.WriteLine(ex.Message, ConsoleColor.Red); } + } + #endregion First level Executors with UI + + #region private methods + #region private DisplayBackupPackages + private static void BackupPackageListDisplayer() { DisplayBackupPackageMenu(); } + private static Menu DisplayBackupPackageMenu(BackupPackageManagerXmlProcessor config=null, string prompt=null, bool silent=false) + { + if (config==null) { config = new BackupPackageManagerXmlProcessor(XMLCONNECTIONSTRING, "", "hu-HU"); } + List bfdefList = config.GetDefinitionList(); + var menubp = new Menu("Backup packages",prompt) + .SetMenuItemDisplayer(DisplayBackupPackageInfo) + .SetSelectionMode(Menu.SelectionMode.Multi); + menubp.ClearMenuItemList(); + foreach (var bfdef in bfdefList) + { + var fi = CollectBackupPackageInfo(bfdef); + menubp.AddMenuItem(new Menu.Item(bfdef.Xml_Key, null, null, new Menu.ExecutorParameter(pars:fi))); + } + if (!silent) { menubp.DisplayItems(1); } + return menubp; + } + #endregion private DisplayBackupPackages + + #region private method: DisplayBackupPackageInfo + private static object DisplayBackupPackageInfo(object obj, int lineix) + { + BackupPackage bp = ((obj as Menu.ExecutorParameter).Parameters as BackupPackage); + if (lineix == 0) + { + ColorConsole.Write($"{bp.Xml_PackageName}", ConsoleColor.Black, ConsoleColor.White); + ColorConsole.Write($"{bp.Xml_Description}", ConsoleColor.White,prefix:", "); + ColorConsole.WriteLine(""); + return " "; + } + if (lineix == 1) + { + ColorConsole.Write($"{bp.Xml_PackageFilePath}", ConsoleColor.White, prefix: "Package:"); + ColorConsole.WriteLine(""); + return " "; + } + if (lineix == 2) + { + ColorConsole.Write($"{bp.Xml_SourceIncludeFilenameMaskList}", ConsoleColor.White, prefix: "Mask:"); + ColorConsole.Write($"{bp.SizePackageTotal}", ConsoleColor.White, prefix: ", Bytes to include:"); + ColorConsole.WriteLine(""); + return " "; + } + return null; + } + #endregion private method: DisplayBackupPackageInfo + + #region private CollectBackupPackageInfo + private static BackupPackage CollectBackupPackageInfo(BackupPackage bp) + { + bp.SizePackageTotal= 0; + foreach (var bf in bp.Xml_BackupFolderList) + { + bf.FolderExists = Directory.Exists(bf.Xml_Path); + if (bf.FolderExists) + { + var di = new DirectoryInfo(bf.Xml_Path); + bp.SizePackageTotal += Vrh.Log4Pro.MaintenanceConsole.FileCleanerManagerNS.FileCleanerManagerCore.DirSize(di, bf.Xml_IncludeFileNameMask, bf.Xml_IncludeFileFullPathRegex, recurse: true); + } + } + return bp; + } + #endregion private CollectBackupPackageInfo + #endregion private methods + } + #endregion BackupPackageManager class + + #region class BackupPackageManagerCore + public static class BackupPackageManagerCore + { + /// + /// Create zip package content file + /// + /// BackupFolder descriptor + /// the target directory path where the zip file is created + /// filename substitution variables + public static void FolderZipBackup(BackupPackage.BackupFolder bf, string destinationfolderpath, Dictionary vars) + { + string foldertobackuppath = bf.Xml_Path; + + string destinationbackupfile = bf.Xml_BackupToFile; + if (string.IsNullOrEmpty(destinationbackupfile)) { destinationbackupfile = (new DirectoryInfo(foldertobackuppath)).Name + ".zip"; } + string includefilenamemask = bf.Xml_IncludeFileNameMask; + string includefullpathregex = bf.Xml_IncludeFileFullPathRegex; + + var destinationfile = Path.GetFileNameWithoutExtension(destinationbackupfile); + var destinationext = Path.GetExtension(destinationbackupfile); if (string.IsNullOrWhiteSpace(destinationext)) { destinationext = ".zip"; } + destinationbackupfile = Path.Combine(destinationfolderpath, destinationfile+destinationext); + + destinationbackupfile = VRH.Common.StringConstructor.ResolveConstructor(vars, destinationbackupfile, "{}@@"); + + if (File.Exists(destinationbackupfile)) { File.Delete(destinationbackupfile); } + + if (!Path.IsPathRooted(foldertobackuppath)) { foldertobackuppath = Path.Combine(Directory.GetCurrentDirectory(), foldertobackuppath); } + ZipTools.CreateEntriesFromDirectoryContent(foldertobackuppath, destinationbackupfile, includefilenamemask,includefullpathregex); + ColorConsole.WriteLine($"Folder backup created. Name:{foldertobackuppath}", ConsoleColor.DarkGreen); + } + /// + /// Create package compressed file + /// + /// package descriptor + /// source directory, where the package content files are located; + /// the package file will be created with the same name with zip or exe extension in its parent directory + /// substitution vars + public static void CreatePackageFile(BackupPackage bp,string sourcedirectorypath, Dictionary vars) + { + string[] sourceincludefilenamemasklist = bp.Xml_SourceIncludeFilenameMaskList.Split(','); + bool createselfextractor = bp.Xml_CreateExe; + + if (!Path.IsPathRooted(sourcedirectorypath)) { sourcedirectorypath = Path.Combine(Directory.GetCurrentDirectory(), sourcedirectorypath); } + + var destinationfolder = Path.GetDirectoryName(sourcedirectorypath); + if (!Path.IsPathRooted(destinationfolder)) { destinationfolder = Path.Combine(Directory.GetCurrentDirectory(), destinationfolder); } + var destinationfile = Path.GetFileNameWithoutExtension(sourcedirectorypath); + + string package___filepath = Path.Combine(destinationfolder, destinationfile); + package___filepath=VRH.Common.StringConstructor.ResolveConstructor(vars, package___filepath, "{}@@"); + + string packageEXEfilepath = package___filepath + ".exe"; + string packageZIPfilepath = package___filepath + ".zip"; + if (File.Exists(packageEXEfilepath)) { File.Delete(packageEXEfilepath); } + if (File.Exists(packageZIPfilepath)) { File.Delete(packageZIPfilepath); } + + List includefilepathlist = new List(); + foreach (var includefilenamemask in sourceincludefilenamemasklist) { includefilepathlist.Add(Path.Combine(sourcedirectorypath, includefilenamemask)); } + + string includeliststr = String.Join(" ", includefilepathlist.ToArray()); + string recursesubdirs = "-r"; + string addfilecommand = "a"; + string response; + string packagefile; + if (createselfextractor) + { + string archivetype_7z = "-t7z"; + string createsfx = "-sfx"; + packagefile = packageEXEfilepath; + response = Tools.ExecuteAndGetStdIo("7z.exe", $"{addfilecommand} {packagefile} {includeliststr} {recursesubdirs} {archivetype_7z} {createsfx}"); + } + else + { + string archivetype_zip = "-tzip"; + packagefile = packageZIPfilepath; + response = Tools.ExecuteAndGetStdIo("7z.exe", $"{addfilecommand} {packagefile} {includeliststr} {recursesubdirs} {archivetype_zip}"); + } + ColorConsole.WriteLine($"Backup package created. Package name:{bp.Xml_PackageName}, package file: {packagefile}", ConsoleColor.Green); + + + // 7 - Zip[64] 16.04 : Copyright(c) 1999 - 2016 Igor Pavlov : 2016 - 10 - 04 + // + // Usage: 7z[< switches > ...] < archive_name > [< file_names > ...] [< @listfiles...>] + // Sample: + // 7z a -t7z -sfx __7zTESTTXT.EXE *.txt -- create __7zTESTTXT.EXE self extracting archive of all files of current directory with txt extension + // 7z a -tzip __7zTESTTXT.ZIP *.txt -- create __7zTESTTXT.ZIP archive of all files of current directory with txt extension + // + // + // a : Add files to archive + // b : Benchmark + // d : Delete files from archive + // e : Extract files from archive (without using directory names) + // h : Calculate hash values for files + // i : Show information about supported formats + // l : List contents of archive + // rn: Rename files in archive + // t : Test integrity of archive + // u : Update files to archive + // x : eXtract files with full paths + // + // + // -- : Stop switches parsing + // -ai[r[-| 0]]{ @listfile | !wildcard} : Include archives + // -ax[r[-| 0]]{ @listfile | !wildcard} : eXclude archives + // -ao{ a | s | t | u} : set Overwrite mode + // -an : disable archive_name field + // -bb[0 - 3] : set output log level + // -bd : disable progress indicator + // -bs{ o | e | p} { 0 | 1 | 2} : set output stream for output / error / progress line + // -bt : show execution time statistics + // -i[r[-| 0]]{ @listfile | !wildcard} : Include filenames + // -m{ Parameters} : set compression Method + // -mmt[N] : set number of CPU threads + // -o{ Directory} : set Output directory + // -p{ Password} : set Password + // -r[-| 0] : Recurse subdirectories + // -sa{ a | e | s} : set Archive name mode + // -scc{ UTF - 8 | WIN | DOS} : set charset for for console input/ output + // -scs{ UTF - 8 | UTF - 16LE | UTF - 16BE | WIN | DOS |{ id} } : set charset for list files + // -scrc[CRC32 | CRC64 | SHA1 | SHA256 | *] : set hash function for x, e, h commands + // -sdel : delete files after compression + // -seml[.] : send archive by email + // -sfx[{ name}] : Create SFX archive + // -si[{ name}] : read data from stdin + // -slp : set Large Pages mode + // -slt : show technical information for l(List) command + // -snh : store hard links as links + // -snl : store symbolic links as links + // -sni : store NT security information + // -sns[-] : store NTFS alternate streams + // -so : write data to stdout + // -spd : disable wildcard matching for file names + // -spe : eliminate duplication of root folder for extract command + // -spf : use fully qualified file paths + // -ssc[-] : set sensitive case mode + // -ssw : compress shared files + // -stl : set archive timestamp from the most recently modified file + // -stm{HexMask} : set CPU thread affinity mask(hexadecimal number) + // -stx{Type} : exclude archive type + // -t{Type} : Set type of archive + // -u[-][p#][q#][r#][x#][y#][z#][!newArchiveName] : Update options + // -v{ Size} [b| k | m | g] : Create volumes + // -w[{ path}] : assign Work directory.Empty path means a temporary directory + // -x[r[-| 0]]{ @listfile | !wildcard} : eXclude filenames + // -y : assume Yes on all queries + + } + } + #endregion class BackupPackageManagerCore + + #region BackupPackageManagerXmlProcessor class + public class BackupPackageManagerXmlProcessor : XmlParser + { + private List _backuppackagelist; + #region constructor + public BackupPackageManagerXmlProcessor(string xmlcs, string basefolder, string lcid) : base(xmlcs, basefolder, lcid, null) + { + _backuppackagelist = new List(); + var bpxmllist = GetAllXElements(nameof(BackupPackage.XmlStructure.BackupPackage)); + if (bpxmllist != null && bpxmllist.Any()) + { + foreach (var bpxml in bpxmllist) { var bp = new BackupPackage(bpxml); if (bp.Valid) { _backuppackagelist.Add(bp); } } + } + } + #endregion constructor + #region GetDefinitionList + public List GetDefinitionList() { return _backuppackagelist; } + #endregion GetDefinitionList + } + #endregion BackupPackageManagerXmlProcessor class + + #region BackupPackage class + public class BackupPackage : XmlLinqBase + { + #region fields + public bool Valid = true; + public string Xml_Key; + public string Xml_PackageName; + public string Xml_Description; + public string Xml_PackageFilePath; + public string Xml_SourceIncludeFilenameMaskList; + public bool Xml_CreateExe; + public List Xml_BackupFolderList; + public List Xml_BackupSQLDataBaseList; + + public long SizePackageTotal; + #endregion fields + + #region basic constructor + public BackupPackage() { } + #endregion basic constructor + + #region xml constructor + public BackupPackage(XElement backupackagexml) + { + Valid = true; + string ATTRIBUTEMANDATORY = nameof(XmlStructure.BackupPackage) + " attribute is mandatory! Name: {0}"; + Xml_Key = GetValue(nameof(XmlStructure.BackupPackage.Attributes.Key), backupackagexml, XmlStructure.BackupPackage.Attributes.Key.Values.DEFAULT); + Xml_PackageName = backupackagexml.Attribute(XName.Get(nameof(XmlStructure.BackupPackage.Attributes.Name)))?.Value; + if (string.IsNullOrWhiteSpace(Xml_PackageName)) { throw new ApplicationException(string.Format(ATTRIBUTEMANDATORY, nameof(XmlStructure.BackupPackage.Attributes.Name))); } + Xml_Description = GetValue(nameof(XmlStructure.BackupPackage.Attributes.Description), backupackagexml, Xml_PackageName); + Xml_PackageFilePath = GetValue(nameof(XmlStructure.BackupPackage.Attributes.PackageFilePath), backupackagexml, ""); + if (string.IsNullOrWhiteSpace(Xml_PackageFilePath)) { throw new ApplicationException(string.Format(ATTRIBUTEMANDATORY, XmlStructure.BackupPackage.Attributes.PackageFilePath.Values.DEFAULT)); } + + Xml_SourceIncludeFilenameMaskList = GetValue(nameof(XmlStructure.BackupPackage.Attributes.IncludeFilenameMaskList), backupackagexml, XmlStructure.BackupPackage.Attributes.IncludeFilenameMaskList.Values.DEFAULT); + + string XmlCreateExestring = GetValue(nameof(XmlStructure.BackupPackage.Attributes.CreateExe), backupackagexml, XmlStructure.BackupPackage.Attributes.CreateExe.Values.DEFAULT.ToString()); + if (string.IsNullOrWhiteSpace(XmlCreateExestring)) { XmlCreateExestring = XmlStructure.BackupPackage.Attributes.CreateExe.Values.DEFAULT.ToString(); } + Xml_CreateExe = bool.Parse(XmlCreateExestring); + + Xml_BackupFolderList = new List(); + //var conditionxmlList = GetAllXElements(foldertocleanxml, nameof(XmlStructure.FolderToClean.Conditions), nameof(XmlStructure.FolderToClean.Conditions.Condition)); + var backupfolderxmlList = backupackagexml.Elements(XName.Get(nameof(XmlStructure.BackupPackage.BackupFolder))); + if (backupfolderxmlList!=null && backupfolderxmlList.Any()) + { + foreach (var backupfolderxml in backupfolderxmlList) { Xml_BackupFolderList.Add(new BackupFolder(backupfolderxml)); } + } + Xml_BackupSQLDataBaseList = new List(); + //var conditionxmlList = GetAllXElements(foldertocleanxml, nameof(XmlStructure.FolderToClean.Conditions), nameof(XmlStructure.FolderToClean.Conditions.Condition)); + var backupsqldbxmlList = backupackagexml.Elements(XName.Get(nameof(XmlStructure.BackupPackage.BackupSQLDataBase))); + if (backupsqldbxmlList != null && backupsqldbxmlList.Any()) + { + foreach (var backupsqldbxml in backupsqldbxmlList) { Xml_BackupSQLDataBaseList.Add(new BackupSQLDataBase(backupsqldbxml)); } + } + } + #endregion xml constructor + + #region cloner constructor + public BackupPackage(BackupPackage bp) + { + Valid = bp.Valid; + Xml_Key = bp.Xml_Key; + Xml_PackageName = bp.Xml_PackageName; + Xml_Description = bp.Xml_Description; + Xml_BackupFolderList = bp.Xml_BackupFolderList.Select(c=>new BackupFolder(c)).ToList(); ; + Xml_PackageFilePath=bp.Xml_PackageFilePath; + Xml_BackupSQLDataBaseList = bp.Xml_BackupSQLDataBaseList.Select(c => new BackupSQLDataBase(c)).ToList(); ; + Xml_SourceIncludeFilenameMaskList = bp.Xml_SourceIncludeFilenameMaskList; + } + #endregion cloner constructor + + #region XmlStructure + public static class XmlStructure + { + public static class BackupPackage + { + public static class Attributes + { + public static class Key { public static class Values { public const string DEFAULT = ""; } } + public static class Name { } + public static class Description { } + public static class CreateExe { public static class Values { public const bool DEFAULT = true; } } + public static class IncludeFilenameMaskList { public static class Values { public const string DEFAULT = "*"; } } + public static class PackageFilePath{ public static class Values { public const string DEFAULT = "BackupPackage_{TIMESTAMP}_{PACKAGENAME}"; } } + } + public static class BackupFolder + { + public static class Attributes + { + public static class Path { public static class Values { public const string DEFAULT = ""; } } + public static class Description { } + public static class BackupToFile { } + public static class IncludeNameMask { public class Values { public const string DEFAULT = "*"; } } + public static class IncludePathRegexp { public class Values { public const string DEFAULT = ".*"; } } + } + } + public static class BackupSQLDataBase + { + public static class Attributes + { + public static class DBBackup { public static class Values { public const bool DEFAULT = true; } } + public static class ScriptBackup { public static class Values { public const bool DEFAULT = true; } } + public static class TableDataBackup { public static class Values { public const bool DEFAULT = true; } } + public static class Key { public static class Values { public const string DEFAULT = ""; } } + } + } + } + } + #endregion XmlStructure + + #region BackupFolder class + public class BackupFolder : XmlLinqBase + { + public BackupFolder(XElement backupfolderxml) + { + Xml_Path = GetValue(nameof(XmlStructure.BackupPackage.BackupFolder.Attributes.Path), backupfolderxml, XmlStructure.BackupPackage.BackupFolder.Attributes.Path.Values.DEFAULT); + Xml_Description = GetValue(nameof(XmlStructure.BackupPackage.BackupFolder.Attributes.Description), backupfolderxml, Xml_Path); + Xml_BackupToFile = GetValue(nameof(XmlStructure.BackupPackage.BackupFolder.Attributes.BackupToFile), backupfolderxml, ""); + Xml_IncludeFileNameMask = GetValue(nameof(XmlStructure.BackupPackage.BackupFolder.Attributes.IncludeNameMask), backupfolderxml, XmlStructure.BackupPackage.BackupFolder.Attributes.IncludeNameMask.Values.DEFAULT); + Xml_IncludeFileFullPathRegex = GetValue(nameof(XmlStructure.BackupPackage.BackupFolder.Attributes.IncludePathRegexp), backupfolderxml, XmlStructure.BackupPackage.BackupFolder.Attributes.IncludePathRegexp.Values.DEFAULT); + } + public BackupFolder(BackupFolder bf) + { + Xml_Path = bf.Xml_Path; + Xml_Description = bf.Xml_Description; + Xml_BackupToFile = bf.Xml_BackupToFile; + FolderExists = bf.FolderExists; + Xml_IncludeFileNameMask = bf.Xml_IncludeFileNameMask; + Xml_IncludeFileFullPathRegex = bf.Xml_IncludeFileFullPathRegex; + } + public string Xml_Path; + public string Xml_Description; + public string Xml_BackupToFile; + public string Xml_IncludeFileNameMask; + public string Xml_IncludeFileFullPathRegex; + public bool FolderExists; + } + #endregion BackupFolder class + #region BackupSQLDataBase class + public class BackupSQLDataBase : XmlLinqBase + { + public BackupSQLDataBase(XElement backupfolderxml) + { + Xml_Key = GetValue(nameof(XmlStructure.BackupPackage.BackupSQLDataBase.Attributes.Key), backupfolderxml, XmlStructure.BackupPackage.BackupSQLDataBase.Attributes.Key.Values.DEFAULT); + Xml_DBBackup = GetValue(nameof(XmlStructure.BackupPackage.BackupSQLDataBase.Attributes.DBBackup), backupfolderxml, XmlStructure.BackupPackage.BackupSQLDataBase.Attributes.DBBackup.Values.DEFAULT); + Xml_ScriptBackup = GetValue(nameof(XmlStructure.BackupPackage.BackupSQLDataBase.Attributes.ScriptBackup), backupfolderxml, XmlStructure.BackupPackage.BackupSQLDataBase.Attributes.ScriptBackup.Values.DEFAULT); + Xml_TableDataBackup = GetValue(nameof(XmlStructure.BackupPackage.BackupSQLDataBase.Attributes.TableDataBackup), backupfolderxml, XmlStructure.BackupPackage.BackupSQLDataBase.Attributes.TableDataBackup.Values.DEFAULT); + } + public BackupSQLDataBase(BackupSQLDataBase bf) + { + Xml_Key = bf.Xml_Key; + Xml_DBBackup = bf.Xml_DBBackup; + Xml_ScriptBackup = bf.Xml_ScriptBackup; + Xml_TableDataBackup = bf.Xml_TableDataBackup; + } + public string Xml_Key; + public bool Xml_DBBackup; + public bool Xml_ScriptBackup; + public bool Xml_TableDataBackup; + } + #endregion BackupSQLDataBase class + + } + #endregion BackupPackage class +} diff --git a/Vrh.Log4Pro.MaintenanceConsole/Manager - FileCleanerManager.cs b/Vrh.Log4Pro.MaintenanceConsole/Manager - FileCleanerManager.cs index d0fa20a..214566f 100644 --- a/Vrh.Log4Pro.MaintenanceConsole/Manager - FileCleanerManager.cs +++ b/Vrh.Log4Pro.MaintenanceConsole/Manager - FileCleanerManager.cs @@ -1,5 +1,6 @@ using System; using System.IO; +using System.IO.Compression; using System.Configuration.Install; using System.Collections.Generic; using System.Linq; @@ -12,97 +13,95 @@ using Microsoft.Web.Administration; using System.Management; using System.Diagnostics; +using Vrh.Log4Pro.MaintenanceConsole.MenuNS; +using Vrh.Log4Pro.MaintenanceConsole.ColorConsoleNS; +using Vrh.Log4Pro.MaintenanceConsole.CommandLineParserNS; + using Vrh.XmlProcessing; +using VRH.Common; using System.Xml.Linq; using System.Text.RegularExpressions; -namespace Vrh.Log4Pro.MaintenanceConsole +namespace Vrh.Log4Pro.MaintenanceConsole.FileCleanerManagerNS { #region FileCleanerManager class public static class FileCleanerManager { + private const string XMLCONNECTIONSTRING = "config=MAINTENANCECONSOLE_FILECLEANERMANAGER;"; + private const string XMLCONNECTIONSTRING_DEFAULT = "file=Config.Xml;element=FileCleaner;"; + #region Execute public static object Execute(object o1 = null, object o2 = null) { - string xmlcs = "file=Config.Xml;element=FileCleaner;"; - var config = new FileCleanerManagerCoreXmlProcessor(xmlcs, "", "hu-HU"); + var args = (o1 as Menu.ExecutorParameter).Args; + var functionkey = CommandLine.GetCommandLineArgument(args, CLP.CMD_FUNCTION); + var config = new FileCleanerManagerXmlProcessor(XMLCONNECTIONSTRING, "", "hu-HU"); + var ep = new Menu.ExecutorParameter(config, args); var menufunctions = new Menu("Manage Folders To Clean", "Select the management function!") - .AddMenuItem(new Menu.Item("CLN", "Clean folder", CleanFolder)) - .SetSelectionMode(Menu.SelectionMode.Single); - - while (true) - { - Menu.Selection sr; - - menufunctions.DisplayTitle(); - var menuservices = DisplayFolders(config); - menufunctions.DisplayItems(); - sr = menufunctions.Select(); - if (sr.Result == Menu.SelectionResult.Exit) { break; } - else if (sr.Result == Menu.SelectionResult.None) { continue; } - else if (sr.Result == Menu.SelectionResult.Error) { continue; } - menufunctions.SetExecutorParameters(sr,config); - menufunctions.ExecuteSelection(sr.SelectedKeyList); - } - return null; + .AddMenuItem(new Menu.Item(CLP.Module.FileCleanerManager.Functions.FolderClean.KEY, "Clean folder", FolderClean, ep)) + .SetSelectionMode(Menu.SelectionMode.Single) + .SetMenuHeaderDisplayer(FolderToCleanListDisplayer); + menufunctions.ExecuteMenu(functionkey); + return o2; } #endregion Execute #region First level Executors with UI - private static object CleanFolder(object parameter, object o) + private static object FolderClean(object parameter, object o) { - var config = parameter as FileCleanerManagerCoreXmlProcessor; + var config = (parameter as Menu.ExecutorParameter).GetConfig(); + var args = (parameter as Menu.ExecutorParameter).Args; - var menufolders = DisplayFolders(config, $"Select the folder(s) to manage with function '{nameof(CleanFolder)}'!", silent: true); + var selectedftcindexes = CommandLine.GetCommandLineArgument(args, CLP.Module.FileCleanerManager.Functions.CMD_FOLDERS); - Menu.Selection sr = menufolders.Select(); + var menufolders = DisplayFolderMenu(config, $"Select the folder(s) to manage with function '{nameof(FolderClean)}'!", silent: true); + + Menu.Selection sr = menufolders.Select(selectedftcindexes); if (sr.Result == Menu.SelectionResult.Exit) { return o; } else if (sr.Result == Menu.SelectionResult.None) { return o; } else if (sr.Result == Menu.SelectionResult.Error) { return o; } else if (sr.Result == Menu.SelectionResult.Ok) { } else { } - foreach (var p in sr.SelectedParameterList) + foreach (var p in sr.SelectedParameterList) { OneFolderClean(p.Parameters as FolderToClean); } + return o; + } + private static void OneFolderClean(FolderToClean ftc) + { + try { - FolderToClean ftc = p as FolderToClean; - try - { - var di = new DirectoryInfo(ftc.Xml_DirectoryPath); - var success = FileCleanerManagerCore.CleanFolderFiles(di,ftc, delete: true); - ColorConsole.WriteLine($"Folder cleaned. Name:{ftc.Xml_DirectoryPath}", ConsoleColor.Green); - } - catch (Exception ex) - { - ColorConsole.WriteLine(ex.Message, ConsoleColor.Red); - } + var di = new DirectoryInfo(ftc.Xml_DirectoryPath); + var success = FileCleanerManagerCore.CleanFolderFiles(di, ftc, delete: true); + ColorConsole.WriteLine($"Folder cleaned. Name:{ftc.Xml_DirectoryPath}", ConsoleColor.Green); } - return o; + catch (Exception ex) { ColorConsole.WriteLine(ex.Message, ConsoleColor.Red); } } #endregion First level Executors with UI #region private methods - #region private DisplayFolders - private static Menu DisplayFolders(FileCleanerManagerCoreXmlProcessor config,string prompt = null,bool silent=false) + #region private DisplayFolderMenu + private static void FolderToCleanListDisplayer() { DisplayFolderMenu(); } + private static Menu DisplayFolderMenu(FileCleanerManagerXmlProcessor config=null,string prompt = null,bool silent=false) { + if (config==null) { config = new FileCleanerManagerXmlProcessor(XMLCONNECTIONSTRING, "", "hu-HU"); } List fctdefList = config.GetDefinitionList(); var menufct = new Menu("Folder to clean",prompt) .SetMenuItemDisplayer(DisplayFolderInfo) - .SetSelectionMode(Menu.SelectionMode.Multi) - .SetHeaderWidth(4); + .SetSelectionMode(Menu.SelectionMode.Multi); menufct.ClearMenuItemList(); foreach (var fctdef in fctdefList) { var fi = CollectFolderInfo(fctdef); - menufct.AddMenuItem(new Menu.Item(null, null, null, fi)); + menufct.AddMenuItem(new Menu.Item(fctdef.Xml_Key, null, null, new Menu.ExecutorParameter(pars:fi))); } if (!silent) { menufct.DisplayItems(1); } return menufct; } - #endregion private DisplayFolders + #endregion private DisplayFolderMenu #region private method: DisplayFolderInfo private static object DisplayFolderInfo(object obj, int lineix) { - FolderToClean ws = obj as FolderToClean; + FolderToClean ws = (obj as Menu.ExecutorParameter).Parameters as FolderToClean; if (lineix == 0) { ColorConsole.Write($"{ws.Xml_DirectoryPath}", ConsoleColor.Black, ConsoleColor.White); @@ -214,7 +213,8 @@ namespace Vrh.Log4Pro.MaintenanceConsole bool conditionresult = false; if (c.Type == FolderToClean.ConditionType.TimeStampInName) { - var fileTSstr = VRH.Common.StringConstructor.ResolveConstructor(groupnamevalues, c.TimestampConstructor, "{}"); + var fileTSstr = VRH.Common.StringConstructor.ResolveConstructor(groupnamevalues, c.TimestampConstructor, "{}@@"); + try { var fileTS = DateTime.Parse(fileTSstr); conditionresult = DateTime.Now.Subtract(fileTS).TotalDays > c.Limit; } catch { @@ -288,12 +288,12 @@ namespace Vrh.Log4Pro.MaintenanceConsole #endregion class FileCleanerManagerCore #region FileCleanerManagerCoreXmlProcessor class - public class FileCleanerManagerCoreXmlProcessor : XmlParser + public class FileCleanerManagerXmlProcessor : XmlParser { private List _foldertocleanlist; private int commoncleanupdays; #region constructor - public FileCleanerManagerCoreXmlProcessor(string xmlcs, string basefolder, string lcid) : base(xmlcs, basefolder, lcid, null) + public FileCleanerManagerXmlProcessor(string xmlcs, string basefolder, string lcid) : base(xmlcs, basefolder, lcid, null) { _foldertocleanlist = new List(); commoncleanupdays = GetValue(nameof(FolderToClean.XmlStructure.Attributes.CleanupDays),this.RootElement, FolderToClean.XmlStructure.Attributes.CleanupDays.Values.DEFAULT); @@ -315,6 +315,7 @@ namespace Vrh.Log4Pro.MaintenanceConsole { #region fields public bool Valid = true; + public string Xml_Key; public string Xml_DirectoryPath; public bool Xml_Recurse; public bool Xml_RemoveEmptyFolder; @@ -339,6 +340,7 @@ namespace Vrh.Log4Pro.MaintenanceConsole { Valid = true; string ATTRIBUTEMANDATORY = nameof(XmlStructure.FolderToClean) + " attribute is mandatory! Name: {0}"; + Xml_Key = GetValue(nameof(XmlStructure.FolderToClean.Attributes.Key), foldertocleanxml, XmlStructure.FolderToClean.Attributes.Key.Values.DEFAULT); Xml_DirectoryPath = foldertocleanxml.Attribute(XName.Get(nameof(XmlStructure.FolderToClean.Attributes.Directory)))?.Value; if (string.IsNullOrWhiteSpace(Xml_DirectoryPath)) { throw new ApplicationException(string.Format(ATTRIBUTEMANDATORY, nameof(XmlStructure.FolderToClean.Attributes.Directory))); } Xml_Recurse = GetValue(nameof(XmlStructure.FolderToClean.Attributes.Recurse), foldertocleanxml, XmlStructure.FolderToClean.Attributes.Recurse.Values.DEFAULT); @@ -361,6 +363,7 @@ namespace Vrh.Log4Pro.MaintenanceConsole public FolderToClean(FolderToClean ftc) { Valid = ftc.Valid; + Xml_Key= ftc.Xml_Key; Xml_DirectoryPath = ftc.Xml_DirectoryPath; Xml_Recurse = ftc.Xml_Recurse; Xml_RemoveEmptyFolder = ftc.Xml_RemoveEmptyFolder; @@ -414,6 +417,7 @@ namespace Vrh.Log4Pro.MaintenanceConsole { public static class Attributes { + public static class Key { public static class Values { public const string DEFAULT = ""; } } public static class Directory { } public static class CleanupDays { diff --git a/Vrh.Log4Pro.MaintenanceConsole/Manager - MaintenanceToolManager.cs b/Vrh.Log4Pro.MaintenanceConsole/Manager - MaintenanceToolManager.cs index ddd96c0..02de6c4 100644 --- a/Vrh.Log4Pro.MaintenanceConsole/Manager - MaintenanceToolManager.cs +++ b/Vrh.Log4Pro.MaintenanceConsole/Manager - MaintenanceToolManager.cs @@ -12,40 +12,35 @@ using Microsoft.Web.Administration; using System.Management; using System.Diagnostics; +using Vrh.Log4Pro.MaintenanceConsole.MenuNS; +using Vrh.Log4Pro.MaintenanceConsole.ColorConsoleNS; +using Vrh.Log4Pro.MaintenanceConsole.CommandLineParserNS; + using Vrh.XmlProcessing; using System.Xml.Linq; using System.Text.RegularExpressions; -namespace Vrh.Log4Pro.MaintenanceConsole +namespace Vrh.Log4Pro.MaintenanceConsole.MaintenanceToolManagerNS { #region MaintenanceTools class public static class MaintenanceToolManager { + private const string XMLCONNECTIONSTRING = "config=MAINTENANCECONSOLE_MAINTENANCETOOLMANAGER;"; + private const string XMLCONNECTIONSTRING_DEFAULT = "file=Config.Xml;element=MaintenanceTools;"; + #region Execute public static object Execute(object o1 = null, object o2 = null) { - string xmlcs = "file=Config.Xml;element=WindowsServices;"; + var args = (o1 as Menu.ExecutorParameter).Args; + string xmlcs = XMLCONNECTIONSTRING; var config = new MaintenanceToolsXmlProcessor(xmlcs, "", "hu-HU"); var menufunctions = new Menu("Maintenance Tools", "Select function!") - .AddMenuItem(new Menu.Item("RGX", "Regex tester", RegexTester)) - .AddMenuItem(new Menu.Item("TL1", "Tool #1", Tool1)) - .AddMenuItem(new Menu.Item("TL2", "Tool #2", Tool2)) + .AddMenuItem(new Menu.Item(CLP.Module.MaintenanceToolManager.Functions.RegexTester.KEY, "Regex tester", RegexTester,new Menu.ExecutorParameter(cfg:config))) + .AddMenuItem(new Menu.Item(CLP.Module.MaintenanceToolManager.Functions.Tool1.KEY, "Tool #1", Tool1, new Menu.ExecutorParameter(cfg: config, null))) + .AddMenuItem(new Menu.Item(CLP.Module.MaintenanceToolManager.Functions.Tool2.KEY, "Tool #2", Tool2, new Menu.ExecutorParameter(cfg: config, null))) .SetSelectionMode(Menu.SelectionMode.Single); - - while (true) - { - Menu.Selection sr; - - menufunctions.DisplayTitle(); - menufunctions.DisplayItems(); - sr = menufunctions.Select(); - if (sr.Result == Menu.SelectionResult.Exit) { break; } - else if (sr.Result == Menu.SelectionResult.None) { continue; } - else if (sr.Result == Menu.SelectionResult.Error) { continue; } - menufunctions.SetExecutorParameters(sr,config); - menufunctions.ExecuteSelection(sr.SelectedKeyList); - } + menufunctions.ExecuteMenu(); return null; } #endregion Execute @@ -54,7 +49,7 @@ namespace Vrh.Log4Pro.MaintenanceConsole #region RegexTester private static object RegexTester(object parameter, object o) { - var config = parameter as MaintenanceToolsXmlProcessor; + var config = (parameter as Menu.ExecutorParameter).GetConfig(); var regexptesterconfig = config.RegexpTesterConfig; while(true) { diff --git a/Vrh.Log4Pro.MaintenanceConsole/Manager - SQLDataBaseManager.cs b/Vrh.Log4Pro.MaintenanceConsole/Manager - SQLDataBaseManager.cs new file mode 100644 index 0000000..1734874 --- /dev/null +++ b/Vrh.Log4Pro.MaintenanceConsole/Manager - SQLDataBaseManager.cs @@ -0,0 +1,1113 @@ +using System; +using System.IO; +using System.IO.Compression; +using System.Configuration.Install; +using System.Collections.Generic; +using System.Linq; +using System.ServiceProcess; +using System.Text; +using System.Threading; +using System.Threading.Tasks; + +using Microsoft.Web.Administration; +using System.Management; +using System.Diagnostics; + +using Vrh.Log4Pro.MaintenanceConsole.MenuNS; +using Vrh.Log4Pro.MaintenanceConsole.ColorConsoleNS; +using Vrh.Log4Pro.MaintenanceConsole.ToolsNS; +using Vrh.Log4Pro.MaintenanceConsole.CommandLineParserNS; + +using Vrh.XmlProcessing; +using VRH.Common; +using System.Xml.Linq; +using System.Text.RegularExpressions; + +using Microsoft.SqlServer.Management.Common; +using Microsoft.SqlServer.Management.Smo; + +namespace Vrh.Log4Pro.MaintenanceConsole.SQLDataBaseManagerNS +{ + #region SQLDataBaseManager class + public static class SQLDataBaseManager + { + private const string XMLCONNECTIONSTRING = "config=MAINTENANCECONSOLE_SQLDATABASEMANAGER;"; + private const string XMLCONNECTIONSTRING_DEFAULT = "file=Config.Xml;element=SQLDataBases;"; + + #region Execute + public static object Execute(object o1 = null, object o2 = null) + { + var args = (o1 as Menu.ExecutorParameter).Args; + var functionkey = CommandLine.GetCommandLineArgument(args, CLP.CMD_FUNCTION); + + var config = new SQLDataBaseManagerXmlProcessor(XMLCONNECTIONSTRING, "", "hu-HU"); + var ep = new Menu.ExecutorParameter(config, args); + var menufunctions = new Menu("Manage Scheduled tasks", "Select the management function!") + .AddMenuItem(new Menu.Item(CLP.Module.SQLDataBaseManager.Function.BackupDataBase.KEY, "Backup database", BackupDataBase, ep)) + .AddMenuItem(new Menu.Item(CLP.Module.SQLDataBaseManager.Function.CreateCodeScripts.KEY, "Create code scripts", CreateCodeScripts, ep)) + .AddMenuItem(new Menu.Item(CLP.Module.SQLDataBaseManager.Function.CreateDataScripts.KEY, "Create data scripts", CreateDataScripts, ep)) + .AddMenuItem(new Menu.Item(CLP.Module.SQLDataBaseManager.Function.RestoreDataBase.KEY, "Restore database backup", RestoreDataBase, ep)) + .AddMenuItem(new Menu.Item(CLP.Module.SQLDataBaseManager.Function.RelocatePhysicalFiles.KEY, "Copy database and or relocate its physical files", RelocatePhysicalFiles, ep)) + .SetSelectionMode(Menu.SelectionMode.Single) + .SetMenuHeaderDisplayer(DataBaseListDisplayer); + menufunctions.ExecuteMenu(functionkey); + return o2; + } + public static void Execute(string key, bool enabledbbackup, bool enablescriptbackup, bool enabletabledatabackup, string targetfolder=null,DateTime? timestamp = null) + { + var packagets = (timestamp.HasValue ? timestamp.Value : DateTime.Now).ToString("yyyyMMddHHmmss"); + var config = new SQLDataBaseManagerXmlProcessor(XMLCONNECTIONSTRING, "", "hu-HU"); + var origsqld = config.GetDefinitionList().FirstOrDefault(x => x.Xml_Key == key); + if (origsqld != null) + { + var sqld = new SQLDataBase(origsqld); + if (!string.IsNullOrWhiteSpace(targetfolder)) { sqld.Xml_BackupTargetDirectoryPath = targetfolder; } + if (enabledbbackup) { SQLDataBaseManagerCore.CreateBackup(sqld.Xml_BackupTargetDirectoryPath, sqld.SQLCS, sqld.Xml_BackupFileNameMask, sqld.Xml_CreateZip, timestamp); } + if (enablescriptbackup) { SQLDataBaseManagerCore.BackupSqlScripts(sqld.Xml_BackupTargetDirectoryPath, sqld.Xml_BackupFileNameMask, sqld.SQLCS, sqld.Xml_CreateZip, timestamp); } + if (enabletabledatabackup) { SQLDataBaseManagerCore.BackupSqlData(sqld, timestamp); } + } + } + #endregion Execute + + #region First level Executors with UI + private static object CreateDataScripts(object parameter, object o) + { + var config = (parameter as Menu.ExecutorParameter).GetConfig(); + var args = (parameter as Menu.ExecutorParameter).Args; + + var selectedsqldbindexes = CommandLine.GetCommandLineArgument(args, CLP.Module.SQLDataBaseManager.Function.CMD_DATABASES); + + var menufolders = DisplaySQLDataBaseMenu(config, $"Select the scheduled task(s) to manage with function '{nameof(CreateDataScripts)}'!", silent: true); + + Menu.Selection sr = menufolders.Select(selectedsqldbindexes); + if (sr.Result == Menu.SelectionResult.Exit) { return o; } + else if (sr.Result == Menu.SelectionResult.None) { return o; } + else if (sr.Result == Menu.SelectionResult.Error) { return o; } + else if (sr.Result == Menu.SelectionResult.Ok) { } + else { } + + DateTime TS = DateTime.Now; + foreach (var p in sr.SelectedParameterList) + { + SQLDataBase sqld = p.Parameters as SQLDataBase; + try + { + SQLDataBaseManagerCore.BackupSqlData(sqld,TS); + ColorConsole.WriteLine($"SQLDB data scripts created. Name:{sqld.Xml_Description}", ConsoleColor.Green); + } + catch (Exception ex) + { + ColorConsole.WriteLine(ex.Message, ConsoleColor.Red); + } + } + return o; + } + private static object CreateCodeScripts(object parameter, object o) + { + var config = (parameter as Menu.ExecutorParameter).GetConfig(); + var args = (parameter as Menu.ExecutorParameter).Args; + + var selectedsqldbindexes = CommandLine.GetCommandLineArgument(args, CLP.Module.SQLDataBaseManager.Function.CMD_DATABASES); + + var menufolders = DisplaySQLDataBaseMenu(config, $"Select the scheduled task(s) to manage with function '{nameof(CreateCodeScripts)}'!", silent: true); + + Menu.Selection sr = menufolders.Select(selectedsqldbindexes); + if (sr.Result == Menu.SelectionResult.Exit) { return o; } + else if (sr.Result == Menu.SelectionResult.None) { return o; } + else if (sr.Result == Menu.SelectionResult.Error) { return o; } + else if (sr.Result == Menu.SelectionResult.Ok) { } + else { } + + DateTime TS = DateTime.Now; + foreach (var p in sr.SelectedParameterList) + { + SQLDataBase sqld = p.Parameters as SQLDataBase; + try + { + + SQLDataBaseManagerCore.BackupSqlScripts(sqld.Xml_BackupTargetDirectoryPath, sqld.Xml_BackupFileNameMask,sqld.SQLCS,sqld.Xml_CreateZip,TS); + ColorConsole.WriteLine($"SQLDB code scripts created. Name:{sqld.Xml_Description}", ConsoleColor.Green); + } + catch (Exception ex) { ColorConsole.WriteLine(ex.Message, ConsoleColor.Red); } + } + return o; + } + private static object BackupDataBase(object parameter, object o) + { + var config = (parameter as Menu.ExecutorParameter).GetConfig(); + var args = (parameter as Menu.ExecutorParameter).Args; + + var selectedsqldbindexes = CommandLine.GetCommandLineArgument(args, CLP.Module.SQLDataBaseManager.Function.CMD_DATABASES); + + var menufolders = DisplaySQLDataBaseMenu(config, $"Select the scheduled task(s) to manage with function '{nameof(BackupDataBase)}'!", silent: true); + + Menu.Selection sr = menufolders.Select(selectedsqldbindexes); + if (sr.Result == Menu.SelectionResult.Exit) { return o; } + else if (sr.Result == Menu.SelectionResult.None) { return o; } + else if (sr.Result == Menu.SelectionResult.Error) { return o; } + else if (sr.Result == Menu.SelectionResult.Ok) { } + else { } + + var TS = DateTime.Now; + foreach (var p in sr.SelectedParameterList) + { + SQLDataBase ssqldb = p.Parameters as SQLDataBase; + try + { + SQLDataBaseManagerCore.CreateBackup(ssqldb.Xml_BackupTargetDirectoryPath, ssqldb.SQLCS, ssqldb.Xml_BackupFileNameMask, ssqldb.Xml_CreateZip,TS); + ColorConsole.WriteLine($"Database backup created. Name:{ssqldb.DBName}", ConsoleColor.Green); + } + catch (Exception ex) { ColorConsole.WriteLine(ex.Message, ConsoleColor.Red); } + } + return o; + } + private static object RestoreDataBase(object parameter, object o) + { + var config = (parameter as Menu.ExecutorParameter).GetConfig(); + var args = (parameter as Menu.ExecutorParameter).Args; + + var selectedsqldbindexes = CommandLine.GetCommandLineArgument(args, CLP.Module.SQLDataBaseManager.Function.CMD_DATABASES); + bool restorefirst = CommandLine.GetCommandLineArgument(args, CLP.Module.SQLDataBaseManager.Function.RestoreDataBase.CMD_RESTOREFIRST,switchtype:true)!=null; + + var menufolders = DisplaySQLDataBaseMenu(config, $"Select the sql database(s) to manage with function '{nameof(RestoreDataBase)}'!", silent: true); + + Menu.Selection sr = menufolders.Select(selectedsqldbindexes); + if (sr.Result == Menu.SelectionResult.Exit) { return o; } + else if (sr.Result == Menu.SelectionResult.None) { return o; } + else if (sr.Result == Menu.SelectionResult.Error) { return o; } + else if (sr.Result == Menu.SelectionResult.Ok) { } + else { } + foreach (var p in sr.SelectedParameterList) + { + SQLDataBase st = p.Parameters as SQLDataBase; + try + { + var targetdirectorypath = st.Xml_PhysicalFilesDirectoryPath; + var targetdbname= st.DBName; + bool restorefromzip = st.Xml_CreateZip; + var backupfilelist = SQLDataBaseManagerCore.GetBackupFilePathList(st); + if (backupfilelist != null && backupfilelist.Any()) + { + string selectedbackupfilepath; + if (restorefirst) + { + selectedbackupfilepath = backupfilelist.First().FullName; + } + else + { + var selectionlist = backupfilelist + .Select(x => new KeyValuePair($"{x.Name}({x.Length}bytes,created:{x.CreationTime})", x.FullName)) + .ToDictionary(x=>x.Key,x=>x.Value); + var ms = Menu.SelectFromItemList($"Backup files of {st.DBName}", "Select the backup file to restore! First is the newest!", selectionlist,Menu.SelectionMode.Single,getconfirmation:true); + if (ms == null) { continue; } + selectedbackupfilepath = ms.SelectedParameterList.First().Parameters.ToString(); + } + SQLDataBaseManagerCore.RestoreBackup(st.SQLCS, selectedbackupfilepath, targetdirectorypath, restorefromzip, targetdbname); + ColorConsole.WriteLine($"Database '{st.DBName}' restored to '{targetdbname}' into directory '{targetdirectorypath}'.", ConsoleColor.Green); + } + else + { + ColorConsole.WriteLine($"Database '{st.DBName}' restore FAILED, as no backup to restore!", ConsoleColor.Red); + } + } + catch (Exception ex) { ColorConsole.WriteLine(ex.Message, ConsoleColor.Red); } + } + return o; + } + private static object RelocatePhysicalFiles(object parameter, object o) + { + var config = (parameter as Menu.ExecutorParameter).GetConfig(); + var args = (parameter as Menu.ExecutorParameter).Args; + + var selectedtaskindexes = CommandLine.GetCommandLineArgument(args, CLP.Module.ScheduledTaskManager.Function.CMD_TASKS); + + var menufolders = DisplaySQLDataBaseMenu(config, $"Select the sql database(s) to manage with function '{nameof(RelocatePhysicalFiles)}'!", silent: true); + + Menu.Selection sr = menufolders.Select(selectedtaskindexes); + if (sr.Result == Menu.SelectionResult.Exit) { return o; } + else if (sr.Result == Menu.SelectionResult.None) { return o; } + else if (sr.Result == Menu.SelectionResult.Error) { return o; } + else if (sr.Result == Menu.SelectionResult.Ok) { } + else { } + foreach (var p in sr.SelectedParameterList) + { + SQLDataBase sqld = p.Parameters as SQLDataBase; + try + { + var restoredbname = ColorConsole.ReadLine($"Enter the name of the DB to copy '{sqld.DBName}' to. Empty={sqld.DBName}. EX=exit.", ConsoleColor.Yellow, suffix: " --> "); + if (restoredbname == "EX") { continue; } + else if (string.IsNullOrWhiteSpace(restoredbname)) { restoredbname = sqld.DBName; } + ColorConsole.WriteLine("Enter the path for the DB physical files.", ConsoleColor.Yellow); + ColorConsole.WriteLine(sqld.PhysicalFilesDirectoryPath, ConsoleColor.Yellow, prefix: $" Empty=current location of source DB: ", bracket: "[]"); + ColorConsole.WriteLine(SQLDataBaseManagerCore.GetServerDefaultPhysicalDATFileLocation(sqld.SQLCS), ConsoleColor.Yellow,prefix: $" DEFAULT= sql server default location.",bracket:"[]"); + var targetdirectory = ColorConsole.ReadLine($"Enter the target path.EX=exit.", ConsoleColor.Yellow, suffix: " --> "); + if (targetdirectory == "EX") { continue; } + else if (targetdirectory == "DEFAULT") { targetdirectory = null; ; } + else if (string.IsNullOrWhiteSpace(targetdirectory)) { targetdirectory = sqld.PhysicalFilesDirectoryPath; } + + if (restoredbname == sqld.DBName && targetdirectory == sqld.PhysicalFilesDirectoryPath) { continue; } + + SQLDataBaseManagerCore.RelocatePhysicalFiles(sqld, targetdirectory, restoredbname); + ColorConsole.WriteLine($"Database physical files relocated. Name:{sqld.DBName}", ConsoleColor.Green); + } + catch (Exception ex) { ColorConsole.WriteLine(ex.Message, ConsoleColor.Red); } + } + return o; + } + #endregion First level Executors with UI + + #region private methods + #region private DisplaySQLDataBaseMenu + private static void DataBaseListDisplayer() { DisplaySQLDataBaseMenu(); } + private static Menu DisplaySQLDataBaseMenu(SQLDataBaseManagerXmlProcessor config = null, string prompt = null, bool silent = false) + { + if (config == null) { config = new SQLDataBaseManagerXmlProcessor(XMLCONNECTIONSTRING, "", "hu-HU"); } + List schtskdefList = config.GetDefinitionList(); + var menufct = new Menu("SQL Databases", prompt) + .SetMenuItemDisplayer(DisplayDataBaseInfo) + .SetSelectionMode(Menu.SelectionMode.Multi); + menufct.ClearMenuItemList(); + foreach (var schtskdef in schtskdefList) + { + var st = SQLDataBaseManagerCore.CollectDataBaseInfo(schtskdef); + menufct.AddMenuItem(new Menu.Item(schtskdef.Xml_Key, null, null, new Menu.ExecutorParameter(pars: st))); + } + if (!silent) { menufct.DisplayItems(1); } + return menufct; + } + #endregion private DisplaySQLDataBaseMenu + #region private method: DisplayDataBaseInfo + private static object DisplayDataBaseInfo(object obj, int lineix) + { + SQLDataBase st = (obj as Menu.ExecutorParameter).Parameters as SQLDataBase; + if (lineix == 0) + { + ColorConsole.Write($"{st.Xml_Description}", ConsoleColor.Black, ConsoleColor.White); + var statuscolor = st.Status == SQLDataBaseManagerCore.SQLDBStatus.NoAccess ? ConsoleColor.Red:ConsoleColor.Green; + ColorConsole.Write(st.Status.ToString(), statuscolor, bracket: "[]", prefix: " ", suffix: ". "); + if (st.Status != SQLDataBaseManagerCore.SQLDBStatus.NoAccess) + { + ColorConsole.Write(st.DBName, statuscolor, bracket: "[]", prefix: "Database ", suffix: ". "); + ColorConsole.Write(st.DataSource, statuscolor, bracket: "[]", prefix: "from server ", suffix: ". "); + } + ColorConsole.WriteLine(); + return " "; + } + else if (lineix == 1) + { + ColorConsole.Write($"{st.Xml_BackupFileNameMask}", ConsoleColor.Yellow, prefix: "Backup to:", suffix: ".xxx"); + ColorConsole.WriteLine(); + return ""; + } + else if (lineix == 2) + { + ColorConsole.Write($"{st.SQLCS}", ConsoleColor.Yellow, prefix: "SQL DB connection:", suffix: ", "); + ColorConsole.WriteLine(" "); + return " "; + } + else if (lineix == 3) + { + var phypath = SQLDataBaseManagerCore.GetPhysicalFilesLocation(st.SQLCS); + ColorConsole.Write($"{phypath}", ConsoleColor.Yellow, prefix: "DB files physical location:", suffix: " "); + ColorConsole.WriteLine(" "); + return " "; + } + return null; + } + #endregion private method: DisplayDataBaseInfo + #endregion private methods + } + #endregion SQLDataBaseManager class + + #region class SQLDataBaseManager + public static class SQLDataBaseManagerCore + { + #region public CollectDataBaseInfo + public static SQLDataBase CollectDataBaseInfo(SQLDataBase sqld) + { + sqld.Status = GetStatus(sqld.SQLCS); + sqld.PhysicalFilesDirectoryPath = GetPhysicalFilesLocation(sqld.SQLCS); + sqld.DBName = GetDBName(sqld.SQLCS); + sqld.DataSource = GetDataSource(sqld.SQLCS); + return sqld; + } + #endregion public CollectDataBaseInfo + + public static void RelocatePhysicalFiles(SQLDataBase sqld, string targetdirectory, string restoredbname) + { + var dbbackupfilepath = CreateBackup(sqld.Xml_BackupTargetDirectoryPath, sqld.SQLCS, sqld.Xml_BackupFileNameMask, false); + RestoreBackup(sqld.SQLCS, dbbackupfilepath, targetdirectory, false, restoredbname); + if (File.Exists(dbbackupfilepath)) { File.Delete(dbbackupfilepath); } + } + public static void RestoreBackup(string sqlcs, string sourcesqlbackupfilepath, string targetdbphysicalfilesdirectorypath, bool restorefromZIP = false, string restoretodbname = null) + { + string backupfilepath; + if (restorefromZIP) + { + backupfilepath = Path.Combine(Path.GetDirectoryName(sourcesqlbackupfilepath), Path.GetFileNameWithoutExtension(sourcesqlbackupfilepath) + ".bak"); + ZipTools.Extract1stFileFromZIP(backupfilepath, sourcesqlbackupfilepath); + var starttime = DateTime.Now; + while (DateTime.Now.Subtract(starttime).TotalSeconds > 5) { if (File.Exists(backupfilepath)) { break; } Thread.Sleep(500); } + } + else { backupfilepath = sourcesqlbackupfilepath; } + var sqlserver = SQLServerConnect(sqlcs); + + var smoRestore = new Restore(); + smoRestore.NoRecovery = false; + smoRestore.ReplaceDatabase = true; + smoRestore.Action = RestoreActionType.Database; + smoRestore.PercentCompleteNotification = 5; + var backupdevice = new BackupDeviceItem(backupfilepath, DeviceType.File); + smoRestore.Devices.Add(backupdevice); + smoRestore.Database = string.IsNullOrWhiteSpace(restoretodbname) + ? smoRestore.ReadBackupHeader(sqlserver).Rows[0]["DatabaseName"].ToString() + : restoretodbname; + + var dbfilelist = smoRestore.ReadFileList(sqlserver); + var smorestoreDATfile = new RelocateFile(); + string targetdbphysicalfilesdirectorypathDAT = targetdbphysicalfilesdirectorypath; + if (string.IsNullOrEmpty(targetdbphysicalfilesdirectorypathDAT)) { targetdbphysicalfilesdirectorypathDAT = sqlserver.DefaultFile; } + if (string.IsNullOrEmpty(targetdbphysicalfilesdirectorypathDAT)) { targetdbphysicalfilesdirectorypathDAT = sqlserver.MasterDBPath; } + smorestoreDATfile.PhysicalFileName = Path.Combine(targetdbphysicalfilesdirectorypathDAT, smoRestore.Database + "_Data.mdf"); + smorestoreDATfile.LogicalFileName = dbfilelist.Select("Type='D'")[0]["LogicalName"].ToString(); + smoRestore.RelocateFiles.Add(smorestoreDATfile); + + var smorestoreLOGfile = new RelocateFile(); + string targetdbphysicalfilesdirectorypathLOG = targetdbphysicalfilesdirectorypath; + if (string.IsNullOrEmpty(targetdbphysicalfilesdirectorypathLOG)) { targetdbphysicalfilesdirectorypathLOG = sqlserver.DefaultLog; } + if (string.IsNullOrEmpty(targetdbphysicalfilesdirectorypathLOG)) { targetdbphysicalfilesdirectorypathLOG = sqlserver.MasterDBLogPath; } + smorestoreLOGfile.PhysicalFileName = Path.Combine(targetdbphysicalfilesdirectorypathLOG, smoRestore.Database + "_Log.ldf"); + smorestoreLOGfile.LogicalFileName = dbfilelist.Select("Type='L'")[0]["LogicalName"].ToString(); + smoRestore.RelocateFiles.Add(smorestoreLOGfile); + + sqlserver.KillAllProcesses(smoRestore.Database); + + smoRestore.SqlRestore(sqlserver); + if (restorefromZIP) + { + if (File.Exists(backupfilepath)) { File.Delete(backupfilepath); } + } + } + public static string CreateBackup(string backupdirectorypath, string sqlconnectionstring, string backupfilenamemask, bool createzip = false,DateTime? timestamp=null) + { + var sqlserver = SQLServerConnect(sqlconnectionstring); + + var backupts = (timestamp.HasValue ? timestamp.Value : DateTime.Now).ToString("yyyyMMddHHmmss"); + + string backupfileNameOnly = Path.GetFileNameWithoutExtension(backupfilenamemask); + var vars = new Dictionary(); + vars.Add(nameof(DBSubstitutionName.DATABASE), GetDBName(sqlconnectionstring)); + vars.Add(nameof(DBSubstitutionName.DATASOURCE), GetDataSource(sqlconnectionstring)); + vars.Add(nameof(DBSubstitutionName.DBOTYPE), "DBBACKUP"); + vars.Add(nameof(DBSubstitutionName.DBONAME), ""); + vars.Add(nameof(DBSubstitutionName.DBDATAGROUP), ""); + vars.Add(nameof(DBSubstitutionName.BACKUPTS), backupts); + + backupfileNameOnly = VRH.Common.StringConstructor.ResolveConstructor(vars, backupfileNameOnly, "{}@@"); + + string backupfilename = backupfileNameOnly + ".bak"; + string backupFullName = Path.Combine(backupdirectorypath, backupfileNameOnly); + if (File.Exists(backupFullName)) { File.Delete(backupFullName); } + + var smoBackup = new Backup(); + smoBackup.Action = BackupActionType.Database; + smoBackup.BackupSetDescription = $"Full Backup of {sqlserver.ConnectionContext.DatabaseName}"; + smoBackup.BackupSetName = sqlserver.ConnectionContext.DatabaseName + " Backup"; + smoBackup.Database = sqlserver.ConnectionContext.DatabaseName; + smoBackup.MediaDescription = "Disk"; + smoBackup.Devices.AddDevice(backupFullName, DeviceType.File); + smoBackup.SqlBackup(sqlserver); + + if (createzip) + { + string ZIPbackupfilename = backupfileNameOnly + ".zip"; + string ZIPbackupFullName = Path.Combine(backupdirectorypath, ZIPbackupfilename); + if (File.Exists(ZIPbackupFullName)) { File.Delete(ZIPbackupFullName); } + + ZipTools.CreateEntriesFromDirectoryContent(backupdirectorypath, ZIPbackupFullName, backupfilename, "", removearchivedfiles: false, storepathinzip: false); + if (File.Exists(backupFullName)) { File.Delete(backupFullName); } + return ZIPbackupFullName; + + } + return backupFullName; + } + + #region private methods + public static List GetBackupFilePathList(SQLDataBase sqld) + { + var filenamemask = Path.GetFileNameWithoutExtension(sqld.Xml_BackupFileNameMask); + var vars = new Dictionary(); + vars.Add(nameof(DBSubstitutionName.DATABASE), sqld.DBName); + vars.Add(nameof(DBSubstitutionName.DATASOURCE), ""); + vars.Add(nameof(DBSubstitutionName.DBOTYPE), "DBBACKUP"); + vars.Add(nameof(DBSubstitutionName.DBONAME), ""); + vars.Add(nameof(DBSubstitutionName.DBDATAGROUP), ""); + vars.Add(nameof(DBSubstitutionName.BACKUPTS), "*"); + filenamemask = VRH.Common.StringConstructor.ResolveConstructor(vars, filenamemask, "{}@@"); + var filelist = new DirectoryInfo(sqld.Xml_BackupTargetDirectoryPath)?.GetFiles(filenamemask)?.ToList(); + var filelistordered = filelist?.OrderByDescending(x => x.CreationTime).ToList(); + return filelistordered; + } + + /// + /// Enable sa user and set/change its password + /// + /// + /// + /// + /// + public static string ConfigureSaUser(string cs,string password, string newsapassword) + { + var sqlserver = SQLServerConnect(cs); + sqlserver.Settings.LoginMode= ServerLoginMode.Mixed; + sqlserver.Logins["sa"].Enable(); + sqlserver.Logins.ItemById(10).Enable(); + sqlserver.Logins["sa"].ChangePassword(newsapassword); + sqlserver.Alter(); + sqlserver.Logins["a"].Refresh(); + return SQLServerConnect(cs).ConnectionContext.ConnectionString; + } + public static void ConfigureWindowsUser(string cs, string sapassword, string databasename, string windowsfullusername,string windowsuserpassword,List rolenamelist) + { + var sqlserver = SQLServerConnect(cs); + if (!sqlserver.Logins.Contains(windowsfullusername)) + { + var wul = new Microsoft.SqlServer.Management.Smo.Login(sqlserver, windowsfullusername); + wul.LoginType = LoginType.WindowsUser; + wul.Create(windowsuserpassword,LoginCreateOptions.None); + if (!string.IsNullOrWhiteSpace(databasename)) + { + var dbobject = sqlserver.Databases[databasename]; + if (dbobject==null) { throw new Exception($"Specified databas '{databasename}' does not exist!"); } + if (dbobject.Users.Contains(windowsfullusername)) { dbobject.Users[windowsfullusername].Drop(); } + var dbuser = new Microsoft.SqlServer.Management.Smo.User(dbobject, windowsfullusername); + dbuser.Login = windowsfullusername; + dbuser.Create(windowsuserpassword); + foreach (var rn in rolenamelist) + { + var dbrole = dbobject.Roles[rn]; + dbrole.AddMember(windowsfullusername); + dbrole.Alter(); + } + } + } + } + public static void DropDatabase(string cs,string databasename,string sapassword) + { + var sqlserver = SQLServerConnect(cs); + if (sqlserver.Databases.Contains(databasename)) + { + sqlserver.KillAllProcesses(databasename); + sqlserver.Databases[databasename].Drop(); + } + else { throw new Exception($"Specified databas '{databasename}' does not exist!"); } + } + public static string GetServerDefaultPhysicalDATFileLocation(string cs) + { + var sqlserver = SQLDataBaseManagerCore.SQLServerConnect(cs); + return string.IsNullOrEmpty(sqlserver.DefaultFile) ? sqlserver.MasterDBPath : sqlserver.DefaultFile; + } + public static string GetServerDefaultPhysicalLOGFileLocation(string cs) + { + var sqlserver = SQLDataBaseManagerCore.SQLServerConnect(cs); + return string.IsNullOrEmpty(sqlserver.DefaultLog) ? sqlserver.MasterDBLogPath : sqlserver.DefaultLog; + } + public static string GetDBName(string cs) + { + var sqlc = new Microsoft.Data.SqlClient.SqlConnection(cs); + return sqlc.Database; + } + public static string GetDataSource(string cs) + { + var sqlc = new Microsoft.Data.SqlClient.SqlConnection(cs); + return sqlc.DataSource; + } + public enum SQLDBStatus { NoAccess, OK, } + public static SQLDBStatus GetStatus(string cs) + { + try { var s = GetPhysicalFilesLocation(cs); if (s == null) { throw new Exception(); }; return SQLDBStatus.OK; } catch { return SQLDBStatus.NoAccess; } + } + public static Server SQLServerConnect(string sqlconnectionstring) + { + try + { + var sqlconnection = new Microsoft.Data.SqlClient.SqlConnection(sqlconnectionstring); + var serverconnection = new ServerConnection(sqlconnection); + var sqlserver = new Server(serverconnection); + if (string.IsNullOrEmpty(sqlserver.Information.Version.ToString())) { throw new Exception("Connection not established!"); } + return sqlserver; + } + catch (Exception ex) { throw ex; } + } + #region GetPhysicalFilesLocation + /// + /// Returns the physical path to the directory that holds the files of the database + /// + /// + /// the path, or null, if any error occurs + public static string GetPhysicalFilesLocation(string sqlconnectionstring) + { + int commandtimeout = 5000; + string scripttext = ""; + scripttext += " DECLARE @physicalpath varchar(1000) = NULL;"; + scripttext += " SELECT @physicalpath = f.physical_name"; + scripttext += " FROM sys.master_files as f inner join sys.databases as d on f.database_id = d.database_id"; + scripttext += " where d.name = '{DATABASE}' and f.type_desc = 'ROWS';"; + scripttext += " SELECT 1 AS RETURNCODE, @physicalpath AS RETURNMESSAGE;"; + var vars = new Dictionary(); + vars.Add(nameof(DBSubstitutionName.DATABASE), GetDBName(sqlconnectionstring)); + vars.Add(nameof(DBSubstitutionName.DATASOURCE), ""); + var result = ExecuteSQLScript(sqlconnectionstring, scripttext, commandtimeout, vars); + if (result.ReturnValue != 0) { return Path.GetDirectoryName(result.ReturnMessage); } else { return null; }; + } + #endregion GetPhysicalFilesLocation + #region DBSubstitution + public enum DBSubstitutionName + { + DATABASE,DATASOURCE,DBOTYPE,DBONAME,DBDATAGROUP,BACKUPTS, + } + #endregion DBSubstitution + #region ExecuteSQLScript + /// + /// Egy SQL script végrehajtása (GO-val lezárt batch-eket tartalmazhat) + /// + /// sql connection string + /// a script + /// az egyes batch-ek végrehajtási időzítése + /// + /// behelyettesítendő változók (a scriptben ezek nevei {} között kell legyenek) + /// a következő neveket felismeri akkor is, ha nincsenek benne a sztótárban: + /// DATASOURCE: a sql server neve domain/név formában + /// DATABASE: az aadatbázis neve + /// + /// + /// egy ReturnInfoJSON struktúrát, amiben a ReturnValue és ReturnMessage a script által előállított két + /// (egy int és egy string) értéket tartalmazza pl. egy ilyen eredményt: SELECT @returncode, @returnmessage; + /// Ha a végrehajtás nem ad vissza eredményt, akkor az első érték 0, a második pedig null; + /// + /// + public static ReturnInfoJSON ExecuteSQLScript(string sqlconnectionstring, string sqltxt, int commandtimeout, Dictionary vars) + { + var sqlc = new Microsoft.Data.SqlClient.SqlConnection(sqlconnectionstring); + + sqltxt = VRH.Common.StringConstructor.ResolveConstructor(vars, sqltxt, "{}@@"); + + sqlc.Open(); + string SQLBatchTxt = ""; // ebben lesznek az sql script-en belüli batch-ek összerakva + int SQLBatchIndex = 0; // az aktuális batch indexe + int scriptlineindex = 0; // az aktuális script sor indexe + System.Data.DataSet DataSet = null; // ebben lesz az eredmény (az utolsó batch eredménye) + sqltxt += "\r\nGO";// ha esetleg nem lenne, odatesszük a végére az utolsó batch-et lezáró GO-t + foreach (var scriptline in sqltxt.Split(new char[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries)) + { + scriptlineindex += 1; + if (Regex.Match(scriptline, @"^GO$").Success)// a batch utolső sora + { + if (!string.IsNullOrWhiteSpace(SQLBatchTxt)) + { + SQLBatchIndex += 1; + DataSet = ExecuteSQLScriptBatch(sqlc, SQLBatchTxt, commandtimeout); + SQLBatchTxt = ""; + } + } + else if (!string.IsNullOrWhiteSpace(scriptline)) + { + SQLBatchTxt += scriptline + "\r\n"; + } + } + sqlc.Close(); + if (DataSet != null && DataSet.Tables != null) + { + var firstreturnedtable = DataSet.Tables[0]; + var firstreturnedrow = firstreturnedtable.Rows[0]; + var firstreturnedvalue = firstreturnedrow[0]; + var secondreturnedvalue = firstreturnedrow[1]; + var rv = Convert.ToInt32(firstreturnedvalue); + var rm = Convert.ToString(secondreturnedvalue); + return new ReturnInfoJSON() { ReturnValue = rv, ReturnMessage = rm, }; + } + else { return new ReturnInfoJSON() { ReturnValue = 0, ReturnMessage = null, }; } + } + private static System.Data.DataSet ExecuteSQLScriptBatch(Microsoft.Data.SqlClient.SqlConnection sqlc, string sqlbatchtxt, int commandtimeout) + { + var sqlcommand = sqlc.CreateCommand(); + sqlcommand.CommandText = sqlbatchtxt; + sqlcommand.CommandTimeout = commandtimeout; + var DataAdapter = new Microsoft.Data.SqlClient.SqlDataAdapter(sqlcommand); + var DataSet = new System.Data.DataSet(); + DataAdapter.Fill(DataSet); + return DataSet; + } + #endregion ExecuteSQLScript + #region ExecuteSQLStoredProcedure + /// + /// Egy SQL script végrehajtása (GO-val lezárt batch-eket tartalmazhat) + /// + /// sql connection string + /// a script + /// az egyes batch-ek végrehajtási időzítése + /// + /// behelyettesítendő változók (a scriptben ezek nevei {} között kell legyenek) + /// a következő neveket felismeri akkor is, ha nincsenek benne a sztótárban: + /// DATASOURCE: a sql server neve domain/név formában + /// DATABASE: az aadatbázis neve + /// + /// + /// egy ReturnInfoJSON struktúrát, amiben a ReturnValue és ReturnMessage a script által előállított két + /// (egy int és egy string) értéket tartalmazza pl. egy ilyen eredményt: SELECT @returncode, @returnmessage; + /// Ha a végrehajtás nem ad vissza eredményt, akkor az első érték 0, a második pedig null; + /// + /// + public class SPparameter + { + public string Name; + public object Value; + public System.Data.SqlDbType Type; + public int Typepar; + public System.Data.ParameterDirection Direction; + public SPparameter() { } + public SPparameter(Microsoft.Data.SqlClient.SqlParameter p) + { + Name = p.ParameterName; + Value = p.Value; + Type = p.SqlDbType; + Typepar = p.Size; + Direction = p.Direction; + } + } + + public static List ExecuteSQLStoredProcedure(string sqlconnectionstring, string storedprocedurename, int commandtimeout, List SPparameters) + { + var sqlc = new Microsoft.Data.SqlClient.SqlConnection(sqlconnectionstring); + var sqlcommand = sqlc.CreateCommand(); + sqlcommand.Connection = sqlc; + sqlcommand.CommandText = storedprocedurename; + sqlcommand.CommandTimeout = commandtimeout; + sqlcommand.CommandType= System.Data.CommandType.StoredProcedure; + //var DataAdapter = new Microsoft.Data.SqlClient.SqlDataAdapter(sqlcommand); + sqlc.Open(); + foreach (var p in SPparameters) + { + var sqlparameter = new Microsoft.Data.SqlClient.SqlParameter() + { + ParameterName = p.Name, + SqlDbType = p.Type, + Size = p.Typepar, + Direction = p.Direction, + Value = p.Value, + }; + sqlcommand.Parameters.Add(sqlparameter); + } + sqlcommand.ExecuteNonQuery(); + + var sqlresult = new List(); + foreach (var p in SPparameters) + { + if (p.Direction == System.Data.ParameterDirection.Output) + { + sqlresult.Add(new SPparameter(sqlcommand.Parameters[p.Name])); + } + } + sqlc.Close(); + return sqlresult; + } + #endregion ExecuteSQLStoredProcedure + #region BackupSqlScripts + public static void BackupSqlScripts(string backupdirectorypath,string backupfilenamemask,string sqlcs,bool createZip, DateTime? timestamp=null) + { + var sqlserver = SQLServerConnect(sqlcs); + if (sqlserver!=null) + { + string backupts = (timestamp.HasValue? timestamp.Value:DateTime.Now).ToString("yyyyMMddHHmmss"); + var vars = new Dictionary(); + vars.Add(nameof(DBSubstitutionName.DATABASE), GetDBName(sqlcs)); + vars.Add(nameof(DBSubstitutionName.DATASOURCE), GetDataSource(sqlcs)); + vars.Add(nameof(DBSubstitutionName.BACKUPTS), backupts); + vars.Add(nameof(DBSubstitutionName.DBOTYPE), "Scripts"); + + string zipfilefullpath = null; + string tempbackupdirectorypath; + if (createZip) + { + vars[nameof(DBSubstitutionName.DBONAME)] = ""; + vars[nameof(DBSubstitutionName.DBDATAGROUP)] = ""; + string zipfilename = VRH.Common.StringConstructor.ResolveConstructor(vars, backupfilenamemask, "{}@@") + ".zip"; + zipfilefullpath = Path.Combine(backupdirectorypath, zipfilename); + tempbackupdirectorypath = Path.Combine(backupdirectorypath, "TEMP_" + Path.GetFileNameWithoutExtension(zipfilename)); + if (Directory.Exists(tempbackupdirectorypath)) { Directory.Delete(tempbackupdirectorypath, recursive: true); } + if (!Directory.Exists(tempbackupdirectorypath)) { Directory.CreateDirectory(tempbackupdirectorypath); } + } + else { tempbackupdirectorypath = backupdirectorypath; } + + if (!Directory.Exists(backupdirectorypath)) { Directory.CreateDirectory(backupdirectorypath); } + var directorynameonly = new DirectoryInfo(backupdirectorypath).Name; + var backupfilenameext = Path.GetExtension(backupfilenamemask); if (string.IsNullOrWhiteSpace(backupfilenameext)) { backupfilenameext = ".sql"; } + backupfilenamemask = Path.GetFileNameWithoutExtension(backupfilenamemask); + var sqldatabase = sqlserver.Databases[sqlserver.ConnectionContext.DatabaseName]; + + ScriptOneObject(sqlserver, tempbackupdirectorypath, backupfilenamemask + backupfilenameext, new List { sqldatabase }, vars); + ScriptOneObject(sqlserver, tempbackupdirectorypath, backupfilenamemask + backupfilenameext, sqldatabase.UserDefinedFunctions.Cast().ToList(), vars); + ScriptOneObject(sqlserver, tempbackupdirectorypath, backupfilenamemask + backupfilenameext, sqldatabase.StoredProcedures.Cast().ToList(), vars); + ScriptOneObject(sqlserver, tempbackupdirectorypath, backupfilenamemask + backupfilenameext, sqldatabase.Views.Cast().ToList(), vars); + ScriptOneObject(sqlserver, tempbackupdirectorypath, backupfilenamemask + backupfilenameext, sqldatabase.Tables.Cast().ToList(), vars); + ScriptOneObject(sqlserver, tempbackupdirectorypath, backupfilenamemask + backupfilenameext, sqldatabase.Triggers.Cast().ToList(), vars); + if (createZip) + { + ZipTools.CreateEntriesFromDirectoryContent(tempbackupdirectorypath, zipfilefullpath, "*.sql", backupts,removearchivedfiles:true, storepathinzip: false); + } + } + + } + private static void ScriptOneObject(Server sqlserver,string backupdirectory,string backupfilenamemask,List sqldbobjects,Dictionary vars) + { + var sqldbname = sqlserver.ConnectionContext.DatabaseName; + string lastfilename = null; + foreach (var sqldbobj in sqldbobjects) + { + bool systemobject = true; + try { systemobject = sqldbobj.Properties["IsSystemObject"].Value.ToString().ToUpper() == bool.TrueString.ToUpper(); } catch { } + if (systemobject) { continue; } + + string namevalue=null; + if (namevalue == null) { try { namevalue = Tools.GetPropertyValue(sqldbobj, "Name"); } catch { namevalue = null; } } + if (namevalue == null) { try { namevalue = sqldbobj.Properties["Name"].Value.ToString(); } catch { namevalue = null; } } + if (namevalue == null) { namevalue = "UNDEFINED"; } + + vars[nameof(DBSubstitutionName.DBONAME)]=namevalue; + vars[nameof(DBSubstitutionName.DBDATAGROUP)]=sqldbobj.GetType().Name; + + string filename = VRH.Common.StringConstructor.ResolveConstructor(vars, backupfilenamemask, "{}@@"); + if (lastfilename!=filename) + { + var i = 2; + string filenamesav = filename; + while (true) + { + if (!File.Exists(filename)) { break; } + filename = filenamesav + $" ({i})"; + i++; + } + using (var sw = File.AppendText(Path.Combine(backupdirectory, filename))) + { + sw.WriteLine($"use [{sqldbname}]"); + } + lastfilename = filename; + } + var myscripter = new Microsoft.SqlServer.Management.Smo.Scripter(); + myscripter.Server = sqlserver; + myscripter.Options.FileName = Path.Combine(backupdirectory, filename); + myscripter.Options.AppendToFile = true; + myscripter.Options.ScriptSchema = true; + myscripter.Options.ScriptData = false; + myscripter.Options.SchemaQualify = true; + myscripter.Options.AllowSystemObjects = false; + myscripter.Options.IncludeHeaders = true; + myscripter.Options.IncludeIfNotExists = true; + myscripter.Options.ClusteredIndexes = true; + myscripter.Options.DriAll = true; + myscripter.Options.ToFileOnly = true; + myscripter.Options.Indexes = true; + myscripter.Options.Permissions = true; + myscripter.Options.WithDependencies = false; + myscripter.Options.AnsiFile=true; + + var o = new SqlSmoObject[] { sqldbobj }; + //create the drop statement + myscripter.Options.ScriptDrops = true; + List scripttexts = myscripter.Script(o).Cast().ToList(); + //create the create statement + myscripter.Options.ScriptDrops = false; + List scripttexts2 = myscripter.Script(o).Cast().ToList(); + } + return; + } + #endregion BackupSqlScripts + #region BackupSqlData + public static void BackupSqlData(SQLDataBase sqld,DateTime? timestamp=null) + { + string sqlcs = sqld.SQLCS; + var sqlserver = SQLServerConnect(sqlcs); + if (sqlserver != null) + { + string backupts = (timestamp.HasValue ? timestamp.Value : DateTime.Now).ToString("yyyyMMddHHmmss"); + bool createZip = sqld.Xml_CreateZip; + string backupdirectorypath = sqld.Xml_BackupTargetDirectoryPath; + string backupfilenamemask = sqld.Xml_BackupFileNameMask; + + var backupfilenameext = Path.GetExtension(backupfilenamemask); if (string.IsNullOrWhiteSpace(backupfilenameext)) { backupfilenameext = ".sql"; } + backupfilenamemask = Path.GetFileNameWithoutExtension(backupfilenamemask); + + var vars = new Dictionary(); + vars.Add(nameof(DBSubstitutionName.DATABASE), GetDBName(sqlcs)); + vars.Add(nameof(DBSubstitutionName.DATASOURCE), GetDataSource(sqlcs)); + vars.Add(nameof(DBSubstitutionName.BACKUPTS), backupts); + vars.Add(nameof(DBSubstitutionName.DBOTYPE), "TableData"); + + string zipfilefullpath=null; + string tempbackupdirectorypath; + if (createZip) + { + vars[nameof(DBSubstitutionName.DBONAME)] = ""; + vars[nameof(DBSubstitutionName.DBDATAGROUP)] = ""; + string zipfilename = VRH.Common.StringConstructor.ResolveConstructor(vars, backupfilenamemask, "{}@@") + ".zip"; + tempbackupdirectorypath = Path.Combine(backupdirectorypath, "TEMP_"+Path.GetFileNameWithoutExtension(zipfilename)); + zipfilefullpath = Path.Combine(backupdirectorypath, zipfilename); + if (Directory.Exists(tempbackupdirectorypath)) { Directory.Delete(tempbackupdirectorypath, recursive: true); } + if (!Directory.Exists(tempbackupdirectorypath)) { Directory.CreateDirectory(tempbackupdirectorypath); } + } + else { tempbackupdirectorypath = backupdirectorypath; } + + + if (!Directory.Exists(backupdirectorypath)) { Directory.CreateDirectory(backupdirectorypath); } + + + List backupfilepathlist = new List(); + foreach (var sqldata in sqld.Xml_SQLDataList) + { + vars[nameof(DBSubstitutionName.DBDATAGROUP)] = sqldata.Group; + var sqlfilescreated = ScriptOneDataGroup(sqlserver, tempbackupdirectorypath, backupfilenamemask + backupfilenameext, sqldata.TableNameList, vars); + backupfilepathlist.AddRange(sqlfilescreated); + } + + if (createZip) + { + string fullpathregex = Regex.Escape(string.Join(";",backupfilepathlist)).Replace(';','|'); + ZipTools.CreateEntriesFromDirectoryContent(tempbackupdirectorypath, zipfilefullpath, "*.sql", fullpathregex, removearchivedfiles: true, storepathinzip: false); + } + } + } + private static List ScriptOneDataGroup(Server sqlserver, string backupdirectorypath, string backupfilenamemask, List tablenamelist, Dictionary vars) + { + string filename =null , filefullname=null, lastfilefullname = null; + var myscripter = new Microsoft.SqlServer.Management.Smo.Scripter(); + myscripter.Server = sqlserver; + myscripter.Options.ScriptSchema = false; + myscripter.Options.ScriptData = true; + myscripter.Options.NoCommandTerminator = true; + myscripter.Options.FileName = null; + myscripter.Options.ToFileOnly = true; + myscripter.Options.AnsiFile = true; + //myscripter.Options.AppendToFile = true; + //myscripter.Options.SchemaQualify = true; + //myscripter.Options.AllowSystemObjects = false; + //myscripter.Options.IncludeHeaders = true; + //myscripter.Options.IncludeIfNotExists = true; + //myscripter.Options.ClusteredIndexes = true; + //myscripter.Options.DriAll = true; + //myscripter.Options.Indexes = true; + //myscripter.Options.Permissions = true; + //myscripter.Options.WithDependencies = false; + var backupfilelist = new List(); + var urnstoscript = new UrnCollection(); + var deletefromlist = new List(); + foreach (var tn in tablenamelist) + { + string tn_dbname = tn.Split('.')[0]; + tn_dbname = sqlserver.ConnectionContext.DatabaseName; + string tn_schemaname = tn.Split('.')[1]; + string tn_name = tn.Split('.')[2]; + vars[nameof(DBSubstitutionName.DBONAME)] = $"{tn_schemaname}.{tn_name}"; + filename = VRH.Common.StringConstructor.ResolveConstructor(vars, backupfilenamemask, "{}@@"); + filefullname = Path.Combine(backupdirectorypath, filename); + if (lastfilefullname!=filefullname && lastfilefullname!=null) + { + backupfilelist.Add(CreateOneSqlFile(urnstoscript, deletefromlist,sqlserver, myscripter, lastfilefullname)); + lastfilefullname = filefullname; + deletefromlist.Clear(); + urnstoscript.Clear(); + } + //powershell: $Urn = "$($sqlserver.Urn)/Database[@Name='$($tuple.Database)']/Table[@Name='$($tuple.Table)' and @Schema='$($tuple.Schema)']"; + string urnstring = $"{sqlserver.Urn}/Database[@Name='{tn_dbname}']/Table[@Name='{tn_name}' and @Schema='{tn_schemaname}']"; + deletefromlist=deletefromlist.Prepend($"DELETE FROM [{tn_dbname}].[{tn_schemaname}].[{tn_name}]\r\nGO").ToList();// törlés sorrendje fordított a létrehozáséhoz képest! + urnstoscript.Add(new Microsoft.SqlServer.Management.Sdk.Sfc.Urn(urnstring)); + lastfilefullname = filefullname; + } + backupfilelist.Add(CreateOneSqlFile(urnstoscript, deletefromlist,sqlserver,myscripter,filefullname)); + return backupfilelist; + } + private static string CreateOneSqlFile( UrnCollection urnstoscript,List deletefromlist,Server sqlserver,Scripter myscripter, string sqlfilefullname) + { + myscripter.Options.FileName = sqlfilefullname; + if (urnstoscript.Any()) { myscripter.EnumScript(urnstoscript); } + var scripttext = File.ReadAllText(sqlfilefullname); + deletefromlist = deletefromlist.Prepend($"use [{sqlserver.ConnectionContext.DatabaseName}]").ToList(); + File.WriteAllText(sqlfilefullname, string.Join("\r\n",deletefromlist) +"\r\n\r\n" + scripttext, Encoding.UTF8);//???????????????? + return sqlfilefullname; + } + #endregion BackupSqlData + #endregion private methods + } + #endregion class SQLDataBaseManager + + #region SQLDataBaseManager class + public class SQLDataBaseManagerXmlProcessor : XmlParser + { + #region fields + private List _sqldatabaselist; + #endregion fields + #region constructor + public SQLDataBaseManagerXmlProcessor(string xmlcs, string basefolder, string lcid) : base(xmlcs, basefolder, lcid, null) + { + _sqldatabaselist = new List(); + var schtskxmllist = GetAllXElements(nameof(SQLDataBase.XmlStructure.SQLDataBase)); + var common = new SQLDataBase() + { + Xml_CreateZip = GetValue(nameof(SQLDataBase.XmlStructure.Attributes.CreateZip), this.RootElement, SQLDataBase.XmlStructure.Attributes.CreateZip.Values.DEFAULT), + Xml_BackupFileNameMask = GetValue(nameof(SQLDataBase.XmlStructure.Attributes.BackupFileNameMask), this.RootElement, SQLDataBase.XmlStructure.Attributes.BackupFileNameMask.Values.DEFAULT), + Xml_RestoreFileNameMask = GetValue(nameof(SQLDataBase.XmlStructure.Attributes.RestoreFileNameMask), this.RootElement, SQLDataBase.XmlStructure.Attributes.RestoreFileNameMask.Values.DEFAULT), + Xml_BackupTargetDirectoryPath = GetValue(nameof(SQLDataBase.XmlStructure.Attributes.BackupTargetDirectoryPath), this.RootElement, SQLDataBase.XmlStructure.Attributes.BackupTargetDirectoryPath.Values.DEFAULT), + Xml_PhysicalFilesDirectoryPath = GetValue(nameof(SQLDataBase.XmlStructure.Attributes.PhysicalFilesDirectoryPath), this.RootElement, SQLDataBase.XmlStructure.Attributes.PhysicalFilesDirectoryPath.Values.DEFAULT), + + }; + if (schtskxmllist != null && schtskxmllist.Any()) + { + foreach (var schtskxml in schtskxmllist) { var st = new SQLDataBase(schtskxml,common); if (st.Valid) { _sqldatabaselist.Add(st); } } + } + } + #endregion constructor + #region GetDefinitionList + public List GetDefinitionList() { return _sqldatabaselist; } + #endregion GetDefinitionList + } + #endregion SQLDataBaseManager class + + #region SQLDataBase class + public class SQLDataBase : XmlLinqBase + { + #region fields + public bool Valid = true; + public bool Xml_CreateZip= true; + public string Xml_Key; + public string Xml_Description; + public string Xml_BackupFileNameMask; + public string Xml_RestoreFileNameMask; + public string Xml_BackupTargetDirectoryPath; + public string Xml_SQLConnectionString; + public string Xml_PhysicalFilesDirectoryPath; + public List Xml_SQLDataList; + + public string DBName; + public string DataSource; + public SQLDataBaseManagerCore.SQLDBStatus Status; + public string PhysicalFilesDirectoryPath; + public string SQLCS + { + get { return XmlProcessing.ConnectionStringStore.GetSQL(this.Xml_SQLConnectionString); } + } + #endregion fields + + #region basic constructor + public SQLDataBase() { } + #endregion basic constructor + #region xml constructor + public SQLDataBase(XElement sqldatabasexml, SQLDataBase common) + { + Valid = true; + string ATTRIBUTEMANDATORY = nameof(XmlStructure.SQLDataBase) + " attribute is mandatory! Name: {0}"; + Xml_Key= GetValue(nameof(XmlStructure.SQLDataBase.Attributes.Key), sqldatabasexml, XmlStructure.SQLDataBase.Attributes.Key.Values.DEFAULT); + Xml_Description = sqldatabasexml.Attribute(XName.Get(nameof(XmlStructure.SQLDataBase.Attributes.Description)))?.Value; + if (string.IsNullOrWhiteSpace(Xml_Description)) { throw new ApplicationException(string.Format(ATTRIBUTEMANDATORY, nameof(XmlStructure.SQLDataBase.Attributes.Description))); } + Xml_BackupFileNameMask = GetValue(nameof(XmlStructure.SQLDataBase.Attributes.BackupFileNameMask), sqldatabasexml, common.Xml_BackupFileNameMask); + Xml_RestoreFileNameMask = GetValue(nameof(XmlStructure.SQLDataBase.Attributes.RestoreFileNameMask), sqldatabasexml, common.Xml_RestoreFileNameMask); + Xml_BackupTargetDirectoryPath = GetValue(nameof(XmlStructure.SQLDataBase.Attributes.BackupTargetDirectoryPath), sqldatabasexml, common.Xml_BackupTargetDirectoryPath); + Xml_SQLConnectionString = GetValue(nameof(XmlStructure.SQLDataBase.Attributes.SQLConnectionString), sqldatabasexml, XmlStructure.SQLDataBase.Attributes.SQLConnectionString.Values.DEFAULT); + + var sqldataXmlList = GetAllXElements(sqldatabasexml, nameof(XmlStructure.SQLDataBase.SQLData)); + Xml_CreateZip = GetValue(nameof(XmlStructure.SQLDataBase.Attributes.CreateZip), sqldatabasexml, common.Xml_CreateZip); + Xml_PhysicalFilesDirectoryPath = GetValue(nameof(XmlStructure.SQLDataBase.Attributes.PhysicalFilesDirectoryPath), sqldatabasexml, common.Xml_PhysicalFilesDirectoryPath); + Xml_SQLDataList = new List(); + if (sqldataXmlList!=null) { foreach (var sqldataXml in sqldataXmlList) { Xml_SQLDataList.Add(new SQLData(sqldataXml)); } } + } + #endregion xml constructor + #region cloner constructor + public SQLDataBase(SQLDataBase sqld) + { + Valid = sqld.Valid; + Xml_CreateZip = sqld.Xml_CreateZip; + Xml_Key = sqld.Xml_Key; + Xml_Description = sqld.Xml_Description; + Xml_BackupFileNameMask = sqld.Xml_BackupFileNameMask; + Xml_RestoreFileNameMask = sqld.Xml_RestoreFileNameMask; + Xml_BackupTargetDirectoryPath = sqld.Xml_BackupTargetDirectoryPath; + Xml_SQLConnectionString = sqld.Xml_SQLConnectionString; + Xml_PhysicalFilesDirectoryPath = sqld.Xml_PhysicalFilesDirectoryPath; + Xml_SQLDataList = sqld.Xml_SQLDataList.Select(x => x).ToList(); + } + #endregion cloner constructor + #region XmlStructure + public static class XmlStructure + { + public static class Attributes + { + public static class BackupFileNameMask { public static class Values { public const string DEFAULT = ""; } } + public static class RestoreFileNameMask { public static class Values { public const string DEFAULT = ""; } } + public static class BackupTargetDirectoryPath { public static class Values { public const string DEFAULT = ""; } } + public static class PhysicalFilesDirectoryPath { public static class Values { public const string DEFAULT = ""; } } + + + public static class CreateZip{ public static class Values { public const bool DEFAULT = true; } } + } + public static class SQLDataBase + { + public static class Attributes + { + public static class Key { public static class Values { public const string DEFAULT = ""; } } + public static class Description { } + public static class SQLConnectionString { public static class Values { public const string DEFAULT = ""; } } + public static class BackupFileNameMask { } + public static class RestoreFileNameMask { } + public static class BackupTargetDirectoryPath { } + public static class CreateZip { } + public static class PhysicalFilesDirectoryPath { } + } + public static class SQLData + { + public static class Values { public const string DEFAULT = ""; } + public static class Attributes + { + public static class Group { public static class Values { public const string DEFAULT = ""; } } + } + } + } + } + #endregion XmlStructure + #region SQLData class + public class SQLData : XmlLinqBase + { + #region fields + public string Group = ""; + public List TableNameList; + #endregion fields + #region constructors + public SQLData() { } + public SQLData(SQLData sqld) { Group = sqld.Group; TableNameList = sqld.TableNameList.Select(x => x).ToList(); } + public SQLData(XElement sqldXml) + { + Group = GetValue(nameof(XmlStructure.SQLDataBase.SQLData.Attributes.Group), sqldXml, XmlStructure.SQLDataBase.SQLData.Attributes.Group.Values.DEFAULT); + string tablenamecommalist = GetValue(sqldXml, XmlStructure.SQLDataBase.SQLData.Values.DEFAULT); + if (string.IsNullOrWhiteSpace(tablenamecommalist)) { TableNameList = new List(); } + else + { + var temptablenamelist = tablenamecommalist.Split(new char[]{ ','},StringSplitOptions.RemoveEmptyEntries).ToList(); + TableNameList = new List(); + foreach (string tn in temptablenamelist) + { + var tnparts = tn.Split('.'); + string fullqualifiedname = null; + switch (tnparts.Length) + { + case 1: fullqualifiedname = $"{{DBNAME}}.dbo.{tnparts[0]}"; break; + case 2: fullqualifiedname = $"{{DBNAME}}.{tnparts[0]}.{tnparts[1]}"; break; + case 3: fullqualifiedname = tn; break; + default: throw new Exception($"Table name is incorrect! {nameof(SQLData)} Type:{Group}, table name:{tn}."); + } + TableNameList.Add(fullqualifiedname); + } + } + } + #endregion constructors + } + #endregion SQLData class + } + #endregion SQLDataBase class +} diff --git a/Vrh.Log4Pro.MaintenanceConsole/Manager - ScheduledTaskManager.cs b/Vrh.Log4Pro.MaintenanceConsole/Manager - ScheduledTaskManager.cs index ae874c7..d50ca6f 100644 --- a/Vrh.Log4Pro.MaintenanceConsole/Manager - ScheduledTaskManager.cs +++ b/Vrh.Log4Pro.MaintenanceConsole/Manager - ScheduledTaskManager.cs @@ -12,72 +12,56 @@ using Microsoft.Web.Administration; using System.Management; using System.Diagnostics; +using Vrh.Log4Pro.MaintenanceConsole.MenuNS; +using Vrh.Log4Pro.MaintenanceConsole.ColorConsoleNS; +using Vrh.Log4Pro.MaintenanceConsole.ToolsNS; +using Vrh.Log4Pro.MaintenanceConsole.CommandLineParserNS; + using Vrh.XmlProcessing; using VRH.Common; using System.Xml.Linq; using System.Text.RegularExpressions; -namespace Vrh.Log4Pro.MaintenanceConsole +namespace Vrh.Log4Pro.MaintenanceConsole.ScheduledTaskManagerNS { #region ScheduledTaskManager class - public static class ScheduledTaskmanagerManager + public static class ScheduledTaskManager { - private const string XMLCONNECTIONSTRING = "file=Config.Xml;element=ScheduledTasks;"; + private const string XMLCONNECTIONSTRING = "config=MAINTENANCECONSOLE_SCHEDULEDTASKMANAGER;"; + private const string XMLCONNECTIONSTRING_DEFAULT = "file=Config.Xml;element=ScheduledTasks;"; #region Execute public static object Execute(object o1 = null, object o2 = null) { - var args = o1 as string[]; - var module = CommandLine.GetCommandLineArgument(args, "-MODULE"); - var functionkey = CommandLine.GetCommandLineArgument(args, "-FUNCTION"); + var args = (o1 as Menu.ExecutorParameter).Args; + var functionkey = CommandLine.GetCommandLineArgument(args, CLP.CMD_FUNCTION); - string xmlcs = XMLCONNECTIONSTRING; - var config = new ScheduledTaskManagerCoreXmlProcessor(xmlcs, "", "hu-HU"); + var config = new ScheduledTaskManagerXmlProcessor(XMLCONNECTIONSTRING, "", "hu-HU"); + var ep = new Menu.ExecutorParameter(config, args); var menufunctions = new Menu("Manage Scheduled tasks", "Select the management function!") - .AddMenuItem(new Menu.Item("INS", "Install scheduled task", Install)) - .AddMenuItem(new Menu.Item("UIN", "Uninstall scheduled task", Uninstall)) - .AddMenuItem(new Menu.Item("RUN", "Start scheduled task", Run)) - .AddMenuItem(new Menu.Item("END", "Stop scheduled task", End)) - .AddMenuItem(new Menu.Item("ENA", "Enable scheduled task", Enable)) - .AddMenuItem(new Menu.Item("DIS", "Disable scheduled task", Disable)) - .AddMenuItem(new Menu.Item("CHP", "Change scheduled task priority", ChangePriority)) - .SetSelectionMode(Menu.SelectionMode.Single); - - while (true) - { - Menu.Selection sr; - - menufunctions.DisplayTitle(); - DisplayTasks(config); - menufunctions.DisplayItems(); - sr = menufunctions.Select(functionkey); - if (sr.Result == Menu.SelectionResult.Exit) { break; } - else if (sr.Result == Menu.SelectionResult.None) { continue; } - else if (sr.Result == Menu.SelectionResult.Error) { continue; } - menufunctions.SetExecutorParameters(sr, new ScheduledTaskExecutorParameter (config,args)); - menufunctions.ExecuteSelection(sr.SelectedKeyList); - if (menufunctions.GetCommandMode()) { break; } - } + .AddMenuItem(new Menu.Item(CLP.Module.ScheduledTaskManager.Function.Install.KEY, "Install scheduled task", Install, ep)) + .AddMenuItem(new Menu.Item(CLP.Module.ScheduledTaskManager.Function.Install.KEY, "Uninstall scheduled task", Uninstall, ep)) + .AddMenuItem(new Menu.Item(CLP.Module.ScheduledTaskManager.Function.Install.KEY, "Start scheduled task", Run, ep)) + .AddMenuItem(new Menu.Item(CLP.Module.ScheduledTaskManager.Function.Install.KEY, "Stop scheduled task", End, ep)) + .AddMenuItem(new Menu.Item(CLP.Module.ScheduledTaskManager.Function.Install.KEY, "Enable scheduled task", Enable, ep)) + .AddMenuItem(new Menu.Item(CLP.Module.ScheduledTaskManager.Function.Install.KEY, "Disable scheduled task", Disable, ep)) + .AddMenuItem(new Menu.Item(CLP.Module.ScheduledTaskManager.Function.Install.KEY, "Change scheduled task priority", ChangePriority, ep)) + .SetSelectionMode(Menu.SelectionMode.Single) + .SetMenuHeaderDisplayer(ScheduledTaskListDisplayer); + menufunctions.ExecuteMenu(functionkey); return o2; } #endregion Execute - #region ScheduledTaskFunctionExecutorParameter - public class ScheduledTaskExecutorParameter - { - public ScheduledTaskExecutorParameter(ScheduledTaskManagerCoreXmlProcessor cfg, string[] args) { Config = cfg;Args = args; } - public ScheduledTaskManagerCoreXmlProcessor Config; - public string[] Args; - } - #endregion ScheduledTaskFunctionExecutorParameter + #region First level Executors with UI private static object ChangePriority(object parameter, object o) { - var config = (parameter as ScheduledTaskExecutorParameter).Config; - var args = (parameter as ScheduledTaskExecutorParameter).Args; + var config = (parameter as Menu.ExecutorParameter).GetConfig(); + var args = (parameter as Menu.ExecutorParameter).Args; - var selectedtaskindexes = CommandLine.GetCommandLineArgument(args, "-TASKS"); + var selectedtaskindexes = CommandLine.GetCommandLineArgument(args, CLP.Module.ScheduledTaskManager.Function.CMD_TASKS); - var menufolders = DisplayTasks(config, $"Select the scheduled task(s) to manage with function '{nameof(ChangePriority)}'!"); + var menufolders = DisplayScheduledTaskMenu(config, $"Select the scheduled task(s) to manage with function '{nameof(ChangePriority)}'!",silent:true); Menu.Selection sr = menufolders.Select(selectedtaskindexes); if (sr.Result == Menu.SelectionResult.Exit) { return o; } @@ -87,7 +71,7 @@ namespace Vrh.Log4Pro.MaintenanceConsole else { } foreach (var p in sr.SelectedParameterList) { - ScheduledTask st = p as ScheduledTask; + ScheduledTask st = p.Parameters as ScheduledTask; try { ScheduledTaskManagerCore.SetPriority(st.Xml_Name,st.Xml_Priority); @@ -99,12 +83,12 @@ namespace Vrh.Log4Pro.MaintenanceConsole } private static object Disable(object parameter, object o) { - var config = (parameter as ScheduledTaskExecutorParameter).Config; - var args = (parameter as ScheduledTaskExecutorParameter).Args; + var config = (parameter as Menu.ExecutorParameter).GetConfig(); + var args = (parameter as Menu.ExecutorParameter).Args; - var selectedtaskindexes = CommandLine.GetCommandLineArgument(args, "-TASKS"); + var selectedtaskindexes = CommandLine.GetCommandLineArgument(args, CLP.Module.ScheduledTaskManager.Function.CMD_TASKS); - var menufolders = DisplayTasks(config, $"Select the scheduled task(s) to manage with function '{nameof(Disable)}'!"); + var menufolders = DisplayScheduledTaskMenu(config, $"Select the scheduled task(s) to manage with function '{nameof(Disable)}'!", silent:true); Menu.Selection sr = menufolders.Select(selectedtaskindexes); if (sr.Result == Menu.SelectionResult.Exit) { return o; } @@ -114,7 +98,7 @@ namespace Vrh.Log4Pro.MaintenanceConsole else { } foreach (var p in sr.SelectedParameterList) { - ScheduledTask st = p as ScheduledTask; + ScheduledTask st = p.Parameters as ScheduledTask; try { ScheduledTaskManagerCore.DisableTask(st.Xml_Name); @@ -126,12 +110,12 @@ namespace Vrh.Log4Pro.MaintenanceConsole } private static object Enable(object parameter, object o) { - var config = (parameter as ScheduledTaskExecutorParameter).Config; - var args = (parameter as ScheduledTaskExecutorParameter).Args; + var config = (parameter as Menu.ExecutorParameter).GetConfig(); + var args = (parameter as Menu.ExecutorParameter).Args; - var selectedtaskindexes = CommandLine.GetCommandLineArgument(args, "-TASKS"); + var selectedtaskindexes = CommandLine.GetCommandLineArgument(args, CLP.Module.ScheduledTaskManager.Function.CMD_TASKS); - var menufolders = DisplayTasks(config, $"Select the scheduled task(s) to manage with function '{nameof(Enable)}'!"); + var menufolders = DisplayScheduledTaskMenu(config, $"Select the scheduled task(s) to manage with function '{nameof(Enable)}'!", silent: true); Menu.Selection sr = menufolders.Select(selectedtaskindexes); if (sr.Result == Menu.SelectionResult.Exit) { return o; } @@ -141,7 +125,7 @@ namespace Vrh.Log4Pro.MaintenanceConsole else { } foreach (var p in sr.SelectedParameterList) { - ScheduledTask st = p as ScheduledTask; + ScheduledTask st = p.Parameters as ScheduledTask; try { ScheduledTaskManagerCore.EnableTask(st.Xml_Name); @@ -153,12 +137,12 @@ namespace Vrh.Log4Pro.MaintenanceConsole } private static object End(object parameter, object o) { - var config = (parameter as ScheduledTaskExecutorParameter).Config; - var args = (parameter as ScheduledTaskExecutorParameter).Args; + var config = (parameter as Menu.ExecutorParameter).GetConfig(); + var args = (parameter as Menu.ExecutorParameter).Args; - var selectedtaskindexes = CommandLine.GetCommandLineArgument(args, "-TASKS"); + var selectedtaskindexes = CommandLine.GetCommandLineArgument(args, CLP.Module.ScheduledTaskManager.Function.CMD_TASKS); - var menufolders = DisplayTasks(config, $"Select the scheduled task(s) to manage with function '{nameof(End)}'!"); + var menufolders = DisplayScheduledTaskMenu(config, $"Select the scheduled task(s) to manage with function '{nameof(End)}'!", silent: true); Menu.Selection sr = menufolders.Select(selectedtaskindexes); if (sr.Result == Menu.SelectionResult.Exit) { return o; } @@ -168,7 +152,7 @@ namespace Vrh.Log4Pro.MaintenanceConsole else { } foreach (var p in sr.SelectedParameterList) { - ScheduledTask st = p as ScheduledTask; + ScheduledTask st = p.Parameters as ScheduledTask; try { ScheduledTaskManagerCore.EndTask(st.Xml_Name); @@ -180,12 +164,12 @@ namespace Vrh.Log4Pro.MaintenanceConsole } private static object Run(object parameter, object o) { - var config = (parameter as ScheduledTaskExecutorParameter).Config; - var args = (parameter as ScheduledTaskExecutorParameter).Args; + var config = (parameter as Menu.ExecutorParameter).GetConfig(); + var args = (parameter as Menu.ExecutorParameter).Args; - var selectedtaskindexes = CommandLine.GetCommandLineArgument(args, "-TASKS"); + var selectedtaskindexes = CommandLine.GetCommandLineArgument(args, CLP.Module.ScheduledTaskManager.Function.CMD_TASKS); - var menufolders = DisplayTasks(config, $"Select the scheduled task(s) to manage with function '{nameof(Run)}'!"); + var menufolders = DisplayScheduledTaskMenu(config, $"Select the scheduled task(s) to manage with function '{nameof(Run)}'!", silent: true); Menu.Selection sr = menufolders.Select(selectedtaskindexes); if (sr.Result == Menu.SelectionResult.Exit) { return o; } @@ -195,7 +179,7 @@ namespace Vrh.Log4Pro.MaintenanceConsole else { } foreach (var p in sr.SelectedParameterList) { - ScheduledTask st = p as ScheduledTask; + ScheduledTask st = p.Parameters as ScheduledTask; try { ScheduledTaskManagerCore.RunTask(st.Xml_Name); @@ -210,12 +194,12 @@ namespace Vrh.Log4Pro.MaintenanceConsole } private static object Uninstall(object parameter, object o) { - var config = (parameter as ScheduledTaskExecutorParameter).Config; - var args = (parameter as ScheduledTaskExecutorParameter).Args; + var config = (parameter as Menu.ExecutorParameter).GetConfig(); + var args = (parameter as Menu.ExecutorParameter).Args; - var selectedtaskindexes = CommandLine.GetCommandLineArgument(args, "-TASKS"); + var selectedtaskindexes = CommandLine.GetCommandLineArgument(args, CLP.Module.ScheduledTaskManager.Function.CMD_TASKS); - var menufolders = DisplayTasks(config, $"Select the scheduled task(s) to manage with function '{nameof(Uninstall)}'!"); + var menufolders = DisplayScheduledTaskMenu(config, $"Select the scheduled task(s) to manage with function '{nameof(Uninstall)}'!", silent: true); Menu.Selection sr = menufolders.Select(selectedtaskindexes); if (sr.Result == Menu.SelectionResult.Exit) { return o; } @@ -225,7 +209,7 @@ namespace Vrh.Log4Pro.MaintenanceConsole else { } foreach (var p in sr.SelectedParameterList) { - ScheduledTask st = p as ScheduledTask; + ScheduledTask st = p.Parameters as ScheduledTask; try { ScheduledTaskManagerCore.EndTask(st.Xml_Name); @@ -238,12 +222,12 @@ namespace Vrh.Log4Pro.MaintenanceConsole } private static object Install(object parameter, object o) { - var config = (parameter as ScheduledTaskExecutorParameter).Config; - var args = (parameter as ScheduledTaskExecutorParameter).Args; + var config = (parameter as Menu.ExecutorParameter).GetConfig(); + var args = (parameter as Menu.ExecutorParameter).Args; - var selectedtaskindexes = CommandLine.GetCommandLineArgument(args, "-TASKS"); + var selectedtaskindexes = CommandLine.GetCommandLineArgument(args, CLP.Module.ScheduledTaskManager.Function.CMD_TASKS); - var menufolders = DisplayTasks(config, $"Select the scheduled task(s) to manage with function '{nameof(Install)}'!"); + var menufolders = DisplayScheduledTaskMenu(config, $"Select the scheduled task(s) to manage with function '{nameof(Install)}'!", silent: true); Menu.Selection sr = menufolders.Select(selectedtaskindexes); if (sr.Result == Menu.SelectionResult.Exit) { return o; } @@ -253,7 +237,7 @@ namespace Vrh.Log4Pro.MaintenanceConsole else { } foreach (var p in sr.SelectedParameterList) { - ScheduledTask st = p as ScheduledTask; + ScheduledTask st = p.Parameters as ScheduledTask; try { ScheduledTaskManagerCore.EndTask(st.Xml_Name); @@ -269,27 +253,28 @@ namespace Vrh.Log4Pro.MaintenanceConsole #region private methods #region private DisplayTasks - private static Menu DisplayTasks(ScheduledTaskManagerCoreXmlProcessor config,string prompt = null) + private static void ScheduledTaskListDisplayer() { DisplayScheduledTaskMenu(); } + private static Menu DisplayScheduledTaskMenu(ScheduledTaskManagerXmlProcessor config = null, string prompt = null, bool silent = false) { + if (config == null) { config = new ScheduledTaskManagerXmlProcessor(XMLCONNECTIONSTRING, "", "hu-HU"); } List schtskdefList = config.GetDefinitionList(); - var menufct = new Menu("Scheduled tasks",prompt) + var menufct = new Menu("Scheduled tasks", prompt) .SetMenuItemDisplayer(DisplayTaskInfo) - .SetSelectionMode(Menu.SelectionMode.Multi) - .SetHeaderWidth(4); + .SetSelectionMode(Menu.SelectionMode.Multi); menufct.ClearMenuItemList(); foreach (var schtskdef in schtskdefList) { - var st = CollectTaskInfo(schtskdef); - menufct.AddMenuItem(new Menu.Item(null, null, null, st)); + var st = ScheduledTaskManagerCore.CollectTaskInfo(schtskdef); + menufct.AddMenuItem(new Menu.Item(schtskdef.Xml_Key, null, null, new Menu.ExecutorParameter(pars: st))); } - menufct.DisplayItems(1); + if (!silent) { menufct.DisplayItems(1); } return menufct; } #endregion private DisplayTasks #region private method: DisplayTaskInfo private static object DisplayTaskInfo(object obj, int lineix) { - ScheduledTask st = obj as ScheduledTask; + ScheduledTask st = (obj as Menu.ExecutorParameter).Parameters as ScheduledTask; if (lineix == 0) { ColorConsole.Write($"{st.Xml_Name}", ConsoleColor.Black, ConsoleColor.White); @@ -316,8 +301,15 @@ namespace Vrh.Log4Pro.MaintenanceConsole return null; } #endregion private method: DisplayTaskInfo - #region private CollectTaskInfo - private static ScheduledTask CollectTaskInfo(ScheduledTask schtsk) + #endregion private methods + } + #endregion ScheduledTaskManager class + + #region class ScheduledTaskManagerCore + public static class ScheduledTaskManagerCore + { + #region public CollectTaskInfo + public static ScheduledTask CollectTaskInfo(ScheduledTask schtsk) { string status = Tools.ExecuteAndGetStdIo("schtasks.exe", $"/Query /FO TABLE /TN {schtsk.Xml_Name}"); @@ -326,7 +318,7 @@ namespace Vrh.Log4Pro.MaintenanceConsole var statuslines = status.Split(new string[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries); var statussplitted = statuslines[3] .Split(new string[] { " ", "+" }, StringSplitOptions.RemoveEmptyEntries); - if (statussplitted[1]=="N/A") + if (statussplitted[1] == "N/A") { schtsk.NextRun = ""; schtsk.Priority = -1; @@ -354,14 +346,8 @@ namespace Vrh.Log4Pro.MaintenanceConsole } return schtsk; } - #endregion private CollectTaskInfo - #endregion private methods - } - #endregion ScheduledTaskManager class + #endregion public CollectTaskInfo - #region class ScheduledTaskManagerCore - public static class ScheduledTaskManagerCore - { public static int GetPriority(string taskname) { try @@ -409,7 +395,7 @@ namespace Vrh.Log4Pro.MaintenanceConsole public static void CreateTask(ScheduledTask st) { string taskname = st.Xml_Name; - string tasktorunpars = st.Xml_Commandname; + string tasktorunpars = st.Xml_Commandname.Quote(); string schedulepars = ""; if (st.Xml_Schedule==nameof(ScheduledTask.XmlStructure.ScheduledTask.Attributes.Schedule.Values.MONTHLY)) { schedulepars += "/SC MONTHLY /D 1"; } @@ -424,6 +410,7 @@ namespace Vrh.Log4Pro.MaintenanceConsole string prioritypars = "/RL HIGHEST"; var args = $"/Create /TR {tasktorunpars} {schedulepars} {starttimepars} {passwordpars} {forcecreatepars} {prioritypars} /TN {taskname}"; + var result = Tools.ExecuteAndGetStdIo("schtasks.exe", args); if (st.Xml_Enable) { EnableTask(taskname); } else { DisableTask(taskname); } @@ -433,11 +420,11 @@ namespace Vrh.Log4Pro.MaintenanceConsole #endregion class ScheduledTaskManagerCore #region ScheduledTaskManagerCoreXmlProcessor class - public class ScheduledTaskManagerCoreXmlProcessor : XmlParser + public class ScheduledTaskManagerXmlProcessor : XmlParser { private List _scheduledtasklist; #region constructor - public ScheduledTaskManagerCoreXmlProcessor(string xmlcs, string basefolder, string lcid) : base(xmlcs, basefolder, lcid, null) + public ScheduledTaskManagerXmlProcessor(string xmlcs, string basefolder, string lcid) : base(xmlcs, basefolder, lcid, null) { _scheduledtasklist = new List(); var schtskxmllist = GetAllXElements(nameof(ScheduledTask.XmlStructure.ScheduledTask)); @@ -458,6 +445,7 @@ namespace Vrh.Log4Pro.MaintenanceConsole { #region fields public bool Valid = true; + public string Xml_Key; public string Xml_Name; public int Xml_Priority; public string Xml_Schedule; @@ -495,6 +483,7 @@ namespace Vrh.Log4Pro.MaintenanceConsole { Valid = true; string ATTRIBUTEMANDATORY = nameof(XmlStructure.ScheduledTask) + " attribute is mandatory! Name: {0}"; + Xml_Key= GetValue(nameof(XmlStructure.ScheduledTask.Attributes.Key), scheduledtaskxml, XmlStructure.ScheduledTask.Attributes.Key.Values.DEFAULT); Xml_Name = scheduledtaskxml.Attribute(XName.Get(nameof(XmlStructure.ScheduledTask.Attributes.Name)))?.Value; if (string.IsNullOrWhiteSpace(Xml_Name)) { throw new ApplicationException(string.Format(ATTRIBUTEMANDATORY, nameof(XmlStructure.ScheduledTask.Attributes.Name))); } Xml_Priority = GetValue(nameof(XmlStructure.ScheduledTask.Attributes.Priority), scheduledtaskxml, XmlStructure.ScheduledTask.Attributes.Priority.Values.DEFAULT); @@ -502,7 +491,7 @@ namespace Vrh.Log4Pro.MaintenanceConsole Xml_StartTime = DateTime.Parse(GetValue(nameof(XmlStructure.ScheduledTask.Attributes.StartTime), scheduledtaskxml, XmlStructure.ScheduledTask.Attributes.StartTime.Values.DEFAULT)); Xml_Enable = GetValue(nameof(XmlStructure.ScheduledTask.Attributes.Enable), scheduledtaskxml, XmlStructure.ScheduledTask.Attributes.Enable.Values.DEFAULT); Xml_Run = GetValue(nameof(XmlStructure.ScheduledTask.Attributes.Run), scheduledtaskxml, XmlStructure.ScheduledTask.Attributes.Run.Values.DEFAULT); - Xml_Commandname = GetValue(nameof(XmlStructure.ScheduledTask.Attributes.Commandname), scheduledtaskxml, ""); + Xml_Commandname = GetValue(nameof(XmlStructure.ScheduledTask.Attributes.Command), scheduledtaskxml, ""); //var conditionxmlList = GetAllXElements(foldertocleanxml, nameof(XmlStructure.FolderToClean.Conditions), nameof(XmlStructure.FolderToClean.Conditions.Condition)); } #endregion xml constructor @@ -510,6 +499,7 @@ namespace Vrh.Log4Pro.MaintenanceConsole public ScheduledTask(ScheduledTask ftc) { Valid = ftc.Valid; + Xml_Key= ftc.Xml_Key; Xml_Name = ftc.Xml_Name; Xml_Priority = ftc.Xml_Priority; Xml_Schedule = ftc.Xml_Schedule; @@ -526,14 +516,9 @@ namespace Vrh.Log4Pro.MaintenanceConsole { public static class Attributes { + public static class Key { public static class Values { public const string DEFAULT = ""; } } public static class Name { } - public static class StartTime - { - public static class Values - { - public const string DEFAULT = "04:00"; - } - } + public static class StartTime { public static class Values { public const string DEFAULT = "04:00"; } } public static class Priority { public static class Values @@ -567,7 +552,7 @@ namespace Vrh.Log4Pro.MaintenanceConsole public const bool DEFAULT = false; } } - public static class Commandname { } + public static class Command { } } } } diff --git a/Vrh.Log4Pro.MaintenanceConsole/Manager - UserManager.cs b/Vrh.Log4Pro.MaintenanceConsole/Manager - UserManager.cs new file mode 100644 index 0000000..dedbb82 --- /dev/null +++ b/Vrh.Log4Pro.MaintenanceConsole/Manager - UserManager.cs @@ -0,0 +1,236 @@ +using System; +using System.IO; +using System.Configuration.Install; +using System.Collections.Generic; +using System.Linq; +using System.ServiceProcess; +using System.Text; +using System.Threading; +using System.Threading.Tasks; + +using Microsoft.Web.Administration; +using System.Management; +using System.Diagnostics; + +using Vrh.Log4Pro.MaintenanceConsole.MenuNS; +using Vrh.Log4Pro.MaintenanceConsole.ColorConsoleNS; +using Vrh.Log4Pro.MaintenanceConsole.CommandLineParserNS; +using Vrh.Log4Pro.MaintenanceConsole.ToolsNS; + +using Vrh.XmlProcessing; +using System.Xml.Linq; +using System.Text.RegularExpressions; + +namespace Vrh.Log4Pro.MaintenanceConsole.UserManagerNS +{ + #region MaintenanceTools class + public static class UserManager + { + private static Log4ProUserManagerXmlProcessor Config; + private const string XMLCONNECTIONSTRING = "config=MAINTENANCECONSOLE_LOG4PROUSERMANAGER;"; + private const string XMLCONNECTIONSTRING_DEFAULT = "file=Config.Xml;element=Log4ProUserManager;"; + + #region Execute + public static object Execute(object o1 = null, object o2 = null) + { + var args = (o1 as Menu.ExecutorParameter).Args; + string xmlcs = XMLCONNECTIONSTRING; + var config = new Log4ProUserManagerXmlProcessor(xmlcs, "", "hu-HU"); + Config = config; + var sqlcs = XmlProcessing.ConnectionStringStore.GetSQL(config.Xml_SQLConnectionString); + MembershipTools.SetConnectionString(sqlcs); + + var menufunctions = new Menu("Log4Pro User Manager", "Select function!") + .AddMenuItem(new Menu.Item(CLP.Module.Log4ProUserManager.Functions.CreateSuperuser.KEY, "Create superuser", CreateSuperuser, new Menu.ExecutorParameter(cfg: config))) + .AddMenuItem(new Menu.Item(CLP.Module.Log4ProUserManager.Functions.CreateAdminusers.KEY, "Create Admin and Administrator roles and users", CreateAdminusers, new Menu.ExecutorParameter(cfg: config, null))) + .AddMenuItem(new Menu.Item(CLP.Module.Log4ProUserManager.Functions.DeleteUsers.KEY, "Remove user", DeleteUsers, new Menu.ExecutorParameter(cfg: config, null))) + .SetMenuHeaderDisplayer(UserListDisplayer) + .SetSelectionMode(Menu.SelectionMode.Single); + menufunctions.ExecuteMenu(); + return null; + } + #endregion Execute + #region private UserListDisplayer + private static void UserListDisplayer() + { + int totallinelength = 0; + ColorConsole.Write("", ConsoleColor.Yellow, prefix: "Usernames:"); + foreach (var un in MembershipTools.Users.GetNameList(null)) + { + var predefined = Config.ProtectedUser(un); + totallinelength += un.Length + (predefined?3:2); + if (totallinelength > ColorConsole.BufferWidth) { ColorConsole.WriteLine(""); } + ColorConsole.Write("["); + if (predefined) { ColorConsole.Write("*", ConsoleColor.Red); } + ColorConsole.Write(un, ConsoleColor.Yellow); + ColorConsole.Write("]"); + } + ColorConsole.WriteLine(""); + } + #endregion private UserListDisplayer + + #region First level Executors with UI + #region CreateSuperuser + private static object CreateSuperuser(object parameter, object o) + { + var config = (parameter as Menu.ExecutorParameter).GetConfig(); + var suname = ColorConsole.ReadLine($"Enter Superuser name:", ConsoleColor.Yellow); + if (suname == "EX") { return null; } + var supsw = ColorConsole.ReadLine($"Enter Superuser password:", ConsoleColor.Yellow); + if (supsw == "EX") { return null; } + + try + { + MembershipTools.Users.Create(suname, supsw, superuser: true); + ColorConsole.WriteLine($"Creating superuser '{suname}' was successful!", ConsoleColor.Green); + } + catch (Exception ex) { ColorConsole.WriteLine(ex.Message, ConsoleColor.Red); } + return o; + } + #endregion CreateSuperuser + #region CreateAdminusers + private static object CreateAdminusers(object parameter, object o) + { + var config = (parameter as Menu.ExecutorParameter).GetConfig(); + try + { + MembershipTools.Users.CreateAdminRolesAndUsers(); + ColorConsole.WriteLine($"Creating admin users was successful!", ConsoleColor.Green); + } + catch (Exception ex) { ColorConsole.WriteLine(ex.Message, ConsoleColor.Red); } + return o; + } + #endregion CreateAdminusers + #region DeleteUsers + private static object DeleteUsers(object parameter, object o) + { + var config = (parameter as Menu.ExecutorParameter).GetConfig(); + var uname = ColorConsole.ReadLine($"Enter username:", ConsoleColor.Yellow); + if (uname == "EX") { return null; } + + try + { + if (!config.ProtectedUser(uname)) + { + MembershipTools.Users.Remove(uname); + ColorConsole.WriteLine($"Deleting user '{uname}' was successwful!", ConsoleColor.Green); + } + else { throw new Exception($"User '{uname}' is protected, can not be deleted!"); } + } + catch (Exception ex) { ColorConsole.WriteLine(ex.Message, ConsoleColor.Red); } + return o; + } + #endregion DeleteUsers + #endregion First level Executors with UI + } + #endregion MaintenanceTools class + #region MaintenanceToolsXmlProcessor class + public class Log4ProUserManagerXmlProcessor : XmlParser + { + #region fields + public string Xml_SQLConnectionString; + public string Xml_ProtectedUserNameCommaList; + public List UserGroupList; + public List ProtectedUserNameList; + #endregion fields + #region constructor + public Log4ProUserManagerXmlProcessor(string xmlcs, string basefolder, string lcid) : base(xmlcs, basefolder, lcid, null) + { + Xml_SQLConnectionString = RootElement.Attribute(XName.Get(nameof(XmlStructure.Attributes.SQLConnectionString)))?.Value; + if (string.IsNullOrEmpty(Xml_SQLConnectionString)) { Xml_SQLConnectionString = XmlStructure.Attributes.SQLConnectionString.Values.DEFAULT; } + + Xml_ProtectedUserNameCommaList = RootElement.Attribute(XName.Get(nameof(XmlStructure.Attributes.ProtectedUsernameList)))?.Value; + if (string.IsNullOrEmpty(Xml_ProtectedUserNameCommaList)) { Xml_ProtectedUserNameCommaList = XmlStructure.Attributes.ProtectedUsernameList.Values.DEFAULT; } + ProtectedUserNameList = Xml_ProtectedUserNameCommaList.Split(',').ToList(); + UserGroupList = new List(); + var ugxmllist = RootElement.Element(XName.Get(nameof(XmlStructure.UserGroups))).Elements(XName.Get(nameof(XmlStructure.UserGroups.UserGroup))); + if (ugxmllist!=null && ugxmllist.Any()) + { + foreach (var ugxml in ugxmllist) + { + UserGroupList.Add(new UserGroup(ugxml)); + }; + } + } + #region ProtectedUser + /// + /// Igazzal tésr vissza, ha a user benne van a protected listában + /// + /// + /// + public bool ProtectedUser(string uname) + { + return ProtectedUserNameList.Select(un=>un.ToUpper()).Contains(uname.ToUpper()); + } + #endregion ProtectedUser + #endregion constructor + #region XmlStructure + public static class XmlStructure + { + public static class Attributes + { + public static class SQLConnectionString { public static class Values { public const string DEFAULT = ""; } } + public static class ProtectedUsernameList { public static class Values { public const string DEFAULT = "Admin,Administrator"; } } + + } + public static class UserGroups + { + public static class UserGroup + { + public static class Values + { + public const string DEFAULT = ".*"; + } + public static class Attributes + { + public static class Id {} + public static class DisplayName {} + public static class GroupType + { + public static class Values + { + public const UserGroupType DEFAULT = UserGroupType.UserName; + } + } + } + + } + public static class Values { public const string DEFAULT = "Admin,Administrator"; } + } + } + #endregion XmlStructure + #region UserGroup + public class UserGroup:XmlLinqBase + { + public UserGroup() { } + public UserGroup(XElement ugxml) + { + Id = ugxml.Attribute(XName.Get(nameof(XmlStructure.UserGroups.UserGroup.Attributes.Id)))?.Value; + if (string.IsNullOrEmpty(Id)) { throw new Exception ($"Attribute is mandatory! Name {nameof(XmlStructure.UserGroups.UserGroup.Attributes.Id)}."); } + + Displayname = ugxml.Attribute(XName.Get(nameof(XmlStructure.UserGroups.UserGroup.Attributes.DisplayName)))?.Value; + if (string.IsNullOrEmpty(Displayname)) { Displayname = Id; } + + string grouptypestring = ugxml.Attribute(XName.Get(nameof(XmlStructure.UserGroups.UserGroup.Attributes.GroupType)))?.Value; + if (string.IsNullOrEmpty(grouptypestring)) { GroupType = XmlStructure.UserGroups.UserGroup.Attributes.GroupType.Values.DEFAULT; } + else + { + try { GroupType = (UserGroupType)Enum.Parse(typeof(UserGroupType), grouptypestring); } + catch { throw new Exception($"Attribute value is incorrect! Name {nameof(XmlStructure.UserGroups.UserGroup.Attributes.GroupType)}, Value: {grouptypestring}."); } + } + + Regex = ugxml.Value; + if (Regex==null) { Regex = XmlStructure.UserGroups.UserGroup.Values.DEFAULT; } + } + public UserGroup(UserGroup ug) { Id = ug.Id;Displayname = ug.Displayname;GroupType = ug.GroupType;Regex = ug.Regex; } + public string Id; + public string Displayname; + public UserGroupType GroupType; + public string Regex; + } + public enum UserGroupType { RoleName,RoleGroupName,UserName,} + + #endregion UserGroup + } + #endregion MaintenanceToolsXmlProcessor class +} diff --git a/Vrh.Log4Pro.MaintenanceConsole/Manager - WebApplicationManager.cs b/Vrh.Log4Pro.MaintenanceConsole/Manager - WebApplicationManager.cs index b5cff1b..f3c0ee7 100644 --- a/Vrh.Log4Pro.MaintenanceConsole/Manager - WebApplicationManager.cs +++ b/Vrh.Log4Pro.MaintenanceConsole/Manager - WebApplicationManager.cs @@ -10,160 +10,118 @@ using Microsoft.Web.Administration; using System.Management; using System.Diagnostics; +using Vrh.Log4Pro.MaintenanceConsole.CommandLineParserNS; +using Vrh.Log4Pro.MaintenanceConsole.MenuNS; +using Vrh.Log4Pro.MaintenanceConsole.ColorConsoleNS; + using Vrh.XmlProcessing; +using VRH.Common; using System.Xml.Linq; -namespace Vrh.Log4Pro.MaintenanceConsole +namespace Vrh.Log4Pro.MaintenanceConsole.WebApplicationManagerNS { #region WebApplicationManager public static class WebApplicationManager { + private const string XMLCONNECTIONSTRING = "config=MAINTENANCECONSOLE_WEBAPPLICATIONMANAGER;"; + private const string XMLCONNECTIONSTRING_DEFAULT = "file=Config.Xml;element=WebApplications;"; + #region public method: Execute public static object Execute(object o1=null,object o2=null) { - string xmlcs = "file=Config.xml;element=WebApplications;"; - var config = new WebApplicationManagerXmlProcessor(xmlcs, "", "hu-HU"); + var args = (o1 as Menu.ExecutorParameter).Args; + var functionkey = CommandLine.GetCommandLineArgument(args, CLP.CMD_FUNCTION); + var config = new WebApplicationManagerXmlProcessor(XMLCONNECTIONSTRING, "", "hu-HU"); + var ep = new Menu.ExecutorParameter(config, args); var menufunctions = new Menu("Manage Web Applications","Select the management function!") - .AddMenuItem(new Menu.Item("WAR", "Register WebApplication",Register)) - .AddMenuItem(new Menu.Item("WAU", "Unregister WebApplication",Unregister)) - .AddMenuItem(new Menu.Item("WAI", "Set impersonate identity",SetImpersonateIdentity)) - .AddMenuItem(new Menu.Item("APS", "Start application Pool",PoolStart)) - .AddMenuItem(new Menu.Item("APF", "Stop application Pool",PoolStop)) - .AddMenuItem(new Menu.Item("APR", "Recycle application Pool",PoolRecycle)) - .AddMenuItem(new Menu.Item("WSS", "Start website",SiteStart)) - .AddMenuItem(new Menu.Item("WSF", "Stop website",SiteStop)) - .AddMenuItem(new Menu.Item("APU", "Set pool user account",PoolSetUserAccount)) - .AddMenuItem(new Menu.Item("R", "Restart website and pool",Restart)) - .SetSelectionMode(Menu.SelectionMode.Single); - - var menuapplications = new Menu("Web applications","Select the web application(s) to manage!") - .SetMenuItemDisplayer(DisplayWebAppInfo) - .SetSelectionMode(Menu.SelectionMode.Multi) - .SetHeaderWidth(4); - - while (true) - { - List wadefList = config.GetDefinitionList(); - Menu.Selection sr; - using (ServerManager sm = new ServerManager()) - { - var sites = sm.Sites; - var pools = sm.ApplicationPools; - menufunctions.DisplayTitle(); + .AddMenuItem(new Menu.Item(CLP.Module.WebApplicationManager.Function.Register.KEY, "Register WebApplication",Register,ep)) + .AddMenuItem(new Menu.Item(CLP.Module.WebApplicationManager.Function.Unregister.KEY, "Unregister WebApplication",Unregister, ep)) + .AddMenuItem(new Menu.Item(CLP.Module.WebApplicationManager.Function.SetImpersonateIdentity.KEY, "Set impersonate identity",SetImpersonateIdentity, ep)) + .AddMenuItem(new Menu.Item(CLP.Module.WebApplicationManager.Function.PoolStart.KEY, "Start application Pool",PoolStart, ep)) + .AddMenuItem(new Menu.Item(CLP.Module.WebApplicationManager.Function.PoolStop.KEY, "Stop application Pool",PoolStop, ep)) + .AddMenuItem(new Menu.Item(CLP.Module.WebApplicationManager.Function.PoolRecycle.KEY, "Recycle application Pool",PoolRecycle, ep)) + .AddMenuItem(new Menu.Item(CLP.Module.WebApplicationManager.Function.SiteStart.KEY, "Start website",SiteStart, ep)) + .AddMenuItem(new Menu.Item(CLP.Module.WebApplicationManager.Function.SiteStop.KEY, "Stop website",SiteStop, ep)) + .AddMenuItem(new Menu.Item(CLP.Module.WebApplicationManager.Function.PoolSetUserAccount.KEY, "Set pool user account",PoolSetUserAccount, ep)) + .AddMenuItem(new Menu.Item(CLP.Module.WebApplicationManager.Function.Restart.KEY, "Restart website and pool",Restart, ep)) + .SetSelectionMode(Menu.SelectionMode.Single) + .SetMenuHeaderDisplayer(WebApplicationListDisplayer); - menuapplications.ClearMenuItemList(); - foreach (var wadef in wadefList) - { - var w = WebApplicationManagerCore.CollectWebAppInfo(sites, pools, wadef); - menuapplications.AddMenuItem(new Menu.Item(null, null, null, w)); - } - } - menuapplications.DisplayItems(1); - - menufunctions.DisplayItems(3,35); - sr = menufunctions.Select(); - if (sr.Result == Menu.SelectionResult.Exit) { break; } - else if (sr.Result == Menu.SelectionResult.None) { continue; } - else if (sr.Result == Menu.SelectionResult.Error) { continue; } - var functionexecutor = menufunctions.GetExecutor(sr.SelectedKeyList.First()); - - foreach (var mi in menuapplications.MenuItemList) { mi.Executor=functionexecutor; } - - sr = menuapplications.Select(); - if (sr.Result == Menu.SelectionResult.Exit) { break; } - else if (sr.Result == Menu.SelectionResult.None) { continue; } - else if (sr.Result == Menu.SelectionResult.Error) { continue; } - else if (sr.Result == Menu.SelectionResult.Ok) { } - else { } - menuapplications.ExecuteSelection(sr.SelectedKeyList); - } - return null; + menufunctions.ExecuteMenu(functionkey); + return o2; } #endregion public method: Execute - #region private method: DisplayWebAppInfo - private static object DisplayWebAppInfo(object waobj,int lineix) + + #region private DisplayWebApplicationMenu + private static void WebApplicationListDisplayer() { DisplayWebApplicationMenu(); } + private static Menu DisplayWebApplicationMenu(WebApplicationManagerXmlProcessor config= null, string prompt = null, bool silent=false) { - WebApplication wa = waobj as WebApplication; - if (lineix==0) - { - ColorConsole.WriteLine($"{wa.Xml_Description}", ConsoleColor.Black, ConsoleColor.White); - } - else if (lineix == 1) - { - ColorConsole.Write($"Web app:"); - ColorConsole.Write($"{wa.Xml_AppName}", ConsoleColor.Cyan); - var fc2 = wa.ApplicationState.Contains("Unregistered") ? ConsoleColor.Red : ConsoleColor.Green; - ColorConsole.Write($"{wa.ApplicationState}", fc2, bracket: "()"); - ColorConsole.Write($", Log.path:"); - ColorConsole.Write($"{wa.ApplicationPath}", ConsoleColor.White); - ColorConsole.Write($", Phy.path:"); - ColorConsole.WriteLine($"{wa.Xml_AppPhysicalPath}", ConsoleColor.White); - } - else if (lineix == 2) - { - ColorConsole.Write($"impersonate identity:"); - ColorConsole.WriteLine($"{wa.AppImpersonateIdentity}", ConsoleColor.White); - } - else if (lineix == 3) - { - ColorConsole.Write($"Site:"); - ColorConsole.Write($"{wa.Xml_SiteName}", ConsoleColor.Cyan); - var fc0 = - wa.SiteState.Contains("Started") ? ConsoleColor.Green - : wa.SiteState.Contains("Unregistered") ? ConsoleColor.Red - : ConsoleColor.Yellow; - ColorConsole.Write($"{wa.SiteState}", fc0, bracket: "()"); - ColorConsole.Write($", Ports:"); - ColorConsole.Write($"{wa.SitePortList}", ConsoleColor.White); - ColorConsole.Write($", Phy.path:"); - ColorConsole.WriteLine($"{wa.Xml_SitePhysicalPath}", ConsoleColor.White); - } - else if (lineix == 4) - { - ColorConsole.Write($"Pool:"); - ColorConsole.Write($"{wa.Xml_PoolName}", ConsoleColor.Cyan); - var fc1 = wa.PoolState == null ? ConsoleColor.Red - : wa.PoolState.Contains("Started") ? ConsoleColor.Green - : wa.PoolState.Contains("Unregistered") ? ConsoleColor.Red - : ConsoleColor.Yellow; - string waps = wa.PoolState == null ? "Unregistered/Unknown" : wa.PoolState; - ColorConsole.Write($"{waps}", fc1, bracket: "()"); - ColorConsole.Write($", identity:"); - ColorConsole.WriteLine($"{wa.PoolAccount}", ConsoleColor.White); - } - else if (lineix==5) - { - ColorConsole.WriteLine(); - } - else + if (config == null) { config = new WebApplicationManagerXmlProcessor(XMLCONNECTIONSTRING, "", "hu-HU"); } + List wadefList = config.GetDefinitionList(); + var menuwa = new Menu("Web applications", prompt) + .SetMenuItemDisplayer(DisplayWebAppInfo) + .SetSelectionMode(Menu.SelectionMode.Multi); + menuwa.ClearMenuItemList(); + foreach (var wadef in wadefList) { - return null; + var wa = WebApplicationManagerCore.CollectWebAppInfo(wadef); + menuwa.AddMenuItem(new Menu.Item(wadef.Xml_Key, null, null, new Menu.ExecutorParameter(pars: wa))); } - return ""; + if (!silent) { menuwa.DisplayItems(1); } + return menuwa; } - #endregion private method: DisplayWebAppInfo - #region - private static object Restart(object dobj, object parameters) + #endregion private DisplayWebApplicationMenu + + #region 1st level Executors + private static object Restart(object parameters, object o) { - WebApplication d = dobj as WebApplication; - using (ServerManager sm = new ServerManager()) + var config = (parameters as Menu.ExecutorParameter).GetConfig(); + var args = (parameters as Menu.ExecutorParameter).Args; + var selectedwaindexes = CommandLine.GetCommandLineArgument(args, CLP.Module.WebApplicationManager.Function.CMD_WEBAPPS); + var menuwapps = DisplayWebApplicationMenu(config, "Select the web application(s) to manage!",silent:true); + Menu.Selection sr = menuwapps.Select(selectedwaindexes); + + if (sr.Result == Menu.SelectionResult.Exit) { return o; } + else if (sr.Result == Menu.SelectionResult.None) { return o; } + else if (sr.Result == Menu.SelectionResult.Error) { return o; } + else if (sr.Result == Menu.SelectionResult.Ok) { } + else { } + foreach (var p in sr.SelectedParameterList) { - try { WebApplicationManagerCore.GetPool(sm, d.Xml_PoolName)?.Stop(); } catch { ColorConsole.WriteLine($"Pool {d.Xml_PoolName} already stopped."); } - try { WebApplicationManagerCore.GetSite(sm, d.Xml_SiteName)?.Stop(); } catch { ColorConsole.WriteLine($"Site {d.Xml_SiteName} already stopped."); } + WebApplication wa = p.Parameters as WebApplication; + using (ServerManager sm = new ServerManager()) + { + try { WebApplicationManagerCore.GetPool(sm, wa.Xml_PoolName)?.Stop(); } catch { ColorConsole.WriteLine($"Pool {wa.Xml_PoolName} already stopped."); } + try { WebApplicationManagerCore.GetSite(sm, wa.Xml_SiteName)?.Stop(); } catch { ColorConsole.WriteLine($"Site {wa.Xml_SiteName} already stopped."); } - SiteStart(d, parameters); - PoolStart(d, parameters); - PoolRecycle(d, parameters); + SiteStart(wa, o); + PoolStart(wa, o); + PoolRecycle(wa, o); - ColorConsole.WriteLine($"Pool {d.Xml_PoolName} and site {d.Xml_SiteName} restarted."); - return parameters; + ColorConsole.WriteLine($"Pool {wa.Xml_PoolName} and site {wa.Xml_SiteName} restarted."); + } } + return o; + } + private static object PoolStart(object parameters, object o) + { + var config = (parameters as Menu.ExecutorParameter).GetConfig(); + var args = (parameters as Menu.ExecutorParameter).Args; + var selectedwaindexes = CommandLine.GetCommandLineArgument(args, CLP.Module.WebApplicationManager.Function.CMD_WEBAPPS); + var menuwapps = DisplayWebApplicationMenu(config, "Select the web application(s) to manage!", silent: true); + Menu.Selection sr = menuwapps.Select(selectedwaindexes); + + if (sr.Result == Menu.SelectionResult.Exit) { return o; } + else if (sr.Result == Menu.SelectionResult.None) { return o; } + else if (sr.Result == Menu.SelectionResult.Error) { return o; } + else if (sr.Result == Menu.SelectionResult.Ok) { } + else { } + foreach (var wa in sr.SelectedParameterList) { OnePoolStart(wa.Parameters as WebApplication); } + return o; } - private - static object PoolStart(object dobj, object parameters) + private static void OnePoolStart(WebApplication d) { - WebApplication d = dobj as WebApplication; using (ServerManager sm = new ServerManager()) { bool success = false; @@ -181,12 +139,26 @@ namespace Vrh.Log4Pro.MaintenanceConsole } var successstr = success ? "started" : "NOT started"; ColorConsole.WriteLine($"{d.Xml_PoolName} {successstr}."); - return parameters; } } - private static object PoolRecycle(object dobj, object parameters) + private static object PoolRecycle(object parameters, object o) + { + var config = (parameters as Menu.ExecutorParameter).GetConfig(); + var args = (parameters as Menu.ExecutorParameter).Args; + var selectedwaindexes = CommandLine.GetCommandLineArgument(args, CLP.Module.WebApplicationManager.Function.CMD_WEBAPPS); + var menuwapps = DisplayWebApplicationMenu(config, "Select the web application(s) to manage!", silent: true); + Menu.Selection sr = menuwapps.Select(selectedwaindexes); + + if (sr.Result == Menu.SelectionResult.Exit) { return o; } + else if (sr.Result == Menu.SelectionResult.None) { return o; } + else if (sr.Result == Menu.SelectionResult.Error) { return o; } + else if (sr.Result == Menu.SelectionResult.Ok) { } + else { } + foreach (var wa in sr.SelectedParameterList) { OnePoolRecycle(wa.Parameters as WebApplication); } + return o; + } + private static void OnePoolRecycle(WebApplication d) { - WebApplication d = dobj as WebApplication; using (ServerManager sm = new ServerManager()) { bool success = false; @@ -203,58 +175,100 @@ namespace Vrh.Log4Pro.MaintenanceConsole } var successstr = success ? "recycled" : "NOT recycled"; ColorConsole.WriteLine($"{d.Xml_PoolName} {successstr}."); - return parameters; } } - private static object PoolStop(object dobj, object parameters) + private static object PoolStop(object parameters, object o) + { + var config = (parameters as Menu.ExecutorParameter).GetConfig(); + var args = (parameters as Menu.ExecutorParameter).Args; + var selectedwaindexes = CommandLine.GetCommandLineArgument(args, CLP.Module.WebApplicationManager.Function.CMD_WEBAPPS); + var menuwapps = DisplayWebApplicationMenu(config, "Select the web application(s) to manage!", silent: true); + Menu.Selection sr = menuwapps.Select(selectedwaindexes); + + if (sr.Result == Menu.SelectionResult.Exit) { return o; } + else if (sr.Result == Menu.SelectionResult.None) { return o; } + else if (sr.Result == Menu.SelectionResult.Error) { return o; } + else if (sr.Result == Menu.SelectionResult.Ok) { } + else { } + foreach (var wa in sr.SelectedParameterList) { OnePoolStop(wa.Parameters as WebApplication); } + return o; + } + private static void OnePoolStop(WebApplication wa) { using (ServerManager sm = new ServerManager()) { - WebApplication d = dobj as WebApplication; bool success = false; for (var i = 1; i <= 10; i++) { - var p = WebApplicationManagerCore.GetPool(sm, d.Xml_PoolName); + var p = WebApplicationManagerCore.GetPool(sm, wa.Xml_PoolName); if (p != null && p.State == ObjectState.Started) { p.Stop(); success = true; break; } else { - ColorConsole.WriteLine($"Trying to stop pool {d.Xml_PoolName} ... Press key 'X' to exit..."); + ColorConsole.WriteLine($"Trying to stop pool {wa.Xml_PoolName} ... Press key 'X' to exit..."); if (ColorConsole.KeyAvailable) { if (ColorConsole.ReadKey().KeyChar.ToString().ToUpper() == "X") { break; } } Thread.Sleep(1000); } } var successstr = success ? "stopped" : "NOT stopped"; - ColorConsole.WriteLine($"{d.Xml_PoolName} {successstr}."); - return parameters; + ColorConsole.WriteLine($"{wa.Xml_PoolName} {successstr}."); } } - private static object SiteStart(object dobj, object parameters) + private static object SiteStart(object parameters, object o) { - WebApplication d = dobj as WebApplication; - using (ServerManager sm = new ServerManager()) + var config = (parameters as Menu.ExecutorParameter).GetConfig(); + var args = (parameters as Menu.ExecutorParameter).Args; + var selectedwaindexes = CommandLine.GetCommandLineArgument(args, CLP.Module.WebApplicationManager.Function.CMD_WEBAPPS); + var menuwapps = DisplayWebApplicationMenu(config, "Select the web application(s) to manage!", silent: true); + Menu.Selection sr = menuwapps.Select(selectedwaindexes); + + if (sr.Result == Menu.SelectionResult.Exit) { return o; } + else if (sr.Result == Menu.SelectionResult.None) { return o; } + else if (sr.Result == Menu.SelectionResult.Error) { return o; } + else if (sr.Result == Menu.SelectionResult.Ok) { } + else { } + foreach (var wa in sr.SelectedParameterList) { OneSiteStart(wa.Parameters as WebApplication); } + return o; + } + private static void OneSiteStart(WebApplication wa) + { + using (ServerManager sm = new ServerManager()) { bool success = false; for (var i = 1; i < 4; i++) { - var s = WebApplicationManagerCore.GetSite(sm, d.Xml_SiteName); + var s = WebApplicationManagerCore.GetSite(sm, wa.Xml_SiteName); if (s != null && s.State == ObjectState.Stopped) { s.Start(); success = true; break; } else { - ColorConsole.WriteLine($"Trying to start site {d.Xml_SiteName} ... Press key 'X' to exit..."); + ColorConsole.WriteLine($"Trying to start site {wa.Xml_SiteName} ... Press key 'X' to exit..."); if (ColorConsole.KeyAvailable) { if (ColorConsole.ReadKey().KeyChar.ToString().ToUpper() == "X") { break; } } Thread.Sleep(1000); } } var successstr = success ? "started" : "NOT started"; - ColorConsole.WriteLine($"{d.Xml_SiteName} {successstr}."); - return parameters; + ColorConsole.WriteLine($"{wa.Xml_SiteName} {successstr}."); } } - private static object SiteStop(object dobj, object parameters) + private static object SiteStop(object parameters, object o) { - WebApplication d = dobj as WebApplication; - using (ServerManager sm = new ServerManager()) + var config = (parameters as Menu.ExecutorParameter).GetConfig(); + var args = (parameters as Menu.ExecutorParameter).Args; + var selectedwaindexes = CommandLine.GetCommandLineArgument(args, CLP.Module.WebApplicationManager.Function.CMD_WEBAPPS); + var menuwapps = DisplayWebApplicationMenu(config, "Select the web application(s) to manage!", silent: true); + Menu.Selection sr = menuwapps.Select(selectedwaindexes); + + if (sr.Result == Menu.SelectionResult.Exit) { return o; } + else if (sr.Result == Menu.SelectionResult.None) { return o; } + else if (sr.Result == Menu.SelectionResult.Error) { return o; } + else if (sr.Result == Menu.SelectionResult.Ok) { } + else { } + foreach (var wa in sr.SelectedParameterList) { OneSiteStop(wa.Parameters as WebApplication); } + return o; + } + private static void OneSiteStop(WebApplication d) + { + using (ServerManager sm = new ServerManager()) { bool success = false; for (var i = 1; i < 4; i++) @@ -270,57 +284,120 @@ namespace Vrh.Log4Pro.MaintenanceConsole } var successstr = success ? "stopped" : "NOT stopped"; ColorConsole.WriteLine($"{d.Xml_SiteName} {successstr}."); - return parameters; } } - private static object Register(object dobj, object parameters) + private static object Register(object parameters, object o) { - WebApplication d = dobj as WebApplication; - WebApplicationManagerCore.RegisterWebApplication(d.Xml_SiteName, d.Xml_PoolName, d.Xml_AppName, d.Xml_AppPhysicalPath, d.Xml_SitePhysicalPath, 8080, d.Xml_RecreatePool, d.Xml_RecreateSite, d.Xml_RecreateApp, d.Xml_PoolPipeLineMode); - ColorConsole.WriteLine($"{d.Xml_AppName} is registered in site {d.Xml_SiteName} using pool {d.Xml_PoolName}."); - return parameters; + var config = (parameters as Menu.ExecutorParameter).GetConfig(); + var args = (parameters as Menu.ExecutorParameter).Args; + var selectedwaindexes = CommandLine.GetCommandLineArgument(args, CLP.Module.WebApplicationManager.Function.CMD_WEBAPPS); + var menuwapps = DisplayWebApplicationMenu(config, "Select the web application(s) to manage!", silent: true); + Menu.Selection sr = menuwapps.Select(selectedwaindexes); + + if (sr.Result == Menu.SelectionResult.Exit) { return o; } + else if (sr.Result == Menu.SelectionResult.None) { return o; } + else if (sr.Result == Menu.SelectionResult.Error) { return o; } + else if (sr.Result == Menu.SelectionResult.Ok) { } + else { } + foreach (var p in sr.SelectedParameterList) + { + WebApplication wa=p.Parameters as WebApplication; + WebApplicationManagerCore.RegisterWebApplication(wa.Xml_SiteName, wa.Xml_PoolName, wa.Xml_AppName, wa.Xml_AppPhysicalPath, wa.Xml_SitePhysicalPath, 8080, wa.Xml_RecreatePool, wa.Xml_RecreateSite, wa.Xml_RecreateApp, wa.Xml_PoolPipeLineMode); + ColorConsole.WriteLine($"{wa.Xml_AppName} is registered in site {wa.Xml_SiteName} using pool {wa.Xml_PoolName}."); + } + return o; + } + private static object Unregister(object parameters, object o) + { + var config = (parameters as Menu.ExecutorParameter).GetConfig(); + var args = (parameters as Menu.ExecutorParameter).Args; + var selectedwaindexes = CommandLine.GetCommandLineArgument(args, CLP.Module.WebApplicationManager.Function.CMD_WEBAPPS); + var menuwapps = DisplayWebApplicationMenu(config, "Select the web application(s) to manage!", silent: true); + Menu.Selection sr = menuwapps.Select(selectedwaindexes); + + if (sr.Result == Menu.SelectionResult.Exit) { return o; } + else if (sr.Result == Menu.SelectionResult.None) { return o; } + else if (sr.Result == Menu.SelectionResult.Error) { return o; } + else if (sr.Result == Menu.SelectionResult.Ok) { } + else { } + foreach (var p in sr.SelectedParameterList) + { + WebApplication wa = p.Parameters as WebApplication; + WebApplicationManagerCore.UnRegisterWebApplication(wa.Xml_AppName, wa.Xml_PoolName, wa.Xml_SiteName, wa.Xml_ForceRemovePool, wa.Xml_ForceRemoveSite); + ColorConsole.WriteLine($"{wa.Xml_AppName} is unregistered from site {wa.Xml_SiteName} and from pool {wa.Xml_PoolName}."); + } + return o; } - private static object Unregister(object dobj, object parameters) + private static object SetImpersonateIdentity(object parameters, object o) { - WebApplication d = dobj as WebApplication; - WebApplicationManagerCore.UnRegisterWebApplication(d.Xml_AppName, d.Xml_PoolName, d.Xml_SiteName, d.Xml_ForceRemovePool, d.Xml_ForceRemoveSite); - ColorConsole.WriteLine($"{d.Xml_AppName} is unregistered from site {d.Xml_SiteName} and from pool {d.Xml_PoolName}."); - return parameters; + var config = (parameters as Menu.ExecutorParameter).GetConfig(); + var args = (parameters as Menu.ExecutorParameter).Args; + var selectedwaindexes = CommandLine.GetCommandLineArgument(args, CLP.Module.WebApplicationManager.Function.CMD_WEBAPPS); + var menuwapps = DisplayWebApplicationMenu(config, "Select the web application(s) to manage!", silent: true); + Menu.Selection sr = menuwapps.Select(selectedwaindexes); + + if (sr.Result == Menu.SelectionResult.Exit) { return o; } + else if (sr.Result == Menu.SelectionResult.None) { return o; } + else if (sr.Result == Menu.SelectionResult.Error) { return o; } + else if (sr.Result == Menu.SelectionResult.Ok) { } + else { } + foreach (var p in sr.SelectedParameterList) + { + var wa = p.Parameters as WebApplication; + GetImpersonateInfo(wa, out string username, out string password, out string impersonate); + if (username == "EX" || password == "EX" || impersonate == "EX") { return o; } + string olduserinfo = WebApplicationManagerCore.GetCurrentImpersonateIdentityInfo(wa); + WebApplicationManagerCore.SetImpersonateIdentity(wa.Xml_ImpersonateIdentityConfigFile, impersonate, username, password); + ColorConsole.WriteLine($"Impersonate identity changed for webapp {wa.Xml_AppName}."); + ColorConsole.WriteLine($"From '{olduserinfo}' to '{WebApplicationManagerCore.GetCurrentImpersonateIdentityInfo(wa)}'"); + } + return o; } - private static object SetImpersonateIdentity(object dobj, object parameters) + private static void GetImpersonateInfo(WebApplication wa,out string username, out string password, out string impersonate) { - WebApplication d = dobj as WebApplication; - string username="", password = "",impersonate="FALSE"; - bool parametersarealreadyset = parameters != null; - string olduserinfo = WebApplicationManagerCore.GetImpersonateIdentityInfo(d.Xml_IdentityConfigFile); - if (parametersarealreadyset) + username = ""; password = ""; impersonate = bool.FalseString.ToUpper(); + if (Menu.IsCommandMode()) { - impersonate = ((Dictionary)parameters)["impersonate"]; - username = ((Dictionary)parameters)["username"]; - password = ((Dictionary)parameters)["password"]; + impersonate = wa.Xml_ImpersonateIdentity.ToString(); + username = wa.Xml_ImpersonateIdentityUsername; + password = wa.Xml_ImpersonateIdentityPassword; } else { - while(true) + string olduserinfo = WebApplicationManagerCore.GetCurrentImpersonateIdentityInfo(wa); + while (true) { - + var defaultinxml = WebApplicationManagerCore.GetDefaultImpersonateIdentityInfo(wa); ColorConsole.WriteLine($"Current user info: {olduserinfo}"); - ColorConsole.WriteLine("Set impersonate-on status (true/false), then [Enter], EX=exit."); + ColorConsole.WriteLine($"Set impersonate-on status (true/false).[Enter]=finish input.EX=exit"); + ColorConsole.WriteLine($"Empty in XML={defaultinxml}"); impersonate = ColorConsole.ReadLine().ToUpper(); - if (impersonate == "EX") { return null; } - else if (impersonate == "FALSE") { break; } - else if (impersonate == "TRUE") + if (impersonate == "EX") { return; } + else if (impersonate == "") + { + username = wa.Xml_ImpersonateIdentityUsername; + password = wa.Xml_ImpersonateIdentityPassword; + impersonate = wa.Xml_ImpersonateIdentity.ToString(); + return; + } + else if (impersonate == bool.FalseString.ToUpper()) + { + username = ""; + password = ""; + return; + } + else if (impersonate == bool.TrueString.ToUpper()) { - ColorConsole.WriteLine("Enter username, then [Enter]."); - var un = !string.IsNullOrWhiteSpace(d.Xml_PoolUsername) ? $"empty={d.Xml_PoolUsername }," : ""; - ColorConsole.WriteLine($"{un}EX=exit"); + ColorConsole.WriteLine($"Enter username.[Enter]=finish input.EX=exit"); + if (wa.Xml_ImpersonateIdentity) { ColorConsole.WriteLine(defaultinxml); } username = ColorConsole.ReadLine().ToUpper(); - if (impersonate == "EX") { return null; } - ColorConsole.WriteLine("Enter password, then [Enter]"); - var pw = !string.IsNullOrWhiteSpace(d.Xml_PoolPassword) ? $"empty={d.Xml_PoolPassword}," : ""; - ColorConsole.WriteLine($"{pw}EX=exit"); + if (username == "EX") { return; } + else if (wa.Xml_ImpersonateIdentity && username == "") + { + } + ColorConsole.WriteLine($"Enter password.[Enter]=finish input.Empty=no password.EX=exit"); password = ColorConsole.ReadLine().ToUpper(); - if (impersonate == "EX") { return null; } + if (password == "EX") { return; } break; //bool valid = System.Web.ApplicationSerices.AuthenticationService.ValidateUser(username, password, mull); } @@ -330,126 +407,209 @@ namespace Vrh.Log4Pro.MaintenanceConsole continue; } } - parameters = new Dictionary { { "impersonate", impersonate }, { "username", username }, { "password", password }, }; } - WebApplicationManagerCore.SetImpersonateIdentity(d.Xml_IdentityConfigFile, impersonate, username, password); - ColorConsole.WriteLine($"Impersonate identity changed for webapp {d.Xml_AppName}."); - ColorConsole.WriteLine($"From '{olduserinfo}' to '{WebApplicationManagerCore.GetImpersonateIdentityInfo(d.Xml_IdentityConfigFile)}'"); - - return parameters; } - private static object PoolSetUserAccount(object dobj, object parameters) + private static object PoolSetUserAccount(object parameters, object o) { - WebApplication d = dobj as WebApplication; - string username, password = ""; - bool parametersarealreadyset = parameters != null; - string olduserinfo = WebApplicationManagerCore.GetUserInfo(d.Xml_PoolName); - if (parametersarealreadyset) + var config = (parameters as Menu.ExecutorParameter).GetConfig(); + var args = (parameters as Menu.ExecutorParameter).Args; + var selectedwaindexes = CommandLine.GetCommandLineArgument(args, CLP.Module.WebApplicationManager.Function.CMD_WEBAPPS); + var menuwapps = DisplayWebApplicationMenu(config, "Select the web application(s) to manage!", silent: true); + Menu.Selection sr = menuwapps.Select(selectedwaindexes); + + if (sr.Result == Menu.SelectionResult.Exit) { return o; } + else if (sr.Result == Menu.SelectionResult.None) { return o; } + else if (sr.Result == Menu.SelectionResult.Error) { return o; } + else if (sr.Result == Menu.SelectionResult.Ok) { } + else { } + foreach (var p in sr.SelectedParameterList) { - username = ((Dictionary)parameters)["username"]; - password = ((Dictionary)parameters)["password"]; + var wa = p.Parameters as WebApplication; + GetPoolIdentityInfo(wa, out string username, out string password); + if (username == "EX" || password == "EX") { return o; } + string olduserinfo = WebApplicationManagerCore.GetCurrentPoolIdentityInfo(wa); + WebApplicationManagerCore.SetPoolUserAccount(wa.Xml_AppName, wa.Xml_SiteName, username, password); + ColorConsole.WriteLine($"Pool identity changed for webapp {wa.Xml_AppName}."); + ColorConsole.WriteLine($"From '{olduserinfo}' to '{WebApplicationManagerCore.GetCurrentPoolIdentityInfo(wa)}'"); + } + return o; + } + private static void GetPoolIdentityInfo(WebApplication wa, out string username, out string password) + { + username = ""; password = ""; + if (Menu.IsCommandMode()) + { + username = wa.Xml_PoolName; + password = wa.Xml_PoolPassword; } else { + var defaultinxml = WebApplicationManagerCore.GetDefaultPoolIdentityInfo(wa); + username=""; password = ""; + string olduserinfo = WebApplicationManagerCore.GetCurrentPoolIdentityInfo(wa); ColorConsole.WriteLine($"Current user info: {olduserinfo}"); - ColorConsole.WriteLine("Enter username, then [Enter]."); - ColorConsole.WriteLine("Special usernames are: (Empty=API) "); + var un = $"Empty from XML={defaultinxml}."; + ColorConsole.WriteLine($"Enter username.[Enter]=finish input.{un}EX=exit."); + ColorConsole.WriteLine("Special usernames are:"); ColorConsole.WriteLine($" (API) {nameof(ProcessModelIdentityType.ApplicationPoolIdentity)}"); ColorConsole.WriteLine($" (LSE) {nameof(ProcessModelIdentityType.LocalService)}"); ColorConsole.WriteLine($" (LSY) {nameof(ProcessModelIdentityType.LocalSystem)}"); ColorConsole.WriteLine($" (NSE) {nameof(ProcessModelIdentityType.NetworkService)}"); - ColorConsole.WriteLine(); - ColorConsole.Write(" (EX) ", ConsoleColor.Red); ColorConsole.WriteLine("Exit"); username = ColorConsole.ReadLine().ToUpper(); - if (username == "EX") { return null; } - if (string.IsNullOrEmpty(username)) { username = nameof(ProcessModelIdentityType.ApplicationPoolIdentity); }; - if (username == "API" || username == nameof(ProcessModelIdentityType.ApplicationPoolIdentity)) { username = nameof(ProcessModelIdentityType.ApplicationPoolIdentity); } + if (username == "EX") { return; } + else if (string.IsNullOrEmpty(username)) { username=wa.Xml_PoolUsername; password = wa.Xml_PoolPassword; } + else if (username == "API" || username == nameof(ProcessModelIdentityType.ApplicationPoolIdentity)) { username = nameof(ProcessModelIdentityType.ApplicationPoolIdentity); } else if (username == "LSE" || username == nameof(ProcessModelIdentityType.LocalService)) { username = nameof(ProcessModelIdentityType.LocalService); } else if (username == "LSY" || username == nameof(ProcessModelIdentityType.LocalSystem)) { username = nameof(ProcessModelIdentityType.LocalSystem); } else if (username == "NSE" || username == nameof(ProcessModelIdentityType.NetworkService)) { username = nameof(ProcessModelIdentityType.NetworkService); } else { - ColorConsole.WriteLine("Enter password, then [Enter]"); + ColorConsole.WriteLine("Enter password.[Enter]=finish input.Empty=no password.EX=exit"); password = ColorConsole.ReadLine().ToUpper(); //bool valid = System.Web.ApplicationSerices.AuthenticationService.ValidateUser(username, password, mull); } - parameters = new Dictionary { { "username", username }, { "password", password }, }; } - WebApplicationManagerCore.SetPoolUserAccount(d.Xml_AppName, d.Xml_SiteName, username, password); - ColorConsole.WriteLine($"Pool user changed from {olduserinfo} to {WebApplicationManagerCore.GetUserInfo(d.Xml_PoolName)} for pool {d.Xml_PoolName}."); - return parameters; } - #endregion + #endregion 1st level Executors + + #region private method: DisplayWebAppInfo + private static object DisplayWebAppInfo(object obj, int lineix) + { + WebApplication wa = (obj as Menu.ExecutorParameter).Parameters as WebApplication; + if (lineix == 0) + { + ColorConsole.WriteLine($"{wa.Xml_Description}", ConsoleColor.Black, ConsoleColor.White); + } + else if (lineix == 1) + { + ColorConsole.Write($"Web app:"); + ColorConsole.Write($"{wa.Xml_AppName}", ConsoleColor.Cyan); + var fc2 = wa.ApplicationState.Contains("Unregistered") ? ConsoleColor.Red : ConsoleColor.Green; + ColorConsole.Write($"{wa.ApplicationState}", fc2, bracket: "()"); + ColorConsole.Write($", Log.path:"); + ColorConsole.Write($"{wa.ApplicationPath}", ConsoleColor.White); + ColorConsole.Write($", Phy.path:"); + ColorConsole.WriteLine($"{wa.Xml_AppPhysicalPath}", ConsoleColor.White); + } + else if (lineix == 2) + { + ColorConsole.Write($"impersonate identity:"); + ColorConsole.WriteLine($"{wa.AppImpersonateIdentity}", ConsoleColor.White); + } + else if (lineix == 3) + { + ColorConsole.Write($"Site:"); + ColorConsole.Write($"{wa.Xml_SiteName}", ConsoleColor.Cyan); + var fc0 = + wa.SiteState.Contains("Started") ? ConsoleColor.Green + : wa.SiteState.Contains("Unregistered") ? ConsoleColor.Red + : ConsoleColor.Yellow; + ColorConsole.Write($"{wa.SiteState}", fc0, bracket: "()"); + ColorConsole.Write($", Ports:"); + ColorConsole.Write($"{wa.SitePortList}", ConsoleColor.White); + ColorConsole.Write($", Phy.path:"); + ColorConsole.WriteLine($"{wa.Xml_SitePhysicalPath}", ConsoleColor.White); + } + else if (lineix == 4) + { + ColorConsole.Write($"Pool:"); + ColorConsole.Write($"{wa.Xml_PoolName}", ConsoleColor.Cyan); + var fc1 = wa.PoolState == null ? ConsoleColor.Red + : wa.PoolState.Contains("Started") ? ConsoleColor.Green + : wa.PoolState.Contains("Unregistered") ? ConsoleColor.Red + : ConsoleColor.Yellow; + string waps = wa.PoolState == null ? "Unregistered/Unknown" : wa.PoolState; + ColorConsole.Write($"{waps}", fc1, bracket: "()"); + ColorConsole.Write($", identity:"); + ColorConsole.WriteLine($"{wa.PoolAccount}", ConsoleColor.White); + } + else if (lineix == 5) + { + ColorConsole.WriteLine(); + } + else + { + return null; + } + return ""; + } + #endregion private method: DisplayWebAppInfo } public static class WebApplicationManagerCore { #region private method: CollectWebAppInfo - public static WebApplication CollectWebAppInfo(SiteCollection sites,ApplicationPoolCollection pools, WebApplication wadef) + public static WebApplication CollectWebAppInfo(WebApplication wadef) { - var wa = new WebApplication(wadef); - try + using (ServerManager sm = new ServerManager()) { - wa.Site = sites[wa.Xml_SiteName]; - if (wa.Site == null) { throw new Exception(); } - else + var sites = sm.Sites; + var pools = sm.ApplicationPools; + + var wa = new WebApplication(wadef); + try { - var ss = wa.Site.State; - wa.SiteState = ss.ToString(); - wa.SitePortList = ""; - foreach (var binding in wa.Site.Bindings) - { - if (binding?.EndPoint?.Port != null) { wa.SitePortList += $"[{binding.EndPoint.Port}]"; } - } - var wn = Path.Combine("/", wa.Xml_AppName); - var _wa = wa.Site.Applications[wn]; - if (_wa == null) + wa.Site = sites[wa.Xml_SiteName]; + if (wa.Site == null) { throw new Exception(); } + else { - wa.ApplicationState = "Unregistered/Unknown"; - wa.ApplicationPath = ""; - wa.Application = null; - wa.AppImpersonateIdentity = ""; + var ss = wa.Site.State; + wa.SiteState = ss.ToString(); + wa.SitePortList = ""; + foreach (var binding in wa.Site.Bindings) + { + if (binding?.EndPoint?.Port != null) { wa.SitePortList += $"[{binding.EndPoint.Port}]"; } + } + var wn = Path.Combine("/", wa.Xml_AppName); + var _wa = wa.Site.Applications[wn]; + if (_wa == null) + { + wa.ApplicationState = "Unregistered/Unknown"; + wa.ApplicationPath = ""; + wa.Application = null; + wa.AppImpersonateIdentity = ""; + } + else + { + wa.ApplicationState = "Registered"; + wa.ApplicationPath = _wa.Path; + wa.Application = _wa; + wa.AppImpersonateIdentity = GetCurrentImpersonateIdentityInfo(wa); + } } + } + catch + { + wa.Site = null; + wa.SiteState = "Unregistered/Unknown"; + wa.SitePortList = ""; + wa.Application = null; + wa.ApplicationState = "Unregistered/Unknown"; + wa.ApplicationPath = ""; + }; + try + { + wa.ApplicationPool = pools[wa.Xml_PoolName]; + if (wa.ApplicationPool == null) { throw new Exception(); } else { - wa.ApplicationState = "Registered"; - wa.ApplicationPath = _wa.Path; - wa.Application = _wa; - wa.AppImpersonateIdentity = GetImpersonateIdentityInfo(wa.Xml_IdentityConfigFile); + wa.PoolState = wa.ApplicationPool.State.ToString(); + string pa = $"{wa.ApplicationPool.ProcessModel.IdentityType}"; + if (wa.ApplicationPool.ProcessModel.IdentityType == ProcessModelIdentityType.SpecificUser) + { + pa += $"({wa.ApplicationPool.ProcessModel.UserName}[{wa.ApplicationPool.ProcessModel.Password}])"; + } + wa.PoolAccount = pa; } } - } - catch (Exception ex) - { - wa.Site = null; - wa.SiteState = "Unregistered/Unknown"; - wa.SitePortList = ""; - wa.Application = null; - wa.ApplicationState = "Unregistered/Unknown"; - wa.ApplicationPath = ""; - }; - try - { - wa.ApplicationPool = pools[wa.Xml_PoolName]; - if (wa.ApplicationPool == null) { throw new Exception(); } - else + catch { - wa.PoolState = wa.ApplicationPool.State.ToString(); - string pa = $"{wa.ApplicationPool.ProcessModel.IdentityType}"; - if (wa.ApplicationPool.ProcessModel.IdentityType == ProcessModelIdentityType.SpecificUser) - { - pa += $"({wa.ApplicationPool.ProcessModel.UserName}[{wa.ApplicationPool.ProcessModel.Password}])"; - } - wa.PoolAccount = pa; + wa.ApplicationPool = null; + wa.PoolState = "Unregistered/Unknown"; + wa.PoolAccount = ""; } + return wa; } - catch - { - wa.ApplicationPool = null; - wa.PoolState = "Unregistered/Unknown"; - wa.PoolAccount = ""; - } - return wa; } #endregion private method: CollectWebAppInfo @@ -541,8 +701,9 @@ namespace Vrh.Log4Pro.MaintenanceConsole #endregion private method:CommitChanges #region private methods: Get information (with no ServerManager parameter) - public static string GetImpersonateIdentityInfo(string filepath) + public static string GetCurrentImpersonateIdentityInfo(WebApplication wa) { + var filepath = wa.Xml_ImpersonateIdentityConfigFile; try { var xml = XElement.Load(filepath); @@ -553,6 +714,7 @@ namespace Vrh.Log4Pro.MaintenanceConsole var impersonate = identityXml.Attribute(XName.Get("impersonate"))?.Value; var username = identityXml.Attribute(XName.Get("userName"))?.Value; var password = identityXml.Attribute(XName.Get("password"))?.Value; + string unpswinfo = $", username[password]: {username}[{password}]"; var userinfo = impersonate.ToLower() == "true" && !string.IsNullOrWhiteSpace(username) ? unpswinfo : ""; var retinfo = $"Impersonate={impersonate}{userinfo}"; @@ -561,22 +723,40 @@ namespace Vrh.Log4Pro.MaintenanceConsole } catch { return "no info (exception)"; } } - public static string GetUserInfo(string poolname) + public static string GetDefaultImpersonateIdentityInfo(WebApplication wa) + { + var impersonate = wa.Xml_ImpersonateIdentity; + var username = wa.Xml_ImpersonateIdentityUsername; + var password = wa.Xml_ImpersonateIdentityPassword; + + string unpswinfo = $", username[password]: {username}[{password}]"; + var userinfo = impersonate && !string.IsNullOrWhiteSpace(username) ? unpswinfo : ""; + var retinfo = $"Impersonate={impersonate}{userinfo}"; + return retinfo; + } + public static string GetDefaultPoolIdentityInfo(WebApplication wa) + { + var pit = wa.Xml_PoolIdentitytype; + var pun = wa.Xml_PoolUsername; + var ppw = wa.Xml_PoolPassword; + string userinfo = $"Identity type:{pit}"; + if (pit == ProcessModelIdentityType.SpecificUser) { userinfo += $", username[password]:{pun}[{ppw}]"; } + return userinfo; + } + public static string GetCurrentPoolIdentityInfo(WebApplication wa) { + string poolname = wa.Xml_PoolName; using (var sm2 = new ServerManager()) { - var pool = sm2.ApplicationPools[poolname]; string userinfo = ""; + var pool = sm2.ApplicationPools[poolname]; if (pool != null) { - if (pool.ProcessModel.IdentityType == ProcessModelIdentityType.SpecificUser) - { - userinfo = $"{pool.ProcessModel.UserName}({pool.ProcessModel.Password})"; - } - else - { - userinfo = $"{pool.ProcessModel.IdentityType}"; - } + var pit = pool.ProcessModel.IdentityType; + var pun = pool.ProcessModel.UserName; + var ppw = pool.ProcessModel.IdentityType; + userinfo = $"Identity type:{pit}"; + if (pit == ProcessModelIdentityType.SpecificUser) { userinfo += $", username[password]:{pun}[{ppw}]"; } } return userinfo; } @@ -824,6 +1004,7 @@ namespace Vrh.Log4Pro.MaintenanceConsole public class WebApplication : XmlLinqBase { #region properties from Xml definition + public string Xml_Key; public string Xml_AppName; public string Xml_Description; public string Xml_PoolName; @@ -831,10 +1012,13 @@ namespace Vrh.Log4Pro.MaintenanceConsole public string Xml_AppPhysicalPath; public ManagedPipelineMode Xml_PoolPipeLineMode; public string Xml_SitePhysicalPath; - public string Xml_IdentityConfigFile; + public string Xml_ImpersonateIdentityConfigFile; public ProcessModelIdentityType Xml_PoolIdentitytype; public string Xml_PoolUsername; public string Xml_PoolPassword; + public string Xml_ImpersonateIdentityUsername; + public string Xml_ImpersonateIdentityPassword; + public bool Xml_ImpersonateIdentity; public bool Xml_RecreatePool; public bool Xml_RecreateSite; public bool Xml_RecreateApp; @@ -859,6 +1043,7 @@ namespace Vrh.Log4Pro.MaintenanceConsole { string ATTRIBUTEMANDATORY = nameof(XmlStructure.WebApplication) + " attribute is mandatory! Name: {0}"; + Xml_Key= GetValue(nameof(XmlStructure.WebApplication.Attributes.Key), webappXml, XmlStructure.WebApplication.Attributes.Key.Values.DEFAULT); Xml_AppName = webappXml.Attribute(XName.Get(nameof(XmlStructure.WebApplication.Attributes.Name)))?.Value; if (string.IsNullOrWhiteSpace(Xml_AppName)) { throw new ApplicationException(string.Format(ATTRIBUTEMANDATORY, nameof(XmlStructure.WebApplication.Attributes.Name))); } @@ -876,7 +1061,6 @@ namespace Vrh.Log4Pro.MaintenanceConsole Xml_PoolPipeLineMode = GetValue(nameof(XmlStructure.WebApplication.Attributes.AppPoolPipeLineMode), webappXml, ManagedPipelineMode.Integrated); } Xml_SitePhysicalPath = GetValue(nameof(XmlStructure.WebApplication.Attributes.SiteRootDir), webappXml, Xml_AppPhysicalPath); - Xml_IdentityConfigFile = webappXml.Attribute(XName.Get(nameof(XmlStructure.WebApplication.Attributes.IdentityConfigFile)))?.Value; Xml_PoolUsername = GetValue(nameof(XmlStructure.WebApplication.Attributes.AppPoolUsername), webappXml, nameof(ProcessModelIdentityType.ApplicationPoolIdentity)); Xml_PoolPassword = GetValue(nameof(XmlStructure.WebApplication.Attributes.AppPoolPassword), webappXml, ""); @@ -884,6 +1068,11 @@ namespace Vrh.Log4Pro.MaintenanceConsole catch { Xml_PoolIdentitytype = ProcessModelIdentityType.SpecificUser; } if (Xml_PoolIdentitytype != ProcessModelIdentityType.SpecificUser) { Xml_PoolPassword = ""; Xml_PoolUsername = ""; } + Xml_ImpersonateIdentityConfigFile = webappXml.Attribute(XName.Get(nameof(XmlStructure.WebApplication.Attributes.ImpersonateIdentityConfigFile)))?.Value; + Xml_ImpersonateIdentity = GetValue(nameof(XmlStructure.WebApplication.Attributes.ImpersonateIdentity), webappXml, XmlStructure.WebApplication.Attributes.ImpersonateIdentity.Values.DEFAULT); + Xml_ImpersonateIdentityUsername = GetValue(nameof(XmlStructure.WebApplication.Attributes.ImpersonateIdentityUsername), webappXml, ""); + Xml_ImpersonateIdentityPassword= GetValue(nameof(XmlStructure.WebApplication.Attributes.ImpersonateIdentityPassword), webappXml, ""); + Xml_RecreatePool = GetValue(nameof(XmlStructure.WebApplication.Attributes.RecreatePool), webappXml, false); Xml_RecreateSite = GetValue(nameof(XmlStructure.WebApplication.Attributes.RecreateSite), webappXml, false); Xml_RecreateApp = GetValue(nameof(XmlStructure.WebApplication.Attributes.RecreateApp), webappXml, true); @@ -893,19 +1082,27 @@ namespace Vrh.Log4Pro.MaintenanceConsole } public WebApplication(WebApplication wadef) { + Xml_Key = wadef.Xml_Key; Xml_AppName = wadef.Xml_AppName; Xml_Description = wadef.Xml_Description; Xml_PoolName = wadef.Xml_PoolName; Xml_SiteName = wadef.Xml_SiteName; Xml_AppPhysicalPath = wadef.Xml_AppPhysicalPath; Xml_SitePhysicalPath = wadef.Xml_SitePhysicalPath; - Xml_IdentityConfigFile = wadef.Xml_IdentityConfigFile; + Xml_PoolPipeLineMode = wadef.Xml_PoolPipeLineMode; Xml_PoolIdentitytype = wadef.Xml_PoolIdentitytype; + Xml_PoolUsername = wadef.Xml_PoolUsername; + Xml_PoolPassword = wadef.Xml_PoolPassword; Xml_RecreateSite = wadef.Xml_RecreateSite; Xml_RecreatePool = wadef.Xml_RecreatePool; Xml_RecreateApp = wadef.Xml_RecreateApp; Xml_ForceRemovePool = wadef.Xml_ForceRemovePool; Xml_ForceRemoveSite = wadef.Xml_ForceRemoveSite; + + Xml_ImpersonateIdentityConfigFile = wadef.Xml_ImpersonateIdentityConfigFile; + Xml_ImpersonateIdentity = wadef.Xml_ImpersonateIdentity; + Xml_ImpersonateIdentityUsername = wadef.Xml_ImpersonateIdentityUsername; + Xml_ImpersonateIdentityPassword = wadef.Xml_ImpersonateIdentityPassword; } #region XmlStructure public static class XmlStructure @@ -914,15 +1111,19 @@ namespace Vrh.Log4Pro.MaintenanceConsole { public static class Attributes { + public static class Key { public static class Values { public const string DEFAULT = ""; } } public static class Name { } public static class Description { } public static class AppPool { public static class Values { public const string DEFAULT = "DefaultAppPool"; } } public static class WebSite { public static class Values { public const string DEFAULT = "Default Web Site"; } } public static class InstallDir { } public static class SiteRootDir { } - public static class IdentityConfigFile { } + public static class ImpersonateIdentityConfigFile { } public static class AppPoolUsername { } public static class AppPoolPassword { } + public static class ImpersonateIdentityUsername { } + public static class ImpersonateIdentityPassword { } + public static class ImpersonateIdentity { public static class Values { public const bool DEFAULT = false; } } public static class AppPoolPipeLineMode { } public static class RecreatePool { } public static class RecreateSite { } diff --git a/Vrh.Log4Pro.MaintenanceConsole/Manager - WindowsServiceManager.cs b/Vrh.Log4Pro.MaintenanceConsole/Manager - WindowsServiceManager.cs index 8bf36c4..4401c15 100644 --- a/Vrh.Log4Pro.MaintenanceConsole/Manager - WindowsServiceManager.cs +++ b/Vrh.Log4Pro.MaintenanceConsole/Manager - WindowsServiceManager.cs @@ -12,232 +12,54 @@ using Microsoft.Web.Administration; using System.Management; using System.Diagnostics; +using Vrh.Log4Pro.MaintenanceConsole.MenuNS; +using Vrh.Log4Pro.MaintenanceConsole.ColorConsoleNS; +using Vrh.Log4Pro.MaintenanceConsole.ToolsNS; +using Vrh.Log4Pro.MaintenanceConsole.CommandLineParserNS; + using Vrh.XmlProcessing; +using VRH.Common; using System.Xml.Linq; using System.Text.RegularExpressions; -namespace Vrh.Log4Pro.MaintenanceConsole +namespace Vrh.Log4Pro.MaintenanceConsole.WindowsServiceManagerNS { #region WindowsServiceManager class public static class WindowsServiceManager { + private const string XMLCONNECTIONSTRING = "config=MAINTENANCECONSOLE_WINDOWSSERVICEMANAGER;"; + private const string XMLCONNECTIONSTRING_DEFAULT = "file=Config.Xml;element=WindowsServices;"; + #region Execute public static object Execute(object o1 = null, object o2 = null) { - string xmlcs = "file=Config.Xml;element=WindowsServices;"; - var config = new WindowsServiceManagerXmlProcessor(xmlcs, "", "hu-HU"); + var args = (o1 as Menu.ExecutorParameter).Args; + var functionkey = CommandLine.GetCommandLineArgument(args, CLP.CMD_FUNCTION); + var config = new WindowsServiceManagerXmlProcessor(XMLCONNECTIONSTRING, "", "hu-HU"); + var ep = new Menu.ExecutorParameter(config, args); var menufunctions = new Menu("Manage Windows Services", "Select the management function!") - .AddMenuItem(new Menu.Item("WSR", "Register", Register)) - .AddMenuItem(new Menu.Item("WSU", "Unregister", Unregister)) - .AddMenuItem(new Menu.Item("WSS", "Start", Start)) - .AddMenuItem(new Menu.Item("WSX", "Stop", Stop)) - .AddMenuItem(new Menu.Item("WSK", "Kill", Kill)) - .AddMenuItem(new Menu.Item("WSP", "Purge", Purge)) - .AddMenuItem(new Menu.Item("WSA", "Set user account", SetUserAccount)) - .SetSelectionMode(Menu.SelectionMode.Single); - - while (true) - { - Menu.Selection sr; - - menufunctions.DisplayTitle(); - var menuservices = DisplayServices(config); - menufunctions.DisplayItems(3, 35); - sr = menufunctions.Select(); - if (sr.Result == Menu.SelectionResult.Exit) { break; } - else if (sr.Result == Menu.SelectionResult.None) { continue; } - else if (sr.Result == Menu.SelectionResult.Error) { continue; } - menufunctions.SetExecutorParameters(sr,config); - menufunctions.ExecuteSelection(sr.SelectedKeyList); - } + .AddMenuItem(new Menu.Item(CLP.Module.WindowsServiceManager.Function.Register.KEY, "Register", Register,ep)) + .AddMenuItem(new Menu.Item(CLP.Module.WindowsServiceManager.Function.Unregister.KEY, "Unregister", Unregister, ep)) + .AddMenuItem(new Menu.Item(CLP.Module.WindowsServiceManager.Function.Start.KEY, "Start", Start, ep)) + .AddMenuItem(new Menu.Item(CLP.Module.WindowsServiceManager.Function.Stop.KEY, "Stop", Stop, ep)) + .AddMenuItem(new Menu.Item(CLP.Module.WindowsServiceManager.Function.Kill.KEY, "Kill", Kill, ep)) + .AddMenuItem(new Menu.Item(CLP.Module.WindowsServiceManager.Function.Purge.KEY, "Purge", Purge, ep)) + .AddMenuItem(new Menu.Item(CLP.Module.WindowsServiceManager.Function.SetUserAccount.KEY, "Set user account", SetUserAccount, ep)) + .SetSelectionMode(Menu.SelectionMode.Single) + .SetMenuHeaderDisplayer(ServiceListDisplayer); + menufunctions.ExecuteMenu(functionkey); return null; } #endregion Execute - public static Menu DisplayServices(WindowsServiceManagerXmlProcessor config,string prompt = null,bool silent=false) - { - List wsdefList = config.GetDefinitionList(); - var menuservices = new Menu("Windows services",prompt) - .SetMenuItemDisplayer(DisplayServiceInfo) - .SetSelectionMode(Menu.SelectionMode.Multi) - .SetHeaderWidth(4); - menuservices.ClearMenuItemList(); - foreach (var wsdef in wsdefList) - { - var w = CollectWindowsServiceInfo(wsdef); - menuservices.AddMenuItem(new Menu.Item(null, null, null, w)); - } - if (!silent) { menuservices.DisplayItems(1); } - return menuservices; - } - - #region private method: DisplayServiceInfo - private static object DisplayServiceInfo(object wsobj, int lineix) - { - WindowsService ws = wsobj as WindowsService; - if (lineix == 0) - { - ColorConsole.Write($"{ws.Description}", ConsoleColor.Black, ConsoleColor.White); - ColorConsole.WriteLine($"{ws.DisplayName}", bracket: "()"); - return ws.DisplayName+ws.Description; - } - else if (lineix == 1) - { - ColorConsole.Write($"Win service:"); - ColorConsole.Write($"{ws.Name}", ConsoleColor.Cyan); - var fc2 = - ws.Status.Contains(nameof(WmiServiceStatus.OK)) ? ConsoleColor.Green - : ws.Status.Contains(nameof(WmiServiceStatus.Unknown)) ? ConsoleColor.Red - : ws.Status.Contains(nameof(WmiServiceStatus.Error)) ? ConsoleColor.Red - : ConsoleColor.Yellow; - ColorConsole.Write($"("); - ColorConsole.Write($"{ws.Status}", fc2); - var fc0 = - ws.State.Contains(nameof(WmiServiceState.Running)) ? ConsoleColor.Green - : ws.State.Contains(nameof(WmiServiceState.Unknown)) ? ConsoleColor.Red - : ws.State.Contains(nameof(WmiServiceState.Unregistered)) ? ConsoleColor.Red - : ConsoleColor.Yellow; - ColorConsole.Write($" / "); - ColorConsole.Write($"{ws.State}", fc0); - ColorConsole.Write($")"); - ColorConsole.Write($", StartMode:"); - ColorConsole.Write($"{ws.StartMode}", ConsoleColor.Cyan); - if(ws.Status==nameof(WmiServiceStatus.OK) && ws.State != nameof(WmiServiceState.Stopped) && ws.State != nameof(WmiServiceState.Unknown)) - { - ColorConsole.Write($", Priority:"); - ColorConsole.Write($"{ws.PriorityClass}", ConsoleColor.White); - ColorConsole.Write($", ProcessId:"); - ColorConsole.Write($"{ws.ProcessId}", ConsoleColor.White); - } - ColorConsole.WriteLine(); - return ws.Name; - } - else if (lineix == 2) - { - if (string.IsNullOrEmpty(ws.PathName)) { return ""; } - var cmdarray = CommandLineParser.SplitArgs(ws.PathName).ToArray(); - ColorConsole.Write($"Start command:"); - ColorConsole.WriteLine($"{cmdarray[0]}", ConsoleColor.White); - return ws.PathName; - } - else if (lineix == 3) - { - if (string.IsNullOrEmpty(ws.PathName)) { return ""; } - var cmdparams = CommandLineParser.SplitArgs(ws.PathName).Skip(1).ToArray(); - if (cmdparams.Length==0) { return ""; } - var cmdparamsstr = string.Join("][", cmdparams); - ColorConsole.Write($"Start arguments:"); - ColorConsole.WriteLine($"[{cmdparamsstr}]", ConsoleColor.White); - return cmdparamsstr; - } - else if (lineix == 4) - { - ColorConsole.Write($"User:"); - ColorConsole.WriteLine($"{ws.StartName}", ConsoleColor.White); - return ws.StartName; - } - else if (lineix == 5) - { - ColorConsole.WriteLine(); - return " "; - } - return null; - } - private enum WmiServiceState - { - StartPending, - Running, - Paused, - PausedPending, - Stopped, - StopPending, - Unknown, - Unregistered, - } - private enum WmiServiceStatus - { - OK, - Error, - Degraded, - Unknown, - Pred_Fail, - Starting, - Stopping, - Service, - Stressed, - NonRecover, - No_Contact, - Lost_Comm, - Unregistered, - } - #endregion private method: DisplayServiceInfo - - #region private CollectWindowsServiceInfo - private static WindowsService CollectWindowsServiceInfo(WindowsService ws) - { - using (var wmiService = WindowsServiceManagerCore.GetServiceObject(ws.Name)) - { - using (var service = WindowsServiceManagerCore.GetServiceController(ws.Name)) - { - var wmiserviceproblem = false; - try { wmiService.Get();}catch { wmiserviceproblem = true; } - if (wmiService == null || service == null || wmiserviceproblem) - { - ws.DisplayName = ws.Xml_DisplayName; - ws.Description = ws.Xml_Description; - ws.ThisDependsOn = ws.Xml_Dependon; - ws.ServicesDependOnThis = new string[] { "???" }; - ws.PathName = $"\"{ws.Xml_Exe}\" {ws.Xml_Arguments}"; - ws.StartMode = ws.Xml_StartMode; - ws.State = nameof(WmiServiceState.Unregistered); - ws.Status = nameof(WmiServiceStatus.Unregistered); - if (ws.Xml_IdentityType== ServiceAccount.User) { ws.StartName = ws.Xml_Username + $"({ws.Xml_Password})"; } - else { ws.StartName = ws.Xml_IdentityType.ToString(); } - ws.ProcessId = 0; - ws.PriorityClass = ws.Xml_Priority; - } - else - { - ws.DisplayName = (string)wmiService[nameof(WindowsService.DisplayName)]; - ws.Description = (string)wmiService[nameof(WindowsService.Description)]; - if (string.IsNullOrEmpty(ws.Description)) { ws.Description = ws.DisplayName; } - if (string.IsNullOrEmpty(ws.DisplayName)) { ws.DisplayName = ws.Description; } - ws.ServicesDependOnThis = service.DependentServices.Select(s => s.ServiceName).ToArray(); - try { ws.ThisDependsOn = service.ServicesDependedOn.Select(s => s.ServiceName).ToArray(); } catch { ws.ThisDependsOn = new string[] { "???" }; } - ws.PathName = (string)wmiService[nameof(WindowsService.PathName)];if (ws.PathName == null) { ws.PathName = ""; } - var sm = (string)wmiService[nameof(WindowsService.StartMode)]; - ws.StartMode = - sm == "Auto" ? ServiceStartMode.Automatic - : sm == "Auto" ? ServiceStartMode.Manual - : sm == "Auto" ? ServiceStartMode.Disabled - : sm == "Auto" ? ServiceStartMode.Boot - : sm == "Auto" ? ServiceStartMode.System - : ServiceStartMode.Manual; - ws.State = (string)wmiService[nameof(WindowsService.State)]; - ws.Status = (string)wmiService[nameof(WindowsService.Status)]; - ws.StartName = (string)wmiService[nameof(WindowsService.StartName)]; - ws.ProcessId = 0; - ws.PriorityClass = "-"; - if (ws.State != nameof(WmiServiceState.Stopped)) - { - ws.ProcessId = Convert.ToInt32(wmiService[nameof(WindowsService.ProcessId)]); - ws.PriorityClass = Process.GetProcessById(ws.ProcessId).PriorityClass.ToString(); - } - } - } - } - return ws; - } - #endregion private CollectWindowsServiceInfo - #region First level Executors with UI - private static object Purge(object parameter,object o) + private static object Purge(object parameter, object o) { - var config = parameter as WindowsServiceManagerXmlProcessor; + var config = (parameter as Menu.ExecutorParameter).GetConfig(); while (true) { - ColorConsole.Write($"Enter servicename mask (% and ? are wildchars)!",ConsoleColor.Yellow); + ColorConsole.Write($"Enter servicename mask (% and ? are wildchars)!", ConsoleColor.Yellow); var mask = ColorConsole.ReadLine($" ---> ", ConsoleColor.Yellow).ToUpper(); if (mask == "EX") { return o; } else if (mask == "") { continue; } @@ -245,12 +67,11 @@ namespace Vrh.Log4Pro.MaintenanceConsole if (sl.Length > 10) { sl = sl.Take(10).ToArray(); } var menuservices = new Menu("Windows services", "Select the windows service(es) to delete (max 10 in one run)!") - .SetSelectionMode(Menu.SelectionMode.Multi) - .SetHeaderWidth(4); + .SetSelectionMode(Menu.SelectionMode.Multi); for (var i = 0; i < sl.Length; i++) { - menuservices.AddMenuItem(new Menu.Item(null, $"{sl[i].ServiceName} ({sl[i].DisplayName})", null, sl[i].ServiceName)); + menuservices.AddMenuItem(new Menu.Item(null, $"{sl[i].ServiceName} ({sl[i].DisplayName})", null, new Menu.ExecutorParameter(pars:sl[i].ServiceName))); } menuservices.DisplayItems(1); var ms = menuservices.Select(); @@ -259,21 +80,21 @@ namespace Vrh.Log4Pro.MaintenanceConsole else if (ms.Result == Menu.SelectionResult.Exit) { break; } else { - foreach (var p in ms.SelectedParameterList) + foreach (var p in ms.SelectedParameterList) { ColorConsole.Write($"Enter CONFIRM to delete service ", ConsoleColor.Yellow); - ColorConsole.Write($"{p}", ConsoleColor.White,bracket:"''"); + ColorConsole.Write($"{p}", ConsoleColor.White, bracket: "''"); ColorConsole.Write($"!", ConsoleColor.Yellow); var confirmation = ColorConsole.ReadLine(prefix: " ---> ").ToUpper(); if (confirmation == "EX") { return o; } - else if (confirmation == "") + else if (confirmation == "") { ColorConsole.WriteLine($"Service '{p}' skipped!", ConsoleColor.Green); - continue; + continue; } else if (confirmation == "CONFIRM") { - WindowsServiceManagerCore.Unregister((string)p); + WindowsServiceManagerCore.Unregister((string)(p.Parameters)); ColorConsole.WriteLine($"Service '{p}' deleted!", ConsoleColor.Green); } } @@ -281,12 +102,16 @@ namespace Vrh.Log4Pro.MaintenanceConsole } return o; } - private static object Kill(object parameter,object o) + private static object Kill(object parameter, object o) { - var config = parameter as WindowsServiceManagerXmlProcessor; - var menuservices = DisplayServices(config, $"Select the windows service(es) to manage with function '{nameof(Kill)}'!", silent:true); + var config = (parameter as Menu.ExecutorParameter).GetConfig(); + var args = (parameter as Menu.ExecutorParameter).Args; - Menu.Selection sr = menuservices.Select(); + var selectedserviceindexes = CommandLine.GetCommandLineArgument(args, CLP.Module.WindowsServiceManager.Function.CMD_SERVICES); + + var menuservices = DisplayWindowsServiceMenu(config, $"Select the windows service(es) to manage with function '{nameof(Kill)}'!", silent: true); + + Menu.Selection sr = menuservices.Select(selectedserviceindexes); if (sr.Result == Menu.SelectionResult.Exit) { return o; } else if (sr.Result == Menu.SelectionResult.None) { return o; } else if (sr.Result == Menu.SelectionResult.Error) { return o; } @@ -294,25 +119,26 @@ namespace Vrh.Log4Pro.MaintenanceConsole else { } foreach (var p in sr.SelectedParameterList) { - WindowsService ws = p as WindowsService; + WindowsService ws = p.Parameters as WindowsService; try { var success = WindowsServiceManagerCore.Kill(ws.Name); ColorConsole.WriteLine($"Service killed. Name:{ws.Name}", ConsoleColor.Green); } - catch (Exception ex) - { - ColorConsole.WriteLine(ex.Message, ConsoleColor.Red); - } + catch (Exception ex) { ColorConsole.WriteLine(ex.Message, ConsoleColor.Red); } } return o; } - private static object Register(object parameter, object o) + private static object Register(object parameter, object o) { - var config = parameter as WindowsServiceManagerXmlProcessor; - var menuservices = DisplayServices(config, $"Select the windows service(es) to manage with function '{nameof(Register)}'!", silent: true); + var config = (parameter as Menu.ExecutorParameter).GetConfig(); + var args = (parameter as Menu.ExecutorParameter).Args; - Menu.Selection sr = menuservices.Select(); + var selectedserviceindexes = CommandLine.GetCommandLineArgument(args, CLP.Module.WindowsServiceManager.Function.CMD_SERVICES); + + var menuservices = DisplayWindowsServiceMenu(config, $"Select the windows service(es) to manage with function '{nameof(Register)}'!", silent: true); + + Menu.Selection sr = menuservices.Select(selectedserviceindexes); if (sr.Result == Menu.SelectionResult.Exit) { return o; } else if (sr.Result == Menu.SelectionResult.None) { return o; } else if (sr.Result == Menu.SelectionResult.Error) { return o; } @@ -320,25 +146,25 @@ namespace Vrh.Log4Pro.MaintenanceConsole else { } foreach (var p in sr.SelectedParameterList) { - WindowsService ws = p as WindowsService; + WindowsService ws = p.Parameters as WindowsService; try { - var success = WindowsServiceManagerCore.Register(ws); - ColorConsole.WriteLine($"Service registered. Name:{ws.Name}", ConsoleColor.Green); - } - catch (Exception ex) - { - ColorConsole.WriteLine(ex.Message, ConsoleColor.Red); + var success = WindowsServiceManagerCore.Register(ws, sr.SelectedParameterList.Select(x => (x.Parameters as WindowsService).Name).ToList()); + ColorConsole.WriteLine($"Service unregistered. Name:{ws.Name}", ConsoleColor.Green); } + catch (Exception ex) { ColorConsole.WriteLine(ex.Message, ConsoleColor.Red); } } return o; } - private static object Unregister(object parameter,object o) + private static object Unregister(object parameter, object o) { - var config = parameter as WindowsServiceManagerXmlProcessor; - var menuservices = DisplayServices(config, $"Select the windows service(es) to manage with function '{nameof(Unregister)}'!", silent: true); + var config = (parameter as Menu.ExecutorParameter).GetConfig(); + var args = (parameter as Menu.ExecutorParameter).Args; + var selectedserviceindexes = CommandLine.GetCommandLineArgument(args, CLP.Module.WindowsServiceManager.Function.CMD_SERVICES); + + var menuservices = DisplayWindowsServiceMenu(config, $"Select the windows service(es) to manage with function '{nameof(Unregister)}'!", silent: true); - Menu.Selection sr = menuservices.Select(); + Menu.Selection sr = menuservices.Select(selectedserviceindexes); if (sr.Result == Menu.SelectionResult.Exit) { return o; } else if (sr.Result == Menu.SelectionResult.None) { return o; } else if (sr.Result == Menu.SelectionResult.Error) { return o; } @@ -346,25 +172,25 @@ namespace Vrh.Log4Pro.MaintenanceConsole else { } foreach (var p in sr.SelectedParameterList) { - WindowsService ws = p as WindowsService; + WindowsService ws = p.Parameters as WindowsService; try { var success = WindowsServiceManagerCore.Unregister(ws); ColorConsole.WriteLine($"Service unregistered. Name:{ws.Name}", ConsoleColor.Green); } - catch (Exception ex) - { - ColorConsole.WriteLine(ex.Message, ConsoleColor.Red); - } + catch (Exception ex) { ColorConsole.WriteLine(ex.Message, ConsoleColor.Red); } } return o; } - private static object Start(object parameter,object o) + private static object Start(object parameter, object o) { - var config = parameter as WindowsServiceManagerXmlProcessor; - var menuservices = DisplayServices(config, $"Select the windows service(es) to manage with function '{nameof(Start)}'!", silent: true); + var config = (parameter as Menu.ExecutorParameter).GetConfig(); + var args = (parameter as Menu.ExecutorParameter).Args; + var selectedserviceindexes = CommandLine.GetCommandLineArgument(args, CLP.Module.WindowsServiceManager.Function.CMD_SERVICES); - Menu.Selection sr = menuservices.Select(); + var menuservices = DisplayWindowsServiceMenu(config, $"Select the windows service(es) to manage with function '{nameof(Start)}'!", silent: true); + + Menu.Selection sr = menuservices.Select(selectedserviceindexes); if (sr.Result == Menu.SelectionResult.Exit) { return o; } else if (sr.Result == Menu.SelectionResult.None) { return o; } else if (sr.Result == Menu.SelectionResult.Error) { return o; } @@ -372,25 +198,25 @@ namespace Vrh.Log4Pro.MaintenanceConsole else { } foreach (var p in sr.SelectedParameterList) { - WindowsService ws = p as WindowsService; + WindowsService ws = p.Parameters as WindowsService; try { var success = WindowsServiceManagerCore.Start(ws.Name, ws.Xml_StartTimeout); ColorConsole.WriteLine($"Service started. Name:{ws.Name}", ConsoleColor.Green); } - catch (Exception ex) - { - ColorConsole.WriteLine(ex.Message, ConsoleColor.Red); - } + catch (Exception ex) { ColorConsole.WriteLine(ex.Message, ConsoleColor.Red); } } return o; } - private static object Stop(object parameter,object o) + private static object Stop(object parameter, object o) { - var config = parameter as WindowsServiceManagerXmlProcessor; - var menuservices = DisplayServices(config, $"Select the windows service(es) to manage with function '{nameof(Kill)}'!", silent: true); + var config = (parameter as Menu.ExecutorParameter).GetConfig(); + var args = (parameter as Menu.ExecutorParameter).Args; + var selectedserviceindexes = CommandLine.GetCommandLineArgument(args, CLP.Module.WindowsServiceManager.Function.CMD_SERVICES); + + var menuservices = DisplayWindowsServiceMenu(config, $"Select the windows service(es) to manage with function '{nameof(Kill)}'!", silent: true); - Menu.Selection sr = menuservices.Select(); + Menu.Selection sr = menuservices.Select(selectedserviceindexes); if (sr.Result == Menu.SelectionResult.Exit) { return o; } else if (sr.Result == Menu.SelectionResult.None) { return o; } else if (sr.Result == Menu.SelectionResult.Error) { return o; } @@ -398,25 +224,25 @@ namespace Vrh.Log4Pro.MaintenanceConsole else { } foreach (var p in sr.SelectedParameterList) { - WindowsService ws = p as WindowsService; + WindowsService ws = p.Parameters as WindowsService; try { var success = WindowsServiceManagerCore.Stop(ws.Name, ws.Xml_StopTimeout); ColorConsole.WriteLine($"Service stopped. Name:{ws.Name}", ConsoleColor.Green); } - catch (Exception ex) - { - ColorConsole.WriteLine(ex.Message, ConsoleColor.Red); - } + catch (Exception ex) { ColorConsole.WriteLine(ex.Message, ConsoleColor.Red); } } return o; } - private static object SetUserAccount(object parameter,object o) - { - var config = parameter as WindowsServiceManagerXmlProcessor; - var menuservices = DisplayServices(config, $"Select the windows service(es) to manage with function '{nameof(SetUserAccount)}'!", silent: true); + private static object SetUserAccount(object parameter, object o) + { + var config = (parameter as Menu.ExecutorParameter).GetConfig(); + var args = (parameter as Menu.ExecutorParameter).Args; + var selectedserviceindexes = CommandLine.GetCommandLineArgument(args, CLP.Module.WindowsServiceManager.Function.CMD_SERVICES); + + var menuservices = DisplayWindowsServiceMenu(config, $"Select the windows service(es) to manage with function '{nameof(SetUserAccount)}'!", silent: true); - Menu.Selection sr = menuservices.Select(); + Menu.Selection sr = menuservices.Select(selectedserviceindexes); if (sr.Result == Menu.SelectionResult.Exit) { return o; } else if (sr.Result == Menu.SelectionResult.None) { return o; } else if (sr.Result == Menu.SelectionResult.Error) { return o; } @@ -426,37 +252,15 @@ namespace Vrh.Log4Pro.MaintenanceConsole string username = null, password = null; foreach (var p in sr.SelectedParameterList) { - WindowsService ws = p as WindowsService; + WindowsService ws = p.Parameters as WindowsService; try { using (var wmiService = WindowsServiceManagerCore.GetServiceObject(ws.Name)) { - if (username==null) - { - string olduserinfo = WindowsServiceManagerCore.GetUserInfo(wmiService); - ColorConsole.WriteLine($"Current user info: {olduserinfo}"); - ColorConsole.WriteLine("Enter username then password. [Enter]=save.EX=exit"); - ColorConsole.WriteLine("Username is in the form of 'domainname\\username'"); - ColorConsole.WriteLine("Special usernames are: (Empty=API) "); - - ColorConsole.WriteLine($"LSE", ConsoleColor.Yellow, bracket: "()", prefix: " ", suffix: $" {nameof(ServiceAccount.LocalService)}"); - ColorConsole.WriteLine($"LSY", ConsoleColor.Yellow, bracket: "()", prefix: " ", suffix: $" {nameof(ServiceAccount.LocalSystem)}"); - ColorConsole.WriteLine($"NSE", ConsoleColor.Yellow, bracket: "()", prefix: " ", suffix: $" {nameof(ServiceAccount.NetworkService)}"); - - ColorConsole.WriteLine(); - ColorConsole.WriteLine($"EX", ConsoleColor.Red, bracket: "()", prefix: " ", suffix: " Exit"); - - username = ColorConsole.ReadLine("username -->", ConsoleColor.Yellow, bracket: "[]"); - if (username == "EX") { return null; } - else if (string.IsNullOrEmpty(username)) { username = nameof(ServiceAccount.LocalSystem); } - else if (username.ToUpper() == "LSE" || username == nameof(ServiceAccount.LocalService)) { username = nameof(ServiceAccount.LocalService); } - else if (username.ToUpper() == "LSY" || username == nameof(ServiceAccount.LocalSystem)) { username = nameof(ServiceAccount.LocalSystem); } - else if (username.ToUpper() == "NSE" || username == nameof(ServiceAccount.NetworkService)) { username = nameof(ServiceAccount.NetworkService); } - else - { - password = ColorConsole.ReadLine("password -->", ConsoleColor.Yellow, bracket: "[]"); - if (password == "EX") { return null; } - } + if (username == null) + { + GetUsernameAndPassword(wmiService,ws,out username, out password); + if (username == "EX" || password == "EX") { return null; } } if (WindowsServiceManagerCore.SetUserAccount(wmiService, username, password)) { ColorConsole.WriteLine($"Service user account changed. Name:{ws.Name}", ConsoleColor.Green); } else { ColorConsole.WriteLine($"Service user account change FAILED! Name:{ws.Name}", ConsoleColor.Red); } @@ -467,6 +271,147 @@ namespace Vrh.Log4Pro.MaintenanceConsole return o; } #endregion First level Executors with UI + + #region DisplayServices + private static void ServiceListDisplayer() { DisplayWindowsServiceMenu(); } + public static Menu DisplayWindowsServiceMenu(WindowsServiceManagerXmlProcessor config=null,string prompt = null,bool silent=false) + { + if (config==null) { config = new WindowsServiceManagerXmlProcessor(XMLCONNECTIONSTRING, "", "hu-HU"); } + var menuservices = new Menu("Windows services",prompt) + .SetMenuItemDisplayer(DisplayServiceInfo) + .SetSelectionMode(Menu.SelectionMode.Multi); + menuservices.ClearMenuItemList(); + + List wsgdefList = config.GetWindowsServiceGroupDefinitionList(); + foreach (var wsgdef in wsgdefList) + { + string menuitemtext = wsgdef.Xml_Description + "(" + string.Join(",", wsgdef.Xml_WindowsServiceKeyList) + ")"; + menuservices.AddMenuItem(new Menu.ItemGroup(wsgdef.Xml_Key, menuitemtext, wsgdef.Xml_WindowsServiceKeyList)); + } + + menuservices.AddMenuItem(new Menu.ItemSeparator());// separator + + List wsdefList = config.GetWindowsServiceDefinitionList(); + foreach (var wsdef in wsdefList) + { + menuservices.AddMenuItem(new Menu.Item(wsdef.Xml_Key, null, null, new Menu.ExecutorParameter(pars: wsdef.CollectWindowsServiceInfo()))); + } + + if (!silent) { menuservices.DisplayItems(1); } + return menuservices; + } + #endregion DisplayServices + + #region private method: DisplayServiceInfo + private static object DisplayServiceInfo(object obj, int lineix) + { + if (obj == null) { return null; } + WindowsService ws = (obj as Menu.ExecutorParameter).Parameters as WindowsService; + if (ws == null) { return null; } + if (lineix == 0) + { + ColorConsole.Write($"{ws.Description}", ConsoleColor.Black, ConsoleColor.White); + ColorConsole.WriteLine($"{ws.DisplayName}", bracket: "()"); + return ws.DisplayName+ws.Description; + } + else if (lineix == 1) + { + ColorConsole.Write($"Win service:"); + ColorConsole.Write($"{ws.Name}", ConsoleColor.Cyan); + var fc2 = + ws.Status.Contains(nameof(WindowsService.WmiServiceStatus.OK)) ? ConsoleColor.Green + : ws.Status.Contains(nameof(WindowsService.WmiServiceStatus.Unknown)) ? ConsoleColor.Red + : ws.Status.Contains(nameof(WindowsService.WmiServiceStatus.Error)) ? ConsoleColor.Red + : ConsoleColor.Yellow; + ColorConsole.Write($"("); + ColorConsole.Write($"{ws.Status}", fc2); + var fc0 = + ws.State.Contains(nameof(WindowsService.WmiServiceState.Running)) ? ConsoleColor.Green + : ws.State.Contains(nameof(WindowsService.WmiServiceState.Unknown)) ? ConsoleColor.Red + : ws.State.Contains(nameof(WindowsService.WmiServiceState.Unregistered)) ? ConsoleColor.Red + : ConsoleColor.Yellow; + ColorConsole.Write($" / "); + ColorConsole.Write($"{ws.State}", fc0); + ColorConsole.Write($")"); + ColorConsole.Write($", StartMode:"); + ColorConsole.Write($"{ws.StartMode}", ConsoleColor.Cyan); + if(ws.Status==nameof(WindowsService.WmiServiceStatus.OK) && ws.State != nameof(WindowsService.WmiServiceState.Stopped) && ws.State != nameof(WindowsService.WmiServiceState.Unknown)) + { + ColorConsole.Write($", Priority:"); + ColorConsole.Write($"{ws.PriorityClass}", ConsoleColor.White); + ColorConsole.Write($", ProcessId:"); + ColorConsole.Write($"{ws.ProcessId}", ConsoleColor.White); + } + ColorConsole.WriteLine(); + return ws.Name; + } + else if (lineix == 2) + { + if (string.IsNullOrEmpty(ws.PathName)) { return ""; } + var cmdarray = CommandLineParser.SplitArgs(ws.PathName).ToArray(); + ColorConsole.Write($"Start command:"); + ColorConsole.WriteLine($"{cmdarray[0]}", ConsoleColor.White); + return ws.PathName; + } + else if (lineix == 3) + { + if (string.IsNullOrEmpty(ws.PathName)) { return ""; } + var cmdparams = CommandLineParser.SplitArgs(ws.PathName).Skip(1).ToArray(); + if (cmdparams.Length==0) { return ""; } + var cmdparamsstr = string.Join("][", cmdparams); + ColorConsole.Write($"Start arguments:"); + ColorConsole.WriteLine($"[{cmdparamsstr}]", ConsoleColor.White); + return cmdparamsstr; + } + else if (lineix == 4) + { + ColorConsole.Write($"User:"); + ColorConsole.WriteLine($"{ws.StartName}", ConsoleColor.White); + return ws.StartName; + } + else if (lineix == 5) + { + ColorConsole.WriteLine(); + return " "; + } + return null; + } + #endregion private method: DisplayServiceInfo + + #region private GetUsernameAndPassword + private static void GetUsernameAndPassword(ManagementObject wmiService, WindowsService ws, out string username, out string password) + { + username = null; + password = null; + if (Menu.IsCommandMode()) { username = ws.Xml_Username; password = ws.Xml_Password; return; } + + string olduserinfo = WindowsServiceManagerCore.GetUserInfo(wmiService); + ColorConsole.WriteLine($"Current user info: {olduserinfo}"); + ColorConsole.WriteLine("Enter username then password. [Enter]=save.EX=exit"); + ColorConsole.WriteLine("Username is in the form of 'domainname\\username'"); + ColorConsole.WriteLine($"Empty={ws.Xml_Username} (default defined in XML)"); + ColorConsole.WriteLine("Special usernames are:"); + + ColorConsole.WriteLine($"LSE", ConsoleColor.Yellow, bracket: "()", prefix: " ", suffix: $" {nameof(ServiceAccount.LocalService)}"); + ColorConsole.WriteLine($"LSY", ConsoleColor.Yellow, bracket: "()", prefix: " ", suffix: $" {nameof(ServiceAccount.LocalSystem)}"); + ColorConsole.WriteLine($"NSE", ConsoleColor.Yellow, bracket: "()", prefix: " ", suffix: $" {nameof(ServiceAccount.NetworkService)}"); + + ColorConsole.WriteLine(); + ColorConsole.WriteLine($"EX", ConsoleColor.Red, bracket: "()", prefix: " ", suffix: " Exit"); + + username = ColorConsole.ReadLine("username -->", ConsoleColor.Yellow, bracket: "[]"); + if (username == "EX") { return; } + else if (string.IsNullOrEmpty(username)) { username = ws.Xml_Username; password = ws.Xml_Password; } + else if (username.ToUpper() == "LSE" || username == nameof(ServiceAccount.LocalService)) { username = nameof(ServiceAccount.LocalService); } + else if (username.ToUpper() == "LSY" || username == nameof(ServiceAccount.LocalSystem)) { username = nameof(ServiceAccount.LocalSystem); } + else if (username.ToUpper() == "NSE" || username == nameof(ServiceAccount.NetworkService)) { username = nameof(ServiceAccount.NetworkService); } + else + { + password = ColorConsole.ReadLine("password -->", ConsoleColor.Yellow, bracket: "[]"); + if (password == "EX") { return; } + } + } + #endregion private GetUsernameAndPassword } #endregion WindowsServiceManager class @@ -533,7 +478,15 @@ namespace Vrh.Log4Pro.MaintenanceConsole try { Process proc = Process.GetProcessById(pid); proc.Kill(); } catch (ArgumentException) { } // Process already exited. } - public static bool Register(WindowsService ws) + + #region Register + /// + /// Szerviz regisztrálása + /// + /// a szerviz adatait tartalmazó objektum + /// azon szervizek listája, amelyekkel egy függőségi csoportba tartozik + /// + public static bool Register(WindowsService ws,List dependencygroupservicenamelist) { // sc.exe create "ServiceName" binpath= "c:\windows\system32\NewServ.exe" displayname= "Service display name" obj= "username" password="password" start= auto depend= "sname1/sname2/snmae3" // sc.exe \\myserver create NewService binpath= c:\windows\system32\NewServ.exe @@ -568,8 +521,15 @@ namespace Vrh.Log4Pro.MaintenanceConsole { argumentlist.Add($"obj="); argumentlist.Add(ws.Xml_IdentityType.ToString().Quote()); } - var dependonparametert = String.Join("/", ws.Xml_Dependon); - argumentlist.Add($"depend="); argumentlist.Add(dependonparametert.Quote()); + + // dependency csoport feldolgozása + var effectivedependonlist = new List(); + foreach (var sn in ws.Xml_Dependon) { if (dependencygroupservicenamelist.Contains(sn)) { effectivedependonlist.Add(sn); } } + foreach (var sn in ws.Xml_Dependon) { if (dependencygroupservicenamelist==null || !dependencygroupservicenamelist.Any() || dependencygroupservicenamelist.Contains("*") || dependencygroupservicenamelist.Contains(sn)) { effectivedependonlist.Add(sn); } } + //--------------------------------------- + + var dependonparameter = String.Join("/", effectivedependonlist); + argumentlist.Add($"depend="); argumentlist.Add(dependonparameter.Quote()); var startparameter = ws.Xml_StartMode == ServiceStartMode.Automatic ? "auto" @@ -616,6 +576,7 @@ namespace Vrh.Log4Pro.MaintenanceConsole } return true; } + #endregion Register public static bool Unregister(WindowsService ws) { @@ -734,6 +695,7 @@ namespace Vrh.Log4Pro.MaintenanceConsole List _winservicelist; List _winservicelistinstartorder; List _winservicelistinstoporder; + List _winservicegrouplist; #region constructor public WindowsServiceManagerXmlProcessor(string xmlcs, string basefolder, string lcid) : base(xmlcs, basefolder, lcid, null) { @@ -743,15 +705,28 @@ namespace Vrh.Log4Pro.MaintenanceConsole { foreach (var wsxml in wsxmllist) { var ws = new WindowsService(wsxml); if (ws.Valid) { _winservicelist.Add(ws); } } } - _winservicelistinstartorder = ProduceDefinitionListInStartOrder(); - _winservicelistinstoporder = ProduceDefinitionListInStartOrder(); _winservicelistinstoporder.Reverse(); + _winservicelistinstartorder = ProduceWindowsServiceDefinitionListInStartOrder(); + _winservicelistinstoporder = ProduceWindowsServiceDefinitionListInStartOrder(); _winservicelistinstoporder.Reverse(); + + _winservicegrouplist = new List(); + var wsgxmllist = GetAllXElements(nameof(WindowsService.XmlStructure.WindowsServiceGroup)); + if (wsgxmllist != null && wsgxmllist.Any()) + { + foreach (var wsgxml in wsgxmllist) { var wsg = new WindowsServiceGroup(wsgxml); if (wsg.Valid) { _winservicegrouplist.Add(wsg); } } + } } #endregion constructor - #region GetDefinitionList - public List GetDefinitionList() { return _winservicelist; } - public List GetDefinitionListInStartOrder() { return _winservicelistinstartorder; } - public List GetDefinitionListInStopOrder() { return _winservicelistinstoporder; } - private List ProduceDefinitionListInStartOrder() + #region GetWindowsServiceGroupDefinitionList + public WindowsServiceGroup GetWindowsServiceGroup(string key) { return _winservicegrouplist.FirstOrDefault(x => x.Xml_Key == key); } + public List GetWindowsServiceGroupDefinitionList() { return _winservicegrouplist; } + #endregion GetWindowsServiceGroupDefinitionList + + #region GetWindowsServiceDefinitionList + public WindowsService GetWindowsService(string key) { return _winservicelist.FirstOrDefault(x => x.Xml_Key == key); } + public List GetWindowsServiceDefinitionList() { return _winservicelist; } + public List GetWindowsServiceDefinitionListInStartOrder() { return _winservicelistinstartorder; } + public List GetWindowsServiceDefinitionListInStopOrder() { return _winservicelistinstoporder; } + private List ProduceWindowsServiceDefinitionListInStartOrder() { List listinstartorder = new List(); bool ready = false;//akkor lesz false, ha már minden @@ -764,7 +739,7 @@ namespace Vrh.Log4Pro.MaintenanceConsole if (namelistinstartorder.Contains(s.Name)) { continue; }//ez a szerviz már bekerült a startorder listába ready = false; var dl = s.Xml_Dependon; - if (dl.Length == 0) { listinstartorder.Add(s); continue; }//ha nem függ senkitől, betesszük a startorder listába + if (!dl.Any()) { listinstartorder.Add(s); continue; }//ha nem függ senkitől, betesszük a startorder listába foreach (var dli in dl) { if (string.IsNullOrWhiteSpace(dli)) { continue; } @@ -775,7 +750,7 @@ namespace Vrh.Log4Pro.MaintenanceConsole } return listinstartorder; } - #endregion GetDefinitionList + #endregion GetWindowsServiceDefinitionList } #endregion WindowsServiceManagerXmlProcessor class #region WindowsService class @@ -787,8 +762,8 @@ namespace Vrh.Log4Pro.MaintenanceConsole public string DisplayName; public string Description; public string PathName; - public string[] ThisDependsOn; - public string[] ServicesDependOnThis; + public List ThisDependsOn; + public List ServicesDependOnThis; public int ProcessId; public ServiceStartMode StartMode; public string State; @@ -796,6 +771,7 @@ namespace Vrh.Log4Pro.MaintenanceConsole public string StartName; public string PriorityClass; + public string Xml_Key; public string Xml_DisplayName; public string Xml_Description; public string Xml_Exe; @@ -803,7 +779,7 @@ namespace Vrh.Log4Pro.MaintenanceConsole public ServiceStartMode Xml_StartMode; public string Xml_Priority; public string Xml_Arguments; - public string[] Xml_Dependon; + public List Xml_Dependon; public string Xml_RegistrationMode; public ServiceAccount Xml_IdentityType; public string Xml_Username; @@ -819,6 +795,8 @@ namespace Vrh.Log4Pro.MaintenanceConsole public WindowsService(XElement winservicexml) { string ATTRIBUTEMANDATORY = nameof(XmlStructure.WindowsService) + " attribute is mandatory! Name: {0}"; + Xml_Key = GetValue(nameof(XmlStructure.WindowsService.Attributes.Key), winservicexml, ""); + if (string.IsNullOrEmpty(Xml_Key)) { throw new ApplicationException(string.Format(ATTRIBUTEMANDATORY, nameof(XmlStructure.WindowsService.Attributes.Key))); } Name = winservicexml.Attribute(XName.Get(nameof(XmlStructure.WindowsService.Attributes.Name)))?.Value; if (!ValidServiceName(Name)) { @@ -840,13 +818,12 @@ namespace Vrh.Log4Pro.MaintenanceConsole Xml_Priority = GetValue(nameof(XmlStructure.WindowsService.Attributes.Priority), winservicexml, XmlStructure.WindowsService.Attributes.Priority.Values.DEFAULT); Xml_Arguments = GetValue(nameof(XmlStructure.WindowsService.Attributes.Arguments), winservicexml, ""); - var XmlDependon = new List(); + Xml_Dependon = new List(); string[] dependonarray = GetValue(nameof(XmlStructure.WindowsService.Attributes.DependOn), winservicexml, "").Split(new char[] { ',', ';' }, StringSplitOptions.RemoveEmptyEntries); foreach (var ds in dependonarray) { - if (ValidServiceName(ds)) { XmlDependon.Add(ds); } + if (ValidServiceName(ds)) { Xml_Dependon.Add(ds); } } - Xml_Dependon = XmlDependon.ToArray(); Xml_RegistrationMode = GetValue(nameof(XmlStructure.WindowsService.Attributes.RegistrationMode), winservicexml, XmlStructure.WindowsService.Attributes.RegistrationMode.Values.DEFAULT); Xml_RegistrationMode = Xml_RegistrationMode.Replace('-', '_'); @@ -866,12 +843,71 @@ namespace Vrh.Log4Pro.MaintenanceConsole Xml_StopTimeout = GetValue(nameof(XmlStructure.WindowsService.Attributes.StopTimeout), winservicexml, XmlStructure.WindowsService.Attributes.StopTimeout.Values.DEFAULT); } private bool ValidServiceName(string sn) { return !string.IsNullOrWhiteSpace(Name) && sn[0] != '@'; } + #region public CollectWindowsServiceInfo + public WindowsService CollectWindowsServiceInfo() + { + using (var wmiService = WindowsServiceManagerCore.GetServiceObject(this.Name)) + { + using (var service = WindowsServiceManagerCore.GetServiceController(this.Name)) + { + var wmiserviceproblem = false; + try { wmiService.Get(); } catch { wmiserviceproblem = true; } + if (wmiService == null || service == null || wmiserviceproblem) + { + this.DisplayName = this.Xml_DisplayName; + this.Description = this.Xml_Description; + this.ThisDependsOn = this.Xml_Dependon; + this.ServicesDependOnThis = new List() { "???" }; + this.PathName = $"\"{this.Xml_Exe}\" {this.Xml_Arguments}"; + this.StartMode = this.Xml_StartMode; + this.State = nameof(WmiServiceState.Unregistered); + this.Status = nameof(WindowsService.WmiServiceStatus.Unregistered); + if (this.Xml_IdentityType == ServiceAccount.User) { this.StartName = this.Xml_Username + $"({this.Xml_Password})"; } + else { this.StartName = this.Xml_IdentityType.ToString(); } + this.ProcessId = 0; + this.PriorityClass = this.Xml_Priority; + } + else + { + this.DisplayName = (string)wmiService[nameof(WindowsService.DisplayName)]; + this.Description = (string)wmiService[nameof(WindowsService.Description)]; + if (string.IsNullOrEmpty(this.Description)) { this.Description = this.DisplayName; } + if (string.IsNullOrEmpty(this.DisplayName)) { this.DisplayName = this.Description; } + this.ServicesDependOnThis = service.DependentServices.Select(s => s.ServiceName).ToList(); + try { this.ThisDependsOn = service.ServicesDependedOn.Select(s => s.ServiceName).ToList(); } catch { this.ThisDependsOn = new List() { "???" }; } + this.PathName = (string)wmiService[nameof(WindowsService.PathName)]; if (this.PathName == null) { this.PathName = ""; } + var sm = (string)wmiService[nameof(WindowsService.StartMode)]; + this.StartMode = + sm == "Auto" ? ServiceStartMode.Automatic + : sm == "Auto" ? ServiceStartMode.Manual + : sm == "Auto" ? ServiceStartMode.Disabled + : sm == "Auto" ? ServiceStartMode.Boot + : sm == "Auto" ? ServiceStartMode.System + : ServiceStartMode.Manual; + this.State = (string)wmiService[nameof(WindowsService.State)]; + this.Status = (string)wmiService[nameof(WindowsService.Status)]; + this.StartName = (string)wmiService[nameof(WindowsService.StartName)]; + this.ProcessId = 0; + this.PriorityClass = "-"; + if (this.State != nameof(WmiServiceState.Stopped)) + { + this.ProcessId = Convert.ToInt32(wmiService[nameof(WindowsService.ProcessId)]); + this.PriorityClass = Process.GetProcessById(this.ProcessId).PriorityClass.ToString(); + } + } + } + } + return this; + } + #endregion public CollectWindowsServiceInfo + #endregion xml constructor #region cloner constructor public WindowsService(WindowsService ws) { Name = ws.Name; Valid = ws.Valid; + Xml_Key= ws.Xml_Key; Xml_DisplayName = ws.Xml_DisplayName; Xml_Description = ws.Xml_Description; Xml_Exe = ws.Xml_Exe; @@ -891,10 +927,20 @@ namespace Vrh.Log4Pro.MaintenanceConsole #region XmlStructure public static class XmlStructure { + public static class WindowsServiceGroup + { + public static class Attributes + { + public static class Key { public static class Values { public static string DEFAULT = ""; } } + public static class Description { public static class Values { public static string DEFAULT = ""; } } + public static class WindowsServiceKeyList { public static class Values { public static string DEFAULT = ""; } } + } + } public static class WindowsService { public static class Attributes { + public static class Key { public static class Values { public static string DEFAULT = ""; } } public static class Name { } public static class DisplayName { } public static class Description { } @@ -946,7 +992,65 @@ namespace Vrh.Log4Pro.MaintenanceConsole } } #endregion XmlStructure + #region public classes,types + public enum WmiServiceStatus + { + OK, + Error, + Degraded, + Unknown, + Pred_Fail, + Starting, + Stopping, + Service, + Stressed, + NonRecover, + No_Contact, + Lost_Comm, + Unregistered, + } + public enum WmiServiceState + { + StartPending, + Running, + Paused, + PausedPending, + Stopped, + StopPending, + Unknown, + Unregistered, + } + #endregion public classes,types } #endregion WindowsService class - + #region WindowsServiceGroup class + public class WindowsServiceGroup : XmlLinqBase + { + public bool Valid; + public List Xml_WindowsServiceKeyList; + public string Xml_Key; + public string Xml_Description; + public WindowsServiceGroup() { } + public WindowsServiceGroup(WindowsServiceGroup wsg) + { + Xml_Key = wsg.Xml_Key; + Xml_WindowsServiceKeyList = wsg.Xml_WindowsServiceKeyList.Select(x => x).ToList(); + Xml_Description = wsg.Xml_Description; + Valid = wsg.Valid; + } + public WindowsServiceGroup(XElement wsgxml) + { + Xml_Key = GetValue(nameof(WindowsService.XmlStructure.WindowsServiceGroup.Attributes.Key), wsgxml, WindowsService.XmlStructure.WindowsServiceGroup.Attributes.Key.Values.DEFAULT); + Xml_Description = GetValue(nameof(WindowsService.XmlStructure.WindowsServiceGroup.Attributes.Description), wsgxml, WindowsService.XmlStructure.WindowsServiceGroup.Attributes.Description.Values.DEFAULT); + var keycommaliststring = GetValue(nameof(WindowsService.XmlStructure.WindowsServiceGroup.Attributes.WindowsServiceKeyList), wsgxml, WindowsService.XmlStructure.WindowsServiceGroup.Attributes.WindowsServiceKeyList.Values.DEFAULT); + Valid = false; + if (!string.IsNullOrWhiteSpace(keycommaliststring)) + { + Xml_WindowsServiceKeyList = new List(keycommaliststring.Split(new char[] { ',' },StringSplitOptions.RemoveEmptyEntries)); + if (Xml_WindowsServiceKeyList.Contains("*")) { Xml_WindowsServiceKeyList = new List() { "*" }; } + Valid = Xml_WindowsServiceKeyList.Any(); + } + } + } + #endregion WindowsServiceGroup class } diff --git a/Vrh.Log4Pro.MaintenanceConsole/Program.cs b/Vrh.Log4Pro.MaintenanceConsole/Program.cs index a7143ea..c90e42d 100644 --- a/Vrh.Log4Pro.MaintenanceConsole/Program.cs +++ b/Vrh.Log4Pro.MaintenanceConsole/Program.cs @@ -3,11 +3,27 @@ using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; +using System.Threading; using Microsoft.Web.Administration; using System.Management; using System.Diagnostics; +using Vrh.Log4Pro.MaintenanceConsole.ColorConsoleNS; +using Vrh.Log4Pro.MaintenanceConsole.MenuNS; +using Vrh.Log4Pro.MaintenanceConsole.ToolsNS; + +using Vrh.Log4Pro.MaintenanceConsole.WebApplicationManagerNS; +using Vrh.Log4Pro.MaintenanceConsole.WindowsServiceManagerNS; +using Vrh.Log4Pro.MaintenanceConsole.BackupPackageManagerNS; +using Vrh.Log4Pro.MaintenanceConsole.SQLDataBaseManagerNS; +using Vrh.Log4Pro.MaintenanceConsole.ScheduledTaskManagerNS; +using Vrh.Log4Pro.MaintenanceConsole.FileCleanerManagerNS; +using Vrh.Log4Pro.MaintenanceConsole.MaintenanceToolManagerNS; +using Vrh.Log4Pro.MaintenanceConsole.UserManagerNS; + +using Vrh.Log4Pro.MaintenanceConsole.CommandLineParserNS; + using Vrh.XmlProcessing; using VRH.Common; using System.Xml.Linq; @@ -18,12 +34,18 @@ namespace Vrh.Log4Pro.MaintenanceConsole { static void Main(string[] args) { - ColorConsole.ReadLine("Press a key to start..."); - var appconfigpath = CommandLine.GetCommandLineArgument(args, "-APPCONFIG"); + + var forcedmodulekey = CommandLine.GetCommandLineArgument(args, CLP.CMD_MODULE); + var commandmode = !string.IsNullOrEmpty(forcedmodulekey); + var silentmode = commandmode && !string.IsNullOrEmpty(CommandLine.GetCommandLineArgument(args, CLP.CMD_SILENT, switchtype: true)); + ColorConsole.SetSilentMode(silentmode); + Menu.SetCommandMode(commandmode); + + var appconfigpath = CommandLine.GetCommandLineArgument(args, CLP.CMD_APPCONFIG); CommandLine.SetAppConfigFile(appconfigpath); try { ColorConsole.SetWindowSize(120, 64); } - catch (Exception ex) + catch { ColorConsole.WriteLine("Change the size of the console fonts smaller!"); ColorConsole.ReadKey(); @@ -37,27 +59,98 @@ namespace Vrh.Log4Pro.MaintenanceConsole } var mm = new Menu("Log4ProIS Maintenance Console") - .AddMenuItem(new Menu.Item("WAM", "Web Application Manager", WebApplicationManager.Execute)) - .AddMenuItem(new Menu.Item("WSM", "Windows Service Manager", WindowsServiceManager.Execute)) - .AddMenuItem(new Menu.Item("FCL", "File Cleaner Manager", FileCleanerManager.Execute)) - .AddMenuItem(new Menu.Item("SCH", "Scheduled Task Manager", ScheduledTaskmanagerManager.Execute)) + .AddMenuItem(new Menu.Item(CLP.Module.WebApplicationManager.KEY, "Web Application Manager", WebApplicationManager.Execute, new Menu.ExecutorParameter(args: args))) + .AddMenuItem(new Menu.Item(CLP.Module.WindowsServiceManager.KEY, "Windows Service Manager", WindowsServiceManager.Execute, new Menu.ExecutorParameter(args: args))) + .AddMenuItem(new Menu.Item(CLP.Module.FileCleanerManager.KEY, "File Cleaner Manager", FileCleanerManager.Execute, new Menu.ExecutorParameter(args: args))) + .AddMenuItem(new Menu.Item(CLP.Module.ScheduledTaskManager.KEY, "Scheduled Task Manager", ScheduledTaskManager.Execute, new Menu.ExecutorParameter(args: args))) + .AddMenuItem(new Menu.Item(CLP.Module.BackupPackageManager.KEY, "Backup Package Manager", BackupPackageManager.Execute, new Menu.ExecutorParameter(args: args))) + .AddMenuItem(new Menu.Item(CLP.Module.SQLDataBaseManager.KEY, "SQL Database Manager", SQLDataBaseManager.Execute, new Menu.ExecutorParameter(args: args))) + .AddMenuItem(new Menu.Item(CLP.Module.Log4ProUserManager.KEY, "Log4Pro User Manager", UserManager.Execute, new Menu.ExecutorParameter(args: args))) .AddMenuItem(new Menu.ItemSeparator('-')) - .AddMenuItem(new Menu.Item("TOL", "Maintenance tools", MaintenanceToolManager.Execute)) + .AddMenuItem(new Menu.Item(CLP.Module.MaintenanceToolManager.KEY, "Maintenance tools", MaintenanceToolManager.Execute, new Menu.ExecutorParameter(args: args))) + .SetMenuHeaderDisplayer(DisplayComputerInfo) .SetSelectionMode(Menu.SelectionMode.Single); - var commandmode = !string.IsNullOrEmpty(CommandLine.GetCommandLineArgument(args, "-MODULE")); - if (commandmode) + mm.ExecuteMenu(forcedmodulekey); + + ColorConsole.PressAnykeyToContinue(); + } + static void DisplayComputerInfo() + { + const string XMLCONNECTIONSTRING = "config=MAINTENANCECONSOLE;"; + const string XMLCONNECTIONSTRING_DEFAULT = "file=Config.Xml;"; + var config = new MaintenanceConsoleXmlProcessor(XMLCONNECTIONSTRING, "", "hu-HU"); + + ColorConsole.WriteLine(config.Xml_Header,ConsoleColor.Yellow,bracket:"[]"); + + //computername + ColorConsole.WriteLine(""); + ColorConsole.Write("Computer name: "); + ColorConsole.Write(System.Environment.MachineName, ConsoleColor.Yellow, bracket: "[]",prefix: "", suffix: ","); + var hostname = System.Net.Dns.GetHostName(); + ColorConsole.Write(hostname, ConsoleColor.Yellow, bracket: "[]", prefix: "DNS hostname:"); + ColorConsole.WriteLine(""); + + //username + ColorConsole.Write("Username:"); + ColorConsole.Write(Environment.UserName, ConsoleColor.Yellow, bracket: "[]", prefix: "RunAs:", suffix: ","); + ColorConsole.Write(System.Security.Principal.WindowsIdentity.GetCurrent().Name, ConsoleColor.Yellow, bracket: "[]", prefix: "LoggedIn:"); + ColorConsole.WriteLine(""); + + //ip address + ColorConsole.Write("IP addresses: "); + var host = System.Net.Dns.GetHostEntry(hostname); + foreach (var ip in host.AddressList) { - var silentmode = !string.IsNullOrEmpty(CommandLine.GetCommandLineArgument(args, "-SILENT", switchtype: true)); - ColorConsole.SetSilentMode(silentmode); - Menu.SetCommandModeAllMenus(); - mm.ExecuteCmd(args); + if (ip.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork) + { + ColorConsole.Write(ip.ToString(), ConsoleColor.Yellow, bracket: "[]", prefix: $"{ip.AddressFamily}:",suffix: ","); + } } - else + ColorConsole.WriteLine(""); + + // processor architecture + ColorConsole.Write("Processors: "); + ColorConsole.Write(System.Environment.GetEnvironmentVariable("PROCESSOR_ARCHITECTURE"), ConsoleColor.Yellow, bracket: "[]", prefix: "Architecture: ",suffix:", "); + foreach (var item in new System.Management.ManagementObjectSearcher("Select * from Win32_ComputerSystem").Get()) + { + ColorConsole.Write(item["NumberOfProcessors"].ToString(), ConsoleColor.Yellow, bracket: "[]", prefix: "Physical:",suffix:", "); + ColorConsole.Write(item["NumberOfLogicalProcessors"].ToString(), ConsoleColor.Yellow, bracket: "[]", prefix: "Logical:", suffix: ", "); + } + + int coreCount = 0; + foreach (var item in new System.Management.ManagementObjectSearcher("Select * from Win32_Processor").Get()) { - mm.ExecuteMenu(); - ColorConsole.PressAnykeyToContinue(); + coreCount += int.Parse(item["NumberOfCores"].ToString()); } + ColorConsole.Write(coreCount.ToString(), ConsoleColor.Yellow, bracket: "[]", prefix: "Cores:"); + ColorConsole.WriteLine(""); + + // os version + ColorConsole.Write("Operating system: "); + ColorConsole.Write(System.Environment.OSVersion.Platform.ToString(), ConsoleColor.Yellow, bracket: "[]", prefix: "Platform:",suffix: ","); + ColorConsole.Write(System.Environment.OSVersion.ServicePack, ConsoleColor.Yellow, bracket: "[]", prefix: "Service pack:", suffix: ","); + ColorConsole.Write(System.Environment.OSVersion.VersionString, ConsoleColor.Yellow, bracket: "[]", prefix: "Version string:"); + ColorConsole.WriteLine(""); + ColorConsole.WriteLine(""); + } + } + #region MaintenanceConsoleXmlProcessor class + public class MaintenanceConsoleXmlProcessor : XmlParser + { + public string Xml_Header; + #region constructor + public MaintenanceConsoleXmlProcessor(string xmlcs, string basefolder, string lcid) : base(xmlcs, basefolder, lcid, null) + { + Xml_Header = GetValue(GetXElement(nameof(XmlStructure.Header)),""); + } + #endregion constructor + #region XmlStructure + public static class XmlStructure + { + public static class Header { } } + #endregion XmlStructure } + #endregion MaintenanceConsoleXmlProcessor class } diff --git a/Vrh.Log4Pro.MaintenanceConsole/Vrh.Log4Pro.MaintenanceConsole.csproj b/Vrh.Log4Pro.MaintenanceConsole/Vrh.Log4Pro.MaintenanceConsole.csproj index 105c84b..1862d05 100644 --- a/Vrh.Log4Pro.MaintenanceConsole/Vrh.Log4Pro.MaintenanceConsole.csproj +++ b/Vrh.Log4Pro.MaintenanceConsole/Vrh.Log4Pro.MaintenanceConsole.csproj @@ -9,12 +9,13 @@ Exe Vrh.Log4Pro.MaintenanceConsole Vrh.Log4Pro.MaintenanceConsole - v4.6.2 + v4.7.2 512 true true + AnyCPU @@ -35,6 +36,9 @@ prompt 4 + + servicelogo.ico + ..\packages\EntityFramework.6.4.4\lib\net45\EntityFramework.dll @@ -42,6 +46,117 @@ ..\packages\EntityFramework.6.4.4\lib\net45\EntityFramework.SqlServer.dll + + ..\packages\Microsoft.Data.SqlClient.2.0.0\lib\net46\Microsoft.Data.SqlClient.dll + + + ..\packages\Microsoft.SqlServer.SqlManagementObjects.161.46041.41\lib\net462\Microsoft.Data.Tools.Sql.BatchParser.dll + + + ..\packages\Microsoft.Identity.Client.4.14.0\lib\net45\Microsoft.Identity.Client.dll + + + ..\packages\Microsoft.IdentityModel.JsonWebTokens.5.6.0\lib\net461\Microsoft.IdentityModel.JsonWebTokens.dll + + + ..\packages\Microsoft.IdentityModel.Logging.5.6.0\lib\net461\Microsoft.IdentityModel.Logging.dll + + + ..\packages\Microsoft.IdentityModel.Protocols.5.6.0\lib\net461\Microsoft.IdentityModel.Protocols.dll + + + ..\packages\Microsoft.IdentityModel.Protocols.OpenIdConnect.5.6.0\lib\net461\Microsoft.IdentityModel.Protocols.OpenIdConnect.dll + + + ..\packages\Microsoft.IdentityModel.Tokens.5.6.0\lib\net461\Microsoft.IdentityModel.Tokens.dll + + + ..\packages\Microsoft.SqlServer.Assessment.1.0.280\lib\net462\Microsoft.SqlServer.Assessment.dll + + + ..\packages\Microsoft.SqlServer.Assessment.Authoring.1.0.280\lib\net462\Microsoft.SqlServer.Assessment.Types.dll + + + ..\packages\Microsoft.SqlServer.SqlManagementObjects.161.46041.41\lib\net462\Microsoft.SqlServer.ConnectionInfo.dll + + + ..\packages\Microsoft.SqlServer.SqlManagementObjects.161.46041.41\lib\net462\Microsoft.SqlServer.Dmf.dll + + + ..\packages\Microsoft.SqlServer.SqlManagementObjects.161.46041.41\lib\net462\Microsoft.SqlServer.Dmf.Common.dll + + + ..\packages\Microsoft.SqlServer.SqlManagementObjects.161.46041.41\lib\net462\Microsoft.SqlServer.Management.Assessment.dll + + + ..\packages\Microsoft.SqlServer.SqlManagementObjects.161.46041.41\lib\net462\Microsoft.SqlServer.Management.Collector.dll + + + ..\packages\Microsoft.SqlServer.SqlManagementObjects.161.46041.41\lib\net462\Microsoft.SqlServer.Management.CollectorEnum.dll + + + ..\packages\Microsoft.SqlServer.SqlManagementObjects.161.46041.41\lib\net462\Microsoft.SqlServer.Management.HadrData.dll + + + ..\packages\Microsoft.SqlServer.SqlManagementObjects.161.46041.41\lib\net462\Microsoft.SqlServer.Management.HadrModel.dll + + + ..\packages\Microsoft.SqlServer.SqlManagementObjects.161.46041.41\lib\net462\Microsoft.SqlServer.Management.RegisteredServers.dll + + + ..\packages\Microsoft.SqlServer.SqlManagementObjects.161.46041.41\lib\net462\Microsoft.SqlServer.Management.Sdk.Sfc.dll + + + ..\packages\Microsoft.SqlServer.SqlManagementObjects.161.46041.41\lib\net462\Microsoft.SqlServer.Management.SmoMetadataProvider.dll + + + ..\packages\Microsoft.SqlServer.Management.SqlParser.160.20216.14\lib\net462\Microsoft.SqlServer.Management.SqlParser.dll + + + ..\packages\Microsoft.SqlServer.SqlManagementObjects.161.46041.41\lib\net462\Microsoft.SqlServer.Management.SqlScriptPublish.dll + + + ..\packages\Microsoft.SqlServer.SqlManagementObjects.161.46041.41\lib\net462\Microsoft.SqlServer.Management.XEvent.dll + + + ..\packages\Microsoft.SqlServer.SqlManagementObjects.161.46041.41\lib\net462\Microsoft.SqlServer.Management.XEventDbScoped.dll + + + ..\packages\Microsoft.SqlServer.SqlManagementObjects.161.46041.41\lib\net462\Microsoft.SqlServer.Management.XEventDbScopedEnum.dll + + + ..\packages\Microsoft.SqlServer.SqlManagementObjects.161.46041.41\lib\net462\Microsoft.SqlServer.Management.XEventEnum.dll + + + ..\packages\Microsoft.SqlServer.SqlManagementObjects.161.46041.41\lib\net462\Microsoft.SqlServer.PolicyEnum.dll + + + ..\packages\Microsoft.SqlServer.SqlManagementObjects.161.46041.41\lib\net462\Microsoft.SqlServer.RegSvrEnum.dll + + + ..\packages\Microsoft.SqlServer.SqlManagementObjects.161.46041.41\lib\net462\Microsoft.SqlServer.ServiceBrokerEnum.dll + + + ..\packages\Microsoft.SqlServer.SqlManagementObjects.161.46041.41\lib\net462\Microsoft.SqlServer.Smo.dll + + + ..\packages\Microsoft.SqlServer.SqlManagementObjects.161.46041.41\lib\net462\Microsoft.SqlServer.Smo.Notebook.dll + + + ..\packages\Microsoft.SqlServer.SqlManagementObjects.161.46041.41\lib\net462\Microsoft.SqlServer.SmoExtended.dll + + + ..\packages\Microsoft.SqlServer.SqlManagementObjects.161.46041.41\lib\net462\Microsoft.SqlServer.SqlClrProvider.dll + + + ..\packages\Microsoft.SqlServer.SqlManagementObjects.161.46041.41\lib\net462\Microsoft.SqlServer.SqlEnum.dll + + + ..\packages\Microsoft.SqlServer.SqlManagementObjects.161.46041.41\lib\net462\Microsoft.SqlServer.SqlWmiManagement.dll + + + ..\packages\Microsoft.SqlServer.SqlManagementObjects.161.46041.41\lib\net462\Microsoft.SqlServer.WmiEnum.dll + ..\packages\Microsoft.Web.Administration.11.1.0\lib\netstandard1.5\Microsoft.Web.Administration.dll @@ -51,17 +166,22 @@ ..\packages\Microsoft.Win32.Registry.4.0.0\lib\net46\Microsoft.Win32.Registry.dll + + ..\packages\Newtonsoft.Json.11.0.1\lib\net45\Newtonsoft.Json.dll + ..\packages\System.AppContext.4.1.0\lib\net46\System.AppContext.dll + ..\packages\System.Console.4.0.0\lib\net46\System.Console.dll + ..\packages\System.Diagnostics.DiagnosticSource.4.0.0\lib\net46\System.Diagnostics.DiagnosticSource.dll @@ -71,9 +191,14 @@ ..\packages\System.Diagnostics.Tracing.4.1.0\lib\net462\System.Diagnostics.Tracing.dll + ..\packages\System.Globalization.Calendars.4.0.1\lib\net46\System.Globalization.Calendars.dll + + + ..\packages\System.IdentityModel.Tokens.Jwt.5.6.0\lib\net461\System.IdentityModel.Tokens.Jwt.dll + ..\packages\System.IO.4.1.0\lib\net462\System.IO.dll @@ -140,23 +265,34 @@ + + ..\packages\Microsoft.AspNet.Providers.Core.2.0.0\lib\net40\System.Web.Providers.dll + + - - ..\packages\VRH.Common.2.19.1\lib\net45\VRH.Common.dll + + ..\packages\VRH.Common.2.20.1\lib\net45\VRH.Common.dll + + + ..\packages\VRH.Web.Providers.2.0.2\lib\net452\Vrh.Web.Providers.dll - - ..\packages\Vrh.XmlProcessing.1.23.0\lib\net45\Vrh.XmlProcessing.dll + + ..\packages\Vrh.XmlProcessing.1.24.0\lib\net45\Vrh.XmlProcessing.dll + + + + @@ -170,6 +306,8 @@ Always + + @@ -177,11 +315,14 @@ Always + Always - + + + @@ -189,6 +330,8 @@ + + \ No newline at end of file diff --git a/Vrh.Log4Pro.MaintenanceConsole/XmlParser.xml b/Vrh.Log4Pro.MaintenanceConsole/XmlParser.xml index f0a0a22..de951e8 100644 --- a/Vrh.Log4Pro.MaintenanceConsole/XmlParser.xml +++ b/Vrh.Log4Pro.MaintenanceConsole/XmlParser.xml @@ -1,140 +1,20 @@  - + - 127.0.0.1 - @SINGLESERVERIP@ - WebALM - - @SINGLESERVERIP@ - WebPack - - @SINGLESERVERIP@ - WebAndon - - - - c:\Log4ProIS - c:\Log4ProIS\CONFIG - @APPROOTPATH@\VRH.Log4Pro.ACALM - - @APPROOTPATH@\wwwroot_Log4ProIS - @WEBAPPROOT@\App_Data - @WEBAPPROOT@\App_Data\ALM - @WEBAPPROOT@\App_Data\CP - @WEBAPPROOT@\App_Data\ANDON - @WEBAPPROOT@\App_Data\IS-TRM - - @APPROOTPATH@\wwwroot_WebPack - @WEBAPPROOT_WEBPACK@\App_Data - - @APPROOTPATH@\wwwroot_WebAndon - @WEBAPPROOT_ANDON@\App_Data - - @APPROOTPATH@\wwwroot_WebALM - @WEBAPPROOT_ALM@\App_Data - - @APPROOTPATH@\VRH.Log4Pro.ASEDC-DCWF_ALM\ - @APPROOTPATH@\VRH.Log4Pro.ASEDC-DCWF_CP\ - @APPROOTPATH@\VRH.Log4Pro.ASEDC-ASEMON\ - - localhost - c:\Log4ProISBackups - - @ALMBACKUPS@\Documents - - - @APPDATA@\WebMonitor\XmlParserButtonDefinitions.xml - - false - SITE_SLNOTEBOOKDELL + c:\Log4ProIS + @APPROOTPATH@\MAINTENANCECONSOLE - - - true - - true - Menu.Xml - Accordion - max-width:40vmax; - max-width:80vmax; - max-width:120vmax; - max-width:90vmax;margin 100; padding 10; - max-width:50vmax;font-size:larger;color:white; - max-width:70vmax;font-size:larger;color:white; - max-width:100vmax;font-size:larger;color:white; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + - \ No newline at end of file + diff --git a/Vrh.Log4Pro.MaintenanceConsole/packages.config b/Vrh.Log4Pro.MaintenanceConsole/packages.config index 452ae56..80ad71a 100644 --- a/Vrh.Log4Pro.MaintenanceConsole/packages.config +++ b/Vrh.Log4Pro.MaintenanceConsole/packages.config @@ -1,12 +1,27 @@  + + + + + + + + + + + + + + - + + @@ -17,13 +32,14 @@ + - - + + @@ -41,7 +57,7 @@ - + @@ -49,12 +65,13 @@ - + - - + + + \ No newline at end of file diff --git a/Vrh.Log4Pro.MaintenanceConsole/servicelogo.ico b/Vrh.Log4Pro.MaintenanceConsole/servicelogo.ico new file mode 100644 index 0000000..da8249c Binary files /dev/null and b/Vrh.Log4Pro.MaintenanceConsole/servicelogo.ico differ diff --git a/Vrh.Log4Pro.MaintenanceConsole/system.web.membership.config b/Vrh.Log4Pro.MaintenanceConsole/system.web.membership.config new file mode 100644 index 0000000..eeb5c18 --- /dev/null +++ b/Vrh.Log4Pro.MaintenanceConsole/system.web.membership.config @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/Vrh.Log4Pro.MaintenanceConsole/system.web.rolemanager.config b/Vrh.Log4Pro.MaintenanceConsole/system.web.rolemanager.config new file mode 100644 index 0000000..4f31321 --- /dev/null +++ b/Vrh.Log4Pro.MaintenanceConsole/system.web.rolemanager.config @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file -- libgit2 0.21.2