From e76b511841ab3d83d20a74db6ffb58cbb75bce30 Mon Sep 17 00:00:00 2001 From: Schwirg László Date: Wed, 23 Dec 2020 20:10:14 +0100 Subject: [PATCH] FileCleanerManager és MaintenanceToolManager/RegexTester elkészítése --- Vrh.Log4Pro.MaintenanceConsole/App.config | 11 ++++++++++- Vrh.Log4Pro.MaintenanceConsole/Config.xml | 40 +++++++++++++++++++++++++++++++++++----- Vrh.Log4Pro.MaintenanceConsole/ConsoleFunction - ColorConsole.cs | 2 +- Vrh.Log4Pro.MaintenanceConsole/ConsoleFunction - Menu.cs | 37 +++++++++++++++++++++++++++++++++++-- Vrh.Log4Pro.MaintenanceConsole/Manager - FileCleanerManager.cs | 504 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Vrh.Log4Pro.MaintenanceConsole/Manager - MaintenanceToolManager.cs | 124 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Vrh.Log4Pro.MaintenanceConsole/Manager - WebApplicationManager.cs | 939 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Vrh.Log4Pro.MaintenanceConsole/Manager - WindowsServiceManager.cs | 952 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Vrh.Log4Pro.MaintenanceConsole/Program.cs | 3 +++ Vrh.Log4Pro.MaintenanceConsole/Vrh.Log4Pro.MaintenanceConsole.csproj | 28 ++++++++++++++++++++++++++-- Vrh.Log4Pro.MaintenanceConsole/Vrh.NugetModuls.Documentations/VRH.Common/ReadMe.md | 297 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Vrh.Log4Pro.MaintenanceConsole/WebApplicationManager.cs | 939 --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Vrh.Log4Pro.MaintenanceConsole/WindowsServiceManager.cs | 952 ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Vrh.Log4Pro.MaintenanceConsole/packages.config | 2 ++ 14 files changed, 2928 insertions(+), 1902 deletions(-) create mode 100644 Vrh.Log4Pro.MaintenanceConsole/Manager - FileCleanerManager.cs create mode 100644 Vrh.Log4Pro.MaintenanceConsole/Manager - MaintenanceToolManager.cs create mode 100644 Vrh.Log4Pro.MaintenanceConsole/Manager - WebApplicationManager.cs create mode 100644 Vrh.Log4Pro.MaintenanceConsole/Manager - WindowsServiceManager.cs create mode 100644 Vrh.Log4Pro.MaintenanceConsole/Vrh.NugetModuls.Documentations/VRH.Common/ReadMe.md delete mode 100644 Vrh.Log4Pro.MaintenanceConsole/WebApplicationManager.cs delete mode 100644 Vrh.Log4Pro.MaintenanceConsole/WindowsServiceManager.cs diff --git a/Vrh.Log4Pro.MaintenanceConsole/App.config b/Vrh.Log4Pro.MaintenanceConsole/App.config index 507f944..e8d9451 100644 --- a/Vrh.Log4Pro.MaintenanceConsole/App.config +++ b/Vrh.Log4Pro.MaintenanceConsole/App.config @@ -1,10 +1,14 @@  + + +
+ - + @@ -14,4 +18,9 @@ + + + + + \ No newline at end of file diff --git a/Vrh.Log4Pro.MaintenanceConsole/Config.xml b/Vrh.Log4Pro.MaintenanceConsole/Config.xml index 1e83aec..0707af0 100644 --- a/Vrh.Log4Pro.MaintenanceConsole/Config.xml +++ b/Vrh.Log4Pro.MaintenanceConsole/Config.xml @@ -70,11 +70,11 @@ C:\Log4ProISBackups @DIR_ROOTBAK@\MSMQtests - @DIR_ROOTBAK@\VRH.Logfiles - @ILOG@\RedisLog - @ILOG@\WindowsEventLogs - @ILOG@\WindowsEventLogs - @ILOG@\ServiceScriptLogs + @DIR_ROOTBAK@\VRH.Logfiles + @DIR_ILOG@\RedisLog + @DIR_ILOG@\WindowsEventLogs + @DIR_ILOG@\WindowsEventLogs + @DIR_ILOG@\ServiceScriptLogs @DIR_ROOTBAK@\SystemBackups @DIR_ROOTBAK@\BackupDBOnly @DIR_ROOTBAK@\TEMP @@ -157,4 +157,34 @@ + + + + ^.*\\L_.*_(?'YEAR'\d\d\d\d)(?'MONTH'\d\d)(?'DAY'\d\d)_(?'HOUR'\d\d)(?'MINUTE'\d\d)(?'SECOND'\d\d)$ + + + + + + + ^.*\\VRH.Log4Pro.DataController.WindowsService.exe.*\.dmp$ + + + + + + ^.*\\SQLDBBackup_Lear.*_.*_(?'YEAR'\d\d\d\d)(?'MONTH'\d\d)(?'DAY'\d\d)(?'HOUR'\d\d)(?'MINUTE'\d\d)(?'SECOND'\d\d)\.(bak|zip)$ + + + + + + ^.*\\\d\d\d\d\d\d\d\d\\LearALM_.*_BackupPackage.*(?'YEAR'\d\d\d\d)(?'MONTH'\d\d)(?'DAY'\d\d)(?'HOUR'\d\d)(?'MINUTE'\d\d)(?'SECOND'\d\d).*\.exe$ + + + + + + + \ No newline at end of file diff --git a/Vrh.Log4Pro.MaintenanceConsole/ConsoleFunction - ColorConsole.cs b/Vrh.Log4Pro.MaintenanceConsole/ConsoleFunction - ColorConsole.cs index f91854d..5a4a8fb 100644 --- a/Vrh.Log4Pro.MaintenanceConsole/ConsoleFunction - ColorConsole.cs +++ b/Vrh.Log4Pro.MaintenanceConsole/ConsoleFunction - ColorConsole.cs @@ -48,7 +48,7 @@ namespace Vrh.Log4Pro.MaintenanceConsole Console.ForegroundColor = savecolorF; Console.BackgroundColor = savecolorB; if (!string.IsNullOrEmpty(bracket)) { Console.Write($"{bracket[1]}"); } - if (!string.IsNullOrEmpty(prefix)) { Write(suffix); } + if (!string.IsNullOrEmpty(suffix)) { Write(suffix); } } } #endregion ColorConsole diff --git a/Vrh.Log4Pro.MaintenanceConsole/ConsoleFunction - Menu.cs b/Vrh.Log4Pro.MaintenanceConsole/ConsoleFunction - Menu.cs index d6bd869..acca9e2 100644 --- a/Vrh.Log4Pro.MaintenanceConsole/ConsoleFunction - Menu.cs +++ b/Vrh.Log4Pro.MaintenanceConsole/ConsoleFunction - Menu.cs @@ -31,7 +31,7 @@ namespace Vrh.Log4Pro.MaintenanceConsole #region public properties public List MenuItemList { get; private set; } = new List(); - List MenuKeyList { get { return MenuItemList.Select(x => x.Key).ToList(); } } + List MenuKeyList { get { return MenuItemList.Where(x=> !x.Separator).Select(x => x.Key).ToList(); } } #endregion public properties #region public tools @@ -85,6 +85,17 @@ namespace Vrh.Log4Pro.MaintenanceConsole Console.SetCursorPosition(0, Console.CursorTop); foreach (var menuitem in MenuItemList) { + if (menuitem.Separator && columns == 1) + { + Console.SetCursorPosition(columnlength * columncounter + HeaderWidth, Console.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; } } + } + ColorConsole.WriteLine(new string(menuitem.SeparatorChar, seplen)); + continue; + } ColorConsole.Write($"["); ColorConsole.Write($"{i}"); if (!string.IsNullOrEmpty(menuitem.Key) && !menuitem.Key.StartsWith("#$KEY")) @@ -249,7 +260,15 @@ namespace Vrh.Log4Pro.MaintenanceConsole } private Menu.Item GetItem(int ix) { - return MenuItemList.ElementAt(ix); + var i = 0; + foreach (var mi in MenuItemList) + { + if (mi.Separator) { continue; } + if (i == ix) return mi; + i++; + } + return null; + //return MenuItemList.ElementAt(ix); } private int GetItemIx(string itemkey) { @@ -271,8 +290,18 @@ namespace Vrh.Log4Pro.MaintenanceConsole } } #endregion private tools + public class ItemSeparator : Item + { + public ItemSeparator(char c = '-', int length = 0) : base() + { + Separator = true; + SeparatorChar = c; + SeparatorLength = length; + } + } public class Item { + public Item() { } public Item(string key, string text, MenuItemExecutorFunc executor = null, object parameters = null) { Key = key; @@ -284,6 +313,10 @@ namespace Vrh.Log4Pro.MaintenanceConsole public string Text; public MenuItemExecutorFunc Executor; public object Parameters; + + public bool Separator = false; + public char SeparatorChar = '-'; + public int SeparatorLength = 0; } } } diff --git a/Vrh.Log4Pro.MaintenanceConsole/Manager - FileCleanerManager.cs b/Vrh.Log4Pro.MaintenanceConsole/Manager - FileCleanerManager.cs new file mode 100644 index 0000000..02424d0 --- /dev/null +++ b/Vrh.Log4Pro.MaintenanceConsole/Manager - FileCleanerManager.cs @@ -0,0 +1,504 @@ +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.XmlProcessing; +using System.Xml.Linq; +using System.Text.RegularExpressions; + +namespace Vrh.Log4Pro.MaintenanceConsole +{ + #region FileCleanerManager class + public static class FileCleanerManager + { + #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 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.SetParameters(sr,config); + menufunctions.Execute(sr.SelectedKeyList); + } + return null; + } + #endregion Execute + + #region First level Executors with UI + private static object CleanFolder(object parameter, object o) + { + var config = parameter as FileCleanerManagerCoreXmlProcessor; + + var menufolders = DisplayFolders(config, $"Select the folder(s) to manage with function '{nameof(CleanFolder)}'!", silent: true); + + Menu.Selection sr = menufolders.Select(); + 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) + { + 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); + } + } + return o; + } + #endregion First level Executors with UI + + #region private methods + #region private DisplayFolders + private static Menu DisplayFolders(FileCleanerManagerCoreXmlProcessor config,string prompt = null,bool silent=false) + { + List fctdefList = config.GetDefinitionList(); + var menufct = new Menu("Folder to clean",prompt) + .SetMenuItemDisplayer(DisplayFolderInfo) + .SetSelectionMode(Menu.SelectionMode.Multi) + .SetHeaderWidth(4); + menufct.ClearMenuItemList(); + foreach (var fctdef in fctdefList) + { + var fi = CollectFolderInfo(fctdef); + menufct.AddMenuItem(new Menu.Item(null, null, null, fi)); + } + if (!silent) { menufct.DisplayItems(1); } + return menufct; + } + #endregion private DisplayFolders + #region private method: DisplayFolderInfo + private static object DisplayFolderInfo(object obj, int lineix) + { + FolderToClean ws = obj as FolderToClean; + if (lineix == 0) + { + ColorConsole.Write($"{ws.Xml_DirectoryPath}", ConsoleColor.Black, ConsoleColor.White); + var existscolor = ws.FolderExists ? ConsoleColor.Green : ConsoleColor.Red; + var existstext = ws.FolderExists ? "Exists" : "Missing"; + ColorConsole.WriteLine(existstext, existscolor, bracket: "[]", prefix: " ", suffix: ". "); + return " "; + } + else if (lineix == 1) + { + if (ws.FolderExists) + { + ColorConsole.Write(ws.SizeSelectedBeforeClean.ToString(), ConsoleColor.Yellow, prefix: "Size of filtered files now:"); + ColorConsole.Write(ws.SizeSelectedAfterClean.ToString(), ConsoleColor.Yellow, prefix: ", after cleaning:", suffix: ". "); + ColorConsole.Write(ws.SizeSelectedCleaned.ToString(), ConsoleColor.Red, prefix: "To clean:", suffix: "."); + ColorConsole.WriteLine(" "); + return " "; + } + return ""; + } + else if (lineix == 2) + { + ColorConsole.Write($"{ws.Xml_CleanupDays}", ConsoleColor.Yellow, prefix: "Cleanup days:", bracket: "[]"); + var fc2 = ws.Xml_Recurse ? ConsoleColor.Green : ConsoleColor.Yellow; + ColorConsole.Write($"{ws.Xml_Recurse}", fc2, prefix: ", Recurse:", bracket: "[]"); + var fc0 = ws.Xml_RemoveEmptyFolder ? ConsoleColor.Green : ConsoleColor.Yellow; + ColorConsole.Write($"{ws.Xml_RemoveEmptyFolder}", fc0, prefix: ", Remove empty folder:", bracket: "[]"); + ColorConsole.WriteLine(ws.Xml_IncludeMask, ConsoleColor.Yellow, prefix: ", Include mask:"); + return " "; + } + else // if (lineix == INDEXBASE) + { + const int INDEXBASE = 3; // a linex következő indexe kerüljön ide !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + if (ws.Xml_ConditionList.Count <= lineix - INDEXBASE) { return null; } + var c = ws.Xml_ConditionList.ElementAt(lineix- INDEXBASE); + if (c != null) + { + if (lineix != INDEXBASE) { ColorConsole.Write(ws.Xml_OrConditionList ? "OR" : "AND", ConsoleColor.Yellow,suffix:" "); } + ColorConsole.Write("Condition:"); + ColorConsole.Write(c.Type.ToString(),ConsoleColor.Yellow, prefix: " Type:"); + if (c.Type==FolderToClean.ConditionType.TimeStampInName) { ColorConsole.Write(c.TimestampConstructor, ConsoleColor.Yellow, prefix: ", TS constructor:"); } + ColorConsole.Write(c.Limit.ToString(), ConsoleColor.Yellow, prefix: ", Limit:",suffix: c.Type == FolderToClean.ConditionType.Length ? "bytes" : "days"); + ColorConsole.WriteLine(); + return " "; + } + } + return null; + } + #endregion private method: DisplayFolderInfo + #region private CollectFolderInfo + private static FolderToClean CollectFolderInfo(FolderToClean ftc) + { + ftc.SizeFolderTotal= 0; + ftc.SizeSelectedBeforeClean = 0; + ftc.SizeSelectedCleaned = 0; + ftc.FolderExists = Directory.Exists(ftc.Xml_DirectoryPath); + if (ftc.FolderExists) + { + var di = new DirectoryInfo(ftc.Xml_DirectoryPath); + ftc.SizeFolderTotal = FileCleanerManagerCore.DirSize(di,"*","",ftc.Xml_Recurse); + ftc.SizeSelectedBeforeClean = FileCleanerManagerCore.DirSize(di, ftc.Xml_IncludeMask, ftc.Xml_IncludeFullpathRegexp, ftc.Xml_Recurse); + ftc.SizeSelectedCleaned = FileCleanerManagerCore.CleanFolderFiles(di,ftc,delete:false); + } + return ftc; + } + #endregion private CollectFolderInfo + #endregion private methods + } + #endregion FileCleanerManager class + + #region class FileCleanerManagerCore + public static class FileCleanerManagerCore + { + #region public GetDirSize + public static long DirSize(DirectoryInfo d, string filenamemask, string filefullpathregex, bool recurse) + { + long size = 0; + // Add file sizes. + FileInfo[] fis = d.GetFiles(filenamemask, SearchOption.TopDirectoryOnly); + foreach (FileInfo fi in fis) { if (Regex.Match(fi.FullName, filefullpathregex).Success) { size += fi.Length; } } + // Add subdirectory sizes. + if (recurse) + { + DirectoryInfo[] dis = d.GetDirectories(); + foreach (DirectoryInfo di in dis) { size += DirSize(di, filenamemask, filefullpathregex, recurse); } + } + return size; + } + #endregion public GetDirSize + #region public FileIsToDelete + public static bool FileIsToDelete(FileInfo fi, FolderToClean ftc) + { + var rgx = new Regex(ftc.Xml_IncludeFullpathRegexp); + var rgxmatch = rgx.Match(fi.FullName); + if (rgxmatch.Success) + { + var daystodelete = ftc.Xml_CleanupDays; + var conditionlist = ftc.Xml_ConditionList; + if (conditionlist == null || !conditionlist.Any()) { return true; } + + bool fileistodeleteResult = !ftc.Xml_OrConditionList; + + var groupnames = rgx.GetGroupNames(); + var groupnamevalues = new Dictionary(); + foreach (var rgxgn in groupnames) { groupnamevalues.Add(rgxgn, rgxmatch.Groups[rgxgn].Value); } + + foreach (var c in ftc.Xml_ConditionList) + { + bool conditionresult = false; + if (c.Type == FolderToClean.ConditionType.TimeStampInName) + { + var fileTSstr = VRH.Common.StringConstructor.ResolveConstructor(groupnamevalues, c.TimestampConstructor, "{}"); + try { var fileTS = DateTime.Parse(fileTSstr); conditionresult = DateTime.Now.Subtract(fileTS).TotalDays > c.Limit; } + catch + { + var tscn = nameof(FolderToClean.XmlStructure.FolderToClean.Conditions.Condition.Attributes.TimestampConstructor); + var fprn = nameof(FolderToClean.XmlStructure.FolderToClean.IncludeFullpathRegexp); + throw new Exception( + $"Error in condition, type {FolderToClean.ConditionType.TimeStampInName}. {tscn} or {fprn} value incorrect!" + + $"\n Folder: {ftc.Xml_DirectoryPath}" + + $"\n {tscn} : {c.TimestampConstructor}" + + $"\n {tscn} after substitution: {fileTSstr}"); + } + } + else if (c.Type == FolderToClean.ConditionType.CreationTime) + { + conditionresult = DateTime.Now.Subtract(fi.CreationTime).TotalDays > c.Limit; + } + else if (c.Type == FolderToClean.ConditionType.LastAccessTime) + { + conditionresult = DateTime.Now.Subtract(fi.LastAccessTime).TotalDays > c.Limit; + } + else if (c.Type == FolderToClean.ConditionType.LastWriteTime) + { + conditionresult = DateTime.Now.Subtract(fi.LastWriteTime).TotalDays > c.Limit; + } + else if (c.Type == FolderToClean.ConditionType.Length) + { + conditionresult = fi.Length > c.Limit; + } + + fileistodeleteResult = ftc.Xml_OrConditionList ? fileistodeleteResult || conditionresult : fileistodeleteResult = fileistodeleteResult && conditionresult; + if ((ftc.Xml_OrConditionList && fileistodeleteResult) || (!ftc.Xml_OrConditionList && !fileistodeleteResult)) { break; } + } + return fileistodeleteResult; + } + return false; + } + #endregion public FileIsToDelete + #region public CleanFiles + public static long CleanFolderFiles(DirectoryInfo d,FolderToClean ftc, bool delete) + { + int daystodelete = ftc.Xml_CleanupDays; + long cleanedsize = 0; + // Add file sizes. + FileInfo[] fis = d.GetFiles(ftc.Xml_IncludeMask, SearchOption.TopDirectoryOnly); + foreach (FileInfo fi in fis) + { + if (FileIsToDelete(fi, ftc)) + { + var fl = fi.Length; + try + { + if (delete) { File.Delete(fi.FullName); } + cleanedsize += fl; + } + catch { } + } + } + // Add subdirectory sizes. + if (ftc.Xml_Recurse) + { + foreach (DirectoryInfo di in d.GetDirectories()) { cleanedsize += CleanFolderFiles(di, ftc, delete); } + } + if (ftc.Xml_RemoveEmptyFolder && DirSize(d, ftc.Xml_IncludeMask, ftc.Xml_IncludeFullpathRegexp, ftc.Xml_Recurse) == 0) + { + try { Directory.Delete(d.FullName, ftc.Xml_Recurse); } catch { } + } + return cleanedsize; + } + #endregion public CleanFiles + } + #endregion class FileCleanerManagerCore + + #region FileCleanerManagerCoreXmlProcessor class + public class FileCleanerManagerCoreXmlProcessor : XmlParser + { + private List _foldertocleanlist; + private int commoncleanupdays; + #region constructor + public FileCleanerManagerCoreXmlProcessor(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); + var ftcxmllist = GetAllXElements(nameof(FolderToClean.XmlStructure.FolderToClean)); + if (ftcxmllist != null && ftcxmllist.Any()) + { + foreach (var ftcxml in ftcxmllist) { var ws = new FolderToClean(ftcxml, commoncleanupdays); if (ws.Valid) { _foldertocleanlist.Add(ws); } } + } + } + #endregion constructor + #region GetDefinitionList + public List GetDefinitionList() { return _foldertocleanlist; } + #endregion GetDefinitionList + } + #endregion FileCleanerManagerCoreXmlProcessor class + #region WindowsService class + public class FolderToClean : XmlLinqBase + { + #region fields + public bool Valid = true; + public string Xml_DirectoryPath; + public bool Xml_Recurse; + public bool Xml_RemoveEmptyFolder; + public string Xml_IncludeMask; + public string Xml_IncludeFullpathRegexp; + public bool Xml_OrConditionList = true; + public List Xml_ConditionList; + public int Xml_CleanupDays; + + public bool FolderExists; + public long SizeFolderTotal; + public long SizeSelectedBeforeClean; + public long SizeSelectedAfterClean { get { return SizeSelectedBeforeClean - SizeSelectedCleaned; } } + public long SizeSelectedCleaned; + #endregion fields + + #region basic constructor + public FolderToClean() { } + #endregion basic constructor + #region xml constructor + public FolderToClean(XElement foldertocleanxml,int commoncleanupdays) + { + Valid = true; + string ATTRIBUTEMANDATORY = nameof(XmlStructure.FolderToClean) + " attribute is mandatory! Name: {0}"; + 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); + Xml_RemoveEmptyFolder = GetValue(nameof(XmlStructure.FolderToClean.Attributes.RemoveEmptyFolder), foldertocleanxml, XmlStructure.FolderToClean.Attributes.RemoveEmptyFolder.Values.DEFAULT); + Xml_IncludeMask = GetValue(nameof(XmlStructure.FolderToClean.Attributes.IncludeMask), foldertocleanxml, XmlStructure.FolderToClean.Attributes.IncludeMask.Values.DEFAULT); + Xml_IncludeFullpathRegexp = GetValue(GetXElement(foldertocleanxml,nameof(XmlStructure.FolderToClean.IncludeFullpathRegexp)), XmlStructure.FolderToClean.IncludeFullpathRegexp.Values.DEFAULT); + Xml_CleanupDays = GetValue(GetXElement(foldertocleanxml,nameof(XmlStructure.FolderToClean.Attributes.CleanupDays)), commoncleanupdays); + Xml_ConditionList = new List(); + //var conditionxmlList = GetAllXElements(foldertocleanxml, nameof(XmlStructure.FolderToClean.Conditions), nameof(XmlStructure.FolderToClean.Conditions.Condition)); + var conditionsxml = foldertocleanxml.Element(XName.Get(nameof(XmlStructure.FolderToClean.Conditions))); + var conditionxmlList = conditionsxml?.Elements(XName.Get(nameof(XmlStructure.FolderToClean.Conditions.Condition))); + if (conditionxmlList!=null && conditionxmlList.Any()) + { + Xml_OrConditionList = GetValue(nameof(XmlStructure.FolderToClean.Conditions.Attributes.OrConditionList), conditionsxml, XmlStructure.FolderToClean.Conditions.Attributes.OrConditionList.Values.DEFAULT); + foreach (var conditionxml in conditionxmlList) { Xml_ConditionList.Add(new Condition(conditionxml)); } + } + } + #endregion xml constructor + #region cloner constructor + public FolderToClean(FolderToClean ftc) + { + Valid = ftc.Valid; + Xml_DirectoryPath = ftc.Xml_DirectoryPath; + Xml_Recurse = ftc.Xml_Recurse; + Xml_RemoveEmptyFolder = ftc.Xml_RemoveEmptyFolder; + Xml_IncludeMask = ftc.Xml_IncludeMask; + Xml_IncludeFullpathRegexp = ftc.Xml_IncludeFullpathRegexp; + Xml_OrConditionList = ftc.Xml_OrConditionList; + Xml_CleanupDays = ftc.Xml_CleanupDays; + Xml_ConditionList = ftc.Xml_ConditionList.Select(c=>new Condition(c)).ToList(); ; + } + #endregion cloner constructor + #region Condition + public enum ConditionType { Length, TimeStampInName, LastWriteTime, LastAccessTime, CreationTime, } + public class Condition: XmlLinqBase + { + #region cloner constructor + public Condition(Condition c) + { + Type = c.Type; + TimestampConstructor = c.TimestampConstructor; + Limit = c.Limit; + } + #endregion cloner constructor + #region constructor + public Condition(XElement cxml) + { + var typestr = GetValue(nameof(XmlStructure.FolderToClean.Conditions.Condition.Attributes.Type), cxml, XmlStructure.FolderToClean.Conditions.Condition.Attributes.Type.Values.DEFAULT); + this.Type = (ConditionType)Enum.Parse(typeof(ConditionType),typestr); + TimestampConstructor = GetValue(nameof(XmlStructure.FolderToClean.Conditions.Condition.Attributes.TimestampConstructor), cxml, XmlStructure.FolderToClean.Conditions.Condition.Attributes.TimestampConstructor.Values.DEFAULT); + Limit = GetValue(nameof(XmlStructure.FolderToClean.Conditions.Condition.Attributes.Limit), cxml, XmlStructure.FolderToClean.Conditions.Condition.Attributes.Limit.Values.DEFAULT); + } + #endregion constructor + public ConditionType Type; + public string TimestampConstructor; + public int Limit; + } + #endregion Condition + #region XmlStructure + public static class XmlStructure + { + public static class Attributes + { + public static class CleanupDays + { + public static class Values + { + public const int DEFAULT = 7; + } + } + } + public static class FolderToClean + { + public static class Attributes + { + public static class Directory { } + public static class CleanupDays + { + public static class Values + { + public const int DEFAULT = XmlStructure.Attributes.CleanupDays.Values.DEFAULT; + } + } + public static class Recurse + { + public static class Values + { + public const bool DEFAULT = false; + } + } + public static class RemoveEmptyFolder + { + public static class Values + { + public const bool DEFAULT = false; + } + } + public static class IncludeMask + { + public static class Values + { + public const string DEFAULT = "*.*"; + } + } + } + public static class IncludeFullpathRegexp + { + public static class Values + { + public const string DEFAULT = ""; + } + } + public static class Conditions + { + public static class Attributes + { + public static class OrConditionList + { + public static class Values + { + public const bool DEFAULT = true; + } + } + } + public static class Condition + { + public static class Attributes + { + public static class Type + { + public static class Values + { + public const string DEFAULT = nameof(ConditionType.LastWriteTime); + public static class TimeStampInName { } + public static class Length { } + public static class LastWriteTime { } + public static class LastAccessTime { } + public static class CreationTime { } + } + } + public static class TimestampConstructor + { + public static class Values + { + public const string DEFAULT = "{YEAR}.{MONTH}.{DAY} {HOUR}:{MINUTE}:{SECOND}"; + } + } + public static class Limit + { + public static class Values + { + public const int DEFAULT = XmlStructure.Attributes.CleanupDays.Values.DEFAULT; + } + } + } + } + } + } + } + #endregion XmlStructure + } + #endregion WindowsService class + +} diff --git a/Vrh.Log4Pro.MaintenanceConsole/Manager - MaintenanceToolManager.cs b/Vrh.Log4Pro.MaintenanceConsole/Manager - MaintenanceToolManager.cs new file mode 100644 index 0000000..d1eab7d --- /dev/null +++ b/Vrh.Log4Pro.MaintenanceConsole/Manager - MaintenanceToolManager.cs @@ -0,0 +1,124 @@ +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.XmlProcessing; +using System.Xml.Linq; +using System.Text.RegularExpressions; + +namespace Vrh.Log4Pro.MaintenanceConsole +{ + #region MaintenanceTools class + public static class MaintenanceToolManager + { + #region Execute + public static object Execute(object o1 = null, object o2 = null) + { + string xmlcs = "file=Config.Xml;element=WindowsServices;"; + 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)) + .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.SetParameters(sr,config); + menufunctions.Execute(sr.SelectedKeyList); + } + return null; + } + #endregion Execute + + #region First level Executors with UI + #region RegexTester + private static object RegexTester(object parameter, object o) + { + var config = parameter as MaintenanceToolsXmlProcessor; + var regexptesterconfig = config.RegexpTesterConfig; + while(true) + { + var regexstr = ColorConsole.ReadLine($"Enter REGEX to test with:", ConsoleColor.Yellow); + if (regexstr == "EX") { break; } + var teststr = ColorConsole.ReadLine($"Enter STRING to test:", ConsoleColor.Yellow); + if (teststr == "EX") { break; } + + var rgx = new Regex(regexstr, RegexOptions.None); + var regexmatch = rgx.Match(teststr); + if (!regexmatch.Success) + { + ColorConsole.WriteLine($"No match.", ConsoleColor.Red); + } + else + { + ColorConsole.WriteLine($"Match.", ConsoleColor.Green); + ColorConsole.WriteLine($"Named groups:"); + var groups = new Dictionary(); + foreach (var groupname in rgx.GetGroupNames()) + { + ColorConsole.Write(groupname,bracket:"[]", suffix: " = "); + ColorConsole.WriteLine(regexmatch.Groups[groupname].Value, ConsoleColor.Yellow); + } + } + ColorConsole.ReadLine($"Press any key to continue..."); + } + return o; + } + #endregion RegexTester + #region Tool templates + private static object Tool1(object parameter, object o) + { + var config = parameter as MaintenanceToolsXmlProcessor; + ColorConsole.ReadLine($"{nameof(Tool1)} is not ready yet...",ConsoleColor.Yellow); + return o; + } + private static object Tool2(object parameter, object o) + { + var config = parameter as MaintenanceToolsXmlProcessor; + ColorConsole.ReadLine($"{nameof(Tool2)} is not ready yet...", ConsoleColor.Yellow); + return o; + } + #endregion Tool templates + #endregion First level Executors with UI + } + #endregion MaintenanceTools class + + #region MaintenanceToolsXmlProcessor class + public class MaintenanceToolsXmlProcessor : XmlParser + { + public XElement RegexpTesterConfig; + #region constructor + public MaintenanceToolsXmlProcessor(string xmlcs, string basefolder, string lcid) : base(xmlcs, basefolder, lcid, null) + { + RegexpTesterConfig = GetXElement(nameof(XmlStructure.RegexpTester)); + } + #endregion constructor + #region XmlStructure + public static class XmlStructure + { + public static class RegexpTester { } + } + #endregion XmlStructure + } + #endregion MaintenanceToolsXmlProcessor class +} diff --git a/Vrh.Log4Pro.MaintenanceConsole/Manager - WebApplicationManager.cs b/Vrh.Log4Pro.MaintenanceConsole/Manager - WebApplicationManager.cs new file mode 100644 index 0000000..85105ca --- /dev/null +++ b/Vrh.Log4Pro.MaintenanceConsole/Manager - WebApplicationManager.cs @@ -0,0 +1,939 @@ +using System; +using System.IO; +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.XmlProcessing; +using System.Xml.Linq; + +namespace Vrh.Log4Pro.MaintenanceConsole +{ + #region WebApplicationManager + public static class WebApplicationManager + { + #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 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(); + + 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.Execute(sr.SelectedKeyList); + } + return null; + } + #endregion public method: Execute + #region private method: DisplayWebAppInfo + private static object DisplayWebAppInfo(object waobj,int lineix) + { + 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 + { + return null; + } + return ""; + } + #endregion private method: DisplayWebAppInfo + #region + private static object Restart(object dobj, object parameters) + { + WebApplication d = dobj as WebApplication; + using (ServerManager sm = new ServerManager()) + { + try { WebApplicationManagerCore.GetPool(sm, d.Xml_PoolName)?.Stop(); } catch { Console.WriteLine($"Pool {d.Xml_PoolName} already stopped."); } + try { WebApplicationManagerCore.GetSite(sm, d.Xml_SiteName)?.Stop(); } catch { Console.WriteLine($"Site {d.Xml_SiteName} already stopped."); } + + SiteStart(d, parameters); + PoolStart(d, parameters); + PoolRecycle(d, parameters); + + Console.WriteLine($"Pool {d.Xml_PoolName} and site {d.Xml_SiteName} restarted."); + return parameters; + } + } + private + static object PoolStart(object dobj, object parameters) + { + WebApplication d = dobj as WebApplication; + using (ServerManager sm = new ServerManager()) + { + bool success = false; + for (var i = 1; i <= 10; i++) + { + var p = WebApplicationManagerCore.GetPool(sm, d.Xml_PoolName); + if (p != null && p.State == ObjectState.Stopped) { p.Start(); success = true; break; } + else + { + Console.WriteLine($"Trying to start pool {d.Xml_PoolName} ... Press key 'X' to exit..."); + if (Console.KeyAvailable) { if (Console.ReadKey().KeyChar.ToString().ToUpper() == "X") { break; } } + + Thread.Sleep(1000); + } + } + var successstr = success ? "started" : "NOT started"; + Console.WriteLine($"{d.Xml_PoolName} {successstr}."); + return parameters; + } + } + private static object PoolRecycle(object dobj, object parameters) + { + WebApplication d = dobj as WebApplication; + using (ServerManager sm = new ServerManager()) + { + bool success = false; + for (var i = 1; i < 4; i++) + { + var p = WebApplicationManagerCore.GetPool(sm, d.Xml_PoolName); + if (p != null && p.State == ObjectState.Started) { p.Recycle(); success = true; break; } + else + { + Console.WriteLine($"Trying to recycle pool {d.Xml_PoolName} ... Press key 'X' to exit..."); + if (Console.KeyAvailable) { if (Console.ReadKey().KeyChar.ToString().ToUpper() == "X") { break; } } + Thread.Sleep(1000); + } + } + var successstr = success ? "recycled" : "NOT recycled"; + Console.WriteLine($"{d.Xml_PoolName} {successstr}."); + return parameters; + } + } + private static object PoolStop(object dobj, object parameters) + { + 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); + if (p != null && p.State == ObjectState.Started) { p.Stop(); success = true; break; } + else + { + Console.WriteLine($"Trying to stop pool {d.Xml_PoolName} ... Press key 'X' to exit..."); + if (Console.KeyAvailable) { if (Console.ReadKey().KeyChar.ToString().ToUpper() == "X") { break; } } + + Thread.Sleep(1000); + } + } + var successstr = success ? "stopped" : "NOT stopped"; + Console.WriteLine($"{d.Xml_PoolName} {successstr}."); + return parameters; + } + } + private static object SiteStart(object dobj, object parameters) + { + WebApplication d = dobj as WebApplication; + using (ServerManager sm = new ServerManager()) + { + bool success = false; + for (var i = 1; i < 4; i++) + { + var s = WebApplicationManagerCore.GetSite(sm, d.Xml_SiteName); + if (s != null && s.State == ObjectState.Stopped) { s.Start(); success = true; break; } + else + { + Console.WriteLine($"Trying to start site {d.Xml_SiteName} ... Press key 'X' to exit..."); + if (Console.KeyAvailable) { if (Console.ReadKey().KeyChar.ToString().ToUpper() == "X") { break; } } + Thread.Sleep(1000); + } + } + var successstr = success ? "started" : "NOT started"; + Console.WriteLine($"{d.Xml_SiteName} {successstr}."); + return parameters; + } + } + private static object SiteStop(object dobj, object parameters) + { + WebApplication d = dobj as WebApplication; + using (ServerManager sm = new ServerManager()) + { + bool success = false; + for (var i = 1; i < 4; i++) + { + var s = WebApplicationManagerCore.GetSite(sm, d.Xml_SiteName); + if (s != null && s.State == ObjectState.Started) { s.Stop(); success = true; break; } + else + { + Console.WriteLine($"Trying to stop site {d.Xml_SiteName} ... Press key 'X' to exit..."); + if (Console.KeyAvailable) { if (Console.ReadKey().KeyChar.ToString().ToUpper() == "X") { break; } } + Thread.Sleep(1000); + } + } + var successstr = success ? "stopped" : "NOT stopped"; + Console.WriteLine($"{d.Xml_SiteName} {successstr}."); + return parameters; + } + } + private static object Register(object dobj, object parameters) + { + 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); + Console.WriteLine($"{d.Xml_AppName} is registered in site {d.Xml_SiteName} using pool {d.Xml_PoolName}."); + return parameters; + } + private static object Unregister(object dobj, object parameters) + { + WebApplication d = dobj as WebApplication; + WebApplicationManagerCore.UnRegisterWebApplication(d.Xml_AppName, d.Xml_PoolName, d.Xml_SiteName, d.Xml_ForceRemovePool, d.Xml_ForceRemoveSite); + Console.WriteLine($"{d.Xml_AppName} is unregistered from site {d.Xml_SiteName} and from pool {d.Xml_PoolName}."); + return parameters; + } + private static object SetImpersonateIdentity(object dobj, object parameters) + { + WebApplication d = dobj as WebApplication; + string username="", password = "",impersonate="FALSE"; + bool parametersarealreadyset = parameters != null; + string olduserinfo = WebApplicationManagerCore.GetImpersonateIdentityInfo(d.Xml_IdentityConfigFile); + if (parametersarealreadyset) + { + impersonate = ((Dictionary)parameters)["impersonate"]; + username = ((Dictionary)parameters)["username"]; + password = ((Dictionary)parameters)["password"]; + } + else + { + while(true) + { + + Console.WriteLine($"Current user info: {olduserinfo}"); + Console.WriteLine("Set impersonate-on status (true/false), then [Enter], EX=exit."); + impersonate = Console.ReadLine().ToUpper(); + if (impersonate == "EX") { return null; } + else if (impersonate == "FALSE") { break; } + else if (impersonate == "TRUE") + { + Console.WriteLine("Enter username, then [Enter]."); + var un = !string.IsNullOrWhiteSpace(d.Xml_PoolUsername) ? $"empty={d.Xml_PoolUsername }," : ""; + Console.WriteLine($"{un}EX=exit"); + username = Console.ReadLine().ToUpper(); + if (impersonate == "EX") { return null; } + Console.WriteLine("Enter password, then [Enter]"); + var pw = !string.IsNullOrWhiteSpace(d.Xml_PoolPassword) ? $"empty={d.Xml_PoolPassword}," : ""; + Console.WriteLine($"{pw}EX=exit"); + password = Console.ReadLine().ToUpper(); + if (impersonate == "EX") { return null; } + break; + //bool valid = System.Web.ApplicationSerices.AuthenticationService.ValidateUser(username, password, mull); + } + else + { + Menu.IncorrectSelection(); + continue; + } + } + parameters = new Dictionary { { "impersonate", impersonate }, { "username", username }, { "password", password }, }; + } + WebApplicationManagerCore.SetImpersonateIdentity(d.Xml_IdentityConfigFile, impersonate, username, password); + Console.WriteLine($"Impersonate identity changed for webapp {d.Xml_AppName}."); + Console.WriteLine($"From '{olduserinfo}' to '{WebApplicationManagerCore.GetImpersonateIdentityInfo(d.Xml_IdentityConfigFile)}'"); + + return parameters; + } + private static object PoolSetUserAccount(object dobj, object parameters) + { + WebApplication d = dobj as WebApplication; + string username, password = ""; + bool parametersarealreadyset = parameters != null; + string olduserinfo = WebApplicationManagerCore.GetUserInfo(d.Xml_PoolName); + if (parametersarealreadyset) + { + username = ((Dictionary)parameters)["username"]; + password = ((Dictionary)parameters)["password"]; + } + else + { + Console.WriteLine($"Current user info: {olduserinfo}"); + Console.WriteLine("Enter username, then [Enter]."); + Console.WriteLine("Special usernames are: (Empty=API) "); + Console.WriteLine($" (API) {nameof(ProcessModelIdentityType.ApplicationPoolIdentity)}"); + Console.WriteLine($" (LSE) {nameof(ProcessModelIdentityType.LocalService)}"); + Console.WriteLine($" (LSY) {nameof(ProcessModelIdentityType.LocalSystem)}"); + Console.WriteLine($" (NSE) {nameof(ProcessModelIdentityType.NetworkService)}"); + ColorConsole.WriteLine(); + ColorConsole.Write(" (EX) ", ConsoleColor.Red); ColorConsole.WriteLine("Exit"); + username = Console.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); } + 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 + { + Console.WriteLine("Enter password, then [Enter]"); + password = Console.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); + Console.WriteLine($"Pool user changed from {olduserinfo} to {WebApplicationManagerCore.GetUserInfo(d.Xml_PoolName)} for pool {d.Xml_PoolName}."); + return parameters; + } + #endregion + } + + public static class WebApplicationManagerCore + { + #region private method: CollectWebAppInfo + public static WebApplication CollectWebAppInfo(SiteCollection sites,ApplicationPoolCollection pools, WebApplication wadef) + { + var wa = new WebApplication(wadef); + try + { + wa.Site = sites[wa.Xml_SiteName]; + if (wa.Site == null) { throw new Exception(); } + else + { + 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 = GetImpersonateIdentityInfo(wa.Xml_IdentityConfigFile); + } + } + } + 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 + { + 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 + { + wa.ApplicationPool = null; + wa.PoolState = "Unregistered/Unknown"; + wa.PoolAccount = ""; + } + return wa; + } + #endregion private method: CollectWebAppInfo + + #region private method:RegisterWebApplication + public static void RegisterWebApplication(string sitename, string poolname, string appname, string poolphypath, string sitephypath, int siteport, bool recreatepool, bool recreatesite, bool recreateapp,ManagedPipelineMode plmode) + { + using (ServerManager serverManager = new ServerManager()) + { + if (!isExistWebAppPool(serverManager, poolname)) { CreateWebAppPool(serverManager, poolname, plmode); } + else if (recreatepool) { RemoveWebAppPool(serverManager, poolname); CreateWebAppPool(serverManager, poolname, plmode); } + + if (!isExistWebSite(serverManager, sitename)) { CreateWebSite(serverManager, sitename, poolname, sitename, sitephypath, siteport); } + else if (recreatesite) { RemoveWebSite(serverManager, sitename); CreateWebSite(serverManager, sitename, poolname, sitename, sitephypath, siteport);} + + SetItemProperty(serverManager, poolname, "managedRuntimeVersion", "v4.0"); + SetItemProperty(serverManager, poolname, "enable32BitAppOnWin64", "true"); + + if (!isExistWebApp(serverManager, sitename, appname)) { CreateWebApp(serverManager, appname, poolname, sitename, poolphypath); } + else if (recreateapp) { RemoveWebApp(serverManager, appname, sitename); CreateWebApp(serverManager, appname, poolname, sitename, poolphypath); } + + CommitChanges(serverManager, poolname); + } + } + #endregion private method:RegisterWebApplication + #region private method:UnRegisterWebApplication + public static void UnRegisterWebApplication(string appname, string poolname, string sitename = "Default Web Site",bool forceremovepool=false, bool forceremovesite = false) + { + using (ServerManager sm = new ServerManager()) + { + if (isExistWebApp(sm, sitename, appname)) { RemoveWebApp(sm, appname, sitename); } + if (isExistWebAppPool(sm,poolname) && forceremovepool) { RemoveWebAppPool(sm,poolname); } + if (isExistWebSite(sm, sitename) && forceremovesite) { RemoveWebSite(sm, poolname); } + CommitChanges(sm, poolname); + } + } + #endregion private method:UnRegisterWebApplication + #region private method:SetImpersonateIdentity + public static void SetImpersonateIdentity(string filepath, string impersonate, string username, string password) + { + var identityxml = new XElement("identity"); + identityxml.Add(new XAttribute("impersonate", impersonate.ToLower())); + if (impersonate.ToLower() == "true") + { + if (!string.IsNullOrWhiteSpace(username)) + { + identityxml.Add(new XAttribute("userName", username)); + identityxml.Add(new XAttribute("password", string.IsNullOrWhiteSpace(password)?"":password)); + } + } + identityxml.Save(filepath); + } + #endregion private method:SetImpersonateIdentity + #region private method:SetPoolUserAccount + public static void SetPoolUserAccount(string appname, string sitename, string username, string password) + { + using (var sm = new ServerManager()) + { + //var pool = GetPool(GetPoolName(sitename, appname)); + var pool = GetPool(sm, sitename, appname); + if (username == nameof(ProcessModelIdentityType.ApplicationPoolIdentity) + || username == nameof(ProcessModelIdentityType.LocalService) + || username == nameof(ProcessModelIdentityType.LocalSystem) + || username == nameof(ProcessModelIdentityType.NetworkService)) + { + pool.ProcessModel.UserName = null; + pool.ProcessModel.Password = null; + pool.ProcessModel.IdentityType = (ProcessModelIdentityType)Enum.Parse(typeof(ProcessModelIdentityType), username); + } + else // if (ProcessModelIdentityType.SpecificUser) + { + pool.ProcessModel.UserName = username; + pool.ProcessModel.Password = password; + pool.ProcessModel.IdentityType = ProcessModelIdentityType.SpecificUser; + } + CommitChanges(sm, pool.Name); + } + } + #endregion private method:SetPoolUserAccount + #region private method:CommitChanges + private static void CommitChanges(ServerManager serverManager, string poolname) + { + serverManager.CommitChanges(); + if (isExistWebAppPool(poolname)) + { + var p = GetPool(serverManager, poolname); + if (p.State == ObjectState.Started) { p.Recycle(); } + } + } + #endregion private method:CommitChanges + + #region private methods: Get information (with no ServerManager parameter) + public static string GetImpersonateIdentityInfo(string filepath) + { + try + { + var xml = XElement.Load(filepath); + var identityXml = xml; //?.Element(XName.Get("identity")); + if (identityXml == null) { return "no info"; } + else + { + 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}"; + return retinfo; + } + } + catch { return "no info (exception)"; } + } + public static string GetUserInfo(string poolname) + { + using (var sm2 = new ServerManager()) + { + var pool = sm2.ApplicationPools[poolname]; + string userinfo = ""; + if (pool != null) + { + if (pool.ProcessModel.IdentityType == ProcessModelIdentityType.SpecificUser) + { + userinfo = $"{pool.ProcessModel.UserName}({pool.ProcessModel.Password})"; + } + else + { + userinfo = $"{pool.ProcessModel.IdentityType}"; + } + } + return userinfo; + } + } + private static string GetPoolName(string sitename,string appname) + { + using (ServerManager serverManager = new ServerManager()) + { + return GetPoolName(serverManager, sitename, appname); + } + } + public static ApplicationPool GetPool(string sitename, string appname) + { + using (ServerManager serverManager = new ServerManager()) + { + return GetPool(serverManager, sitename, appname); + } + } + public static ApplicationPool GetPool(string poolname) + { + using (ServerManager serverManager = new ServerManager()) + { + return GetPool(serverManager,poolname); + } + } + private static bool isExistWebAppPool(string poolname) + { + using (ServerManager serverManager = new ServerManager()) + { + return isExistWebAppPool(serverManager, poolname); + } + } + private static bool isExistWebApp(string sitename,string appname) + { + using (ServerManager serverManager = new ServerManager()) + { + return isExistWebApp(serverManager ,sitename, appname); + } + } + private static bool isExistWebSite(string sitename) + { + using (ServerManager serverManager = new ServerManager()) + { + return isExistWebSite(serverManager ,sitename); + } + } + #endregion private methods: Get information (with no ServerManager parameter) + #region private methods: Get information + public static string GetUserInfo(ServerManager sm, string poolname) + { + var pool = sm.ApplicationPools[poolname]; + string userinfo = ""; + if (pool != null) + { + if (pool.ProcessModel.IdentityType == ProcessModelIdentityType.SpecificUser) + { + userinfo = $"{pool.ProcessModel.UserName}({pool.ProcessModel.Password})"; + } + else + { + userinfo = $"{pool.ProcessModel.IdentityType}"; + } + } + return userinfo; + } + public static string GetPoolName(ServerManager serverManager,string sitename, string appname) + { + Site site = serverManager.Sites[sitename]; + Application application = site.Applications[Path.Combine("/", appname)]; + return application.ApplicationPoolName; + } + public static ApplicationPool GetPool(ServerManager serverManager, string sitename, string appname) + { + Site site = serverManager.Sites[sitename]; + Application application = site.Applications[Path.Combine("/",appname)]; + return serverManager.ApplicationPools[application.ApplicationPoolName]; + } + public static ApplicationPool GetPool(ServerManager serverManager, string poolname) + { + return serverManager.ApplicationPools[poolname]; + } + public static Site GetSite(ServerManager serverManager, string sitename) + { + return serverManager.Sites[sitename]; + } + private static bool isExistWebAppPool(ServerManager serverManager, string poolname) + { + try + { + var p = serverManager.ApplicationPools[poolname]; + if (p == null) { return false; } + return p.State != ObjectState.Unknown; + } + catch { return false; } + } + private static bool isExistWebApp(ServerManager serverManager, string sitename, string appname) + { + try + { + var an = Path.Combine(@"/",appname); + var app = serverManager.Sites[sitename].Applications[an]; + return app != null; + } + catch { return false; } + } + private static bool isExistWebSite(ServerManager serverManager, string sitename) + { + try + { + var s = serverManager.Sites[sitename]; + if (s == null) { return false; } + return s.State != ObjectState.Unknown; + } + catch { return false; } + } + #endregion private methods: Get information + #region private methods: Set information + private static void SetItemProperty(ServerManager serverManager, string poolname, string propertyname, string propertyvalue) + { + var pool = GetPool(serverManager, poolname); + pool.SetAttributeValue(propertyname, propertyvalue); //????????????????????????? + } + private static void CreateWebAppPool(ServerManager serverManager ,string poolname, ManagedPipelineMode plmode) + { + serverManager.ApplicationPools.Add(poolname); + ApplicationPool pool = serverManager.ApplicationPools[poolname]; + pool.ManagedPipelineMode = plmode; + } + private static void CreateWebApp(ServerManager serverManager, string appname, string poolname, string sitename, string poolphypath) + { + Site site = serverManager.Sites[sitename]; + Application application = site.Applications[Path.Combine("/",appname)]; + if (application != null) { site.Applications.Remove(application); } + application = site.Applications.Add(Path.Combine("/",appname), poolphypath); + application.ApplicationPoolName = poolname; + } + private static void CreateWebSite(ServerManager serverManager, string sitename, string poolname, string hostheader, string sitephypath, int siteport = 8000) + { + Site mySite = serverManager.Sites.Add(sitename, sitephypath, siteport); + mySite.Applications[0].ApplicationPoolName = poolname; + //mysite.Applications[0].VirtualDirectories[0].PhysicalPath = sitephypath; + mySite.ServerAutoStart = true; + } + private static void RemoveWebSite(ServerManager serverManager, string sitename) + { + Site mySite = serverManager.Sites[sitename]; + if (mySite != null) { serverManager.Sites.Remove(mySite); } + } + private static void RemoveWebAppPool(ServerManager serverManager,string poolname) + { + try + { + ApplicationPool pool = serverManager.ApplicationPools[poolname]; + serverManager.ApplicationPools.Remove(pool); + } + catch { } + } + private static void RemoveWebApp(ServerManager serverManager, string appname, string sitename) + { + Site site = serverManager.Sites[sitename]; + Application application = site.Applications[Path.Combine("/",appname)]; + site.Applications.Remove(application); + } + #endregion private methods: Set information (wit no ServerManager parameter) + #region private methods: Set information (with no ServerManager parameter) + private static void SetItemProperty(string poolname, string propertyname, string propertyvalue) + { + using (ServerManager serverManager = new ServerManager()) + { + SetItemProperty(serverManager, poolname, propertyname, propertyvalue); + CommitChanges(serverManager, poolname); + } + } + private static void CreateWebAppPool(string poolname, ManagedPipelineMode plmode) + { + using (ServerManager serverManager = new ServerManager()) + { + CreateWebAppPool(serverManager, poolname, plmode); + CommitChanges(serverManager, poolname); + } + } + private static void CreateWebApp(string appname, string poolname, string sitename, string poolphypath) + { + using (ServerManager serverManager = new ServerManager()) + { + CreateWebApp(serverManager, appname, poolname, sitename, poolphypath); + CommitChanges(serverManager, poolname); + } + } + private static void CreateWebSite(string sitename, string poolname, string hostheader, string sitephypath, int siteport = 8000) + { + using (ServerManager serverManager = new ServerManager()) + { + CreateWebSite(serverManager, sitename, poolname, hostheader, sitephypath, siteport); + CommitChanges(serverManager, poolname); + } + } + private static void RemoveWebSite(string sitename) + { + using (ServerManager serverManager = new ServerManager()) { RemoveWebSite(serverManager, sitename); } + } + private static void RemovePool(string poolname) + { + using (ServerManager sm = new ServerManager()) + { + RemoveWebAppPool(sm, poolname); + CommitChanges(sm, poolname); + } + } + private static void RemoveWebApp(string sitename, string appname) + { + using (ServerManager sm = new ServerManager()) + { + RemoveWebApp(sm, appname, sitename); + CommitChanges(sm, GetPoolName(sm,sitename, appname)); + } + } + #endregion private methods: Set information (with no ServerManager parameter) + + } + #region WebApplicationManagerXmlProcessor class + public class WebApplicationManagerXmlProcessor : XmlParser + { + #region constructor + public WebApplicationManagerXmlProcessor(string xmlcs, string basefolder, string lcid) : base(xmlcs, basefolder, lcid, null) + { + _webapplist = new List(); + var waxmllist = GetAllXElements(nameof(WebApplication.XmlStructure.WebApplication)); + if (waxmllist != null && waxmllist.Any()) + { + foreach (var waxml in waxmllist) { _webapplist.Add(new WebApplication(waxml)); } + } + } + #endregion constructor + #region properties + List _webapplist = null; + #endregion properties + + #region GetDefinitionList + public List GetDefinitionList() { return _webapplist; } + #endregion GetDefinitionList + } + #endregion WebApplicationManagerXmlProcessor class + #region WebApplication class + public class WebApplication : XmlLinqBase + { + #region properties from Xml definition + public string Xml_AppName; + public string Xml_Description; + public string Xml_PoolName; + public string Xml_SiteName; + public string Xml_AppPhysicalPath; + public ManagedPipelineMode Xml_PoolPipeLineMode; + public string Xml_SitePhysicalPath; + public string Xml_IdentityConfigFile; + public ProcessModelIdentityType Xml_PoolIdentitytype; + public string Xml_PoolUsername; + public string Xml_PoolPassword; + public bool Xml_RecreatePool; + public bool Xml_RecreateSite; + public bool Xml_RecreateApp; + public bool Xml_ForceRemovePool; + public bool Xml_ForceRemoveSite; + #endregion properties from Xml definition + + #region properties from environment + public Site Site; + public string SitePortList; + public string SiteState; + public ApplicationPool ApplicationPool; + public string PoolState; + public string PoolAccount; + public string AppImpersonateIdentity; + public Application Application; + public string ApplicationState; + public string ApplicationPath; + #endregion properties from environment + public WebApplication() { } + public WebApplication(XElement webappXml) + { + string ATTRIBUTEMANDATORY = nameof(XmlStructure.WebApplication) + " attribute is mandatory! Name: {0}"; + + 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))); } + + Xml_Description = GetValue(nameof(XmlStructure.WebApplication.Attributes.Description), webappXml, Xml_AppName); + Xml_PoolName = GetValue(nameof(XmlStructure.WebApplication.Attributes.AppPool), webappXml, XmlStructure.WebApplication.Attributes.AppPool.Values.DEFAULT); + Xml_SiteName = GetValue(nameof(XmlStructure.WebApplication.Attributes.WebSite), webappXml, XmlStructure.WebApplication.Attributes.WebSite.Values.DEFAULT); + + Xml_AppPhysicalPath = webappXml.Attribute(XName.Get(nameof(XmlStructure.WebApplication.Attributes.InstallDir)))?.Value; + if (string.IsNullOrWhiteSpace(Xml_AppPhysicalPath)) { throw new ApplicationException(string.Format(ATTRIBUTEMANDATORY, nameof(XmlStructure.WebApplication.Attributes.InstallDir))); } + + string PoolPipeLineModeStr = webappXml.Attribute(XName.Get(nameof(XmlStructure.WebApplication.Attributes.AppPoolPipeLineMode)))?.Value; + if (string.IsNullOrWhiteSpace(PoolPipeLineModeStr)) { Xml_PoolPipeLineMode = ManagedPipelineMode.Integrated; } + else + { + 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, ""); + try { Xml_PoolIdentitytype = (ProcessModelIdentityType)Enum.Parse(typeof(ProcessModelIdentityType), Xml_PoolUsername); } + catch { Xml_PoolIdentitytype = ProcessModelIdentityType.SpecificUser; } + if (Xml_PoolIdentitytype != ProcessModelIdentityType.SpecificUser) { Xml_PoolPassword = ""; Xml_PoolUsername = ""; } + + 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); + + Xml_ForceRemovePool = GetValue(nameof(XmlStructure.WebApplication.Attributes.ForceRemovePool), webappXml, false); + Xml_ForceRemoveSite = GetValue(nameof(XmlStructure.WebApplication.Attributes.ForceRemoveSite), webappXml, false); + } + public WebApplication(WebApplication wadef) + { + 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_PoolIdentitytype = wadef.Xml_PoolIdentitytype; + 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; + } + #region XmlStructure + public static class XmlStructure + { + public static class WebApplication + { + public static class Attributes + { + 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 AppPoolUsername { } + public static class AppPoolPassword { } + public static class AppPoolPipeLineMode { } + public static class RecreatePool { } + public static class RecreateSite { } + public static class RecreateApp { } + public static class ForceRemovePool { } + public static class ForceRemoveSite { } + } + } + } + #endregion XmlStructure + } + #endregion WebApplication class + #endregion WebApplicationManager +} diff --git a/Vrh.Log4Pro.MaintenanceConsole/Manager - WindowsServiceManager.cs b/Vrh.Log4Pro.MaintenanceConsole/Manager - WindowsServiceManager.cs new file mode 100644 index 0000000..43c86c2 --- /dev/null +++ b/Vrh.Log4Pro.MaintenanceConsole/Manager - WindowsServiceManager.cs @@ -0,0 +1,952 @@ +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.XmlProcessing; +using System.Xml.Linq; +using System.Text.RegularExpressions; + +namespace Vrh.Log4Pro.MaintenanceConsole +{ + #region WindowsServiceManager class + public static class WindowsServiceManager + { + #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 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.SetParameters(sr,config); + menufunctions.Execute(sr.SelectedKeyList); + } + 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) + { + var config = parameter as WindowsServiceManagerXmlProcessor; + while (true) + { + 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; } + var sl = WindowsServiceManagerCore.GetServiceControllers(mask); + 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); + + 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.DisplayItems(1); + var ms = menuservices.Select(); + if (ms.Result == Menu.SelectionResult.None) { continue; } + else if (ms.Result == Menu.SelectionResult.Error) { continue; } + else if (ms.Result == Menu.SelectionResult.Exit) { break; } + else + { + foreach (var p in ms.SelectedParameterList) + { + ColorConsole.Write($"Enter CONFIRM to delete service ", ConsoleColor.Yellow); + ColorConsole.Write($"{p}", ConsoleColor.White,bracket:"''"); + ColorConsole.Write($"!", ConsoleColor.Yellow); + var confirmation = ColorConsole.ReadLine(prefix: " ---> ").ToUpper(); + if (confirmation == "EX") { return o; } + else if (confirmation == "") + { + ColorConsole.WriteLine($"Service '{p}' skipped!", ConsoleColor.Green); + continue; + } + else if (confirmation == "CONFIRM") + { + WindowsServiceManagerCore.Unregister((string)p); + ColorConsole.WriteLine($"Service '{p}' deleted!", ConsoleColor.Green); + } + } + } + } + return 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); + + Menu.Selection sr = menuservices.Select(); + 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) + { + WindowsService ws = p 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); + } + } + return 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); + + Menu.Selection sr = menuservices.Select(); + 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) + { + WindowsService ws = p 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); + } + } + return 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); + + Menu.Selection sr = menuservices.Select(); + 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) + { + WindowsService ws = p 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); + } + } + return 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); + + Menu.Selection sr = menuservices.Select(); + 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) + { + WindowsService ws = p 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); + } + } + return 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); + + Menu.Selection sr = menuservices.Select(); + 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) + { + WindowsService ws = p 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); + } + } + 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); + + Menu.Selection sr = menuservices.Select(); + 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 { } + + string username = null, password = null; + foreach (var p in sr.SelectedParameterList) + { + WindowsService ws = p 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 (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); } + } + } + catch (Exception ex) { ColorConsole.WriteLine(ex.Message, ConsoleColor.Red); } + } + return o; + } + #endregion First level Executors with UI + } + #endregion WindowsServiceManager class + + #region WindowsServiceManagerCore class + public static class WindowsServiceManagerCore + { + public static string GetUserInfo(ManagementObject wmiService) + { + return (string)wmiService[nameof(WindowsService.StartName)]; + } + public static ManagementObject GetServiceObject(string servicename) { return new ManagementObject("Win32_Service.Name='" + servicename + "'"); } + public static ServiceController GetServiceController(string servicename) { return new ServiceController(servicename); } + public static ServiceController[] GetServiceControllers(string servicenamemask) + { + var servicenameregex = @"^" + Regex.Escape(servicenamemask).Replace("%",".*").Replace(@"\?",".")+ @"$"; + + var ServiceControllerList = new List(); + var allservicecontrollers = ServiceController.GetServices(); + foreach (var sc in allservicecontrollers) + { + try + { + if (Regex.Match(sc.ServiceName, servicenameregex).Success) { ServiceControllerList.Add(sc); } + } + catch { ColorConsole.WriteLine($"Error in mask '{servicenamemask}'!",ConsoleColor.Red); return null; } + } + return ServiceControllerList.ToArray(); + } + public static bool SetUserAccount(ManagementObject service, string username, string password) + { + object[] accountParams = new object[11]; + accountParams[6] = username; + accountParams[7] = password; + uint returnCode = (uint)service.InvokeMethod("Change", accountParams); + if (returnCode == 0) { return true; } + else { return false; } + } + + public static bool Kill(string sname) + { + using (var wmiService = WindowsServiceManagerCore.GetServiceObject(sname)) + { + string sstate = (string)wmiService[nameof(WindowsService.State)]; + if (sstate != nameof(ObjectState.Stopped)) + { + int pid = Convert.ToInt32(wmiService[nameof(WindowsService.ProcessId)]); + KillProcessAndChildren(pid); + } + return true; + } + } + + /// + /// Kill a process, and all of its children, grandchildren, etc. + /// + /// Process ID. + private static void KillProcessAndChildren(int pid) + { + // Cannot close 'system idle process'. + if (pid == 0) { return;} + ManagementObjectSearcher searcher = new ManagementObjectSearcher("Select * From Win32_Process Where ParentProcessID=" + pid); + ManagementObjectCollection moc = searcher.Get(); + foreach (ManagementObject mo in moc) { KillProcessAndChildren(Convert.ToInt32(mo["ProcessID"])); } + try { Process proc = Process.GetProcessById(pid); proc.Kill(); } + catch (ArgumentException) { } // Process already exited. + } + public static bool Register(WindowsService ws) + { + // 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 + // sc.exe create NewService binpath= c:\windows\system32\NewServ.exe type= share start= auto depend= +TDI NetBIOS + // + // sc.exe [] create [] + // [type= {own | share | kernel | filesys | rec | interact type= {own | share}}] + // [start= {boot | system | auto | demand | disabled | delayed-auto}] + // [error= {normal | severe | critical | ignore}] + // [binpath= ] + // [group= ] + // [tag= {yes | no}] + // [depend= ] + // [obj= { | }] + // [displayname= ] + // [password= ] + + ProcessStartInfo startInfo = new ProcessStartInfo(); + startInfo.CreateNoWindow = false; + startInfo.UseShellExecute = true; + startInfo.FileName = "sc.exe"; + startInfo.WindowStyle = ProcessWindowStyle.Hidden; + List argumentlist = new List(); + argumentlist.Add($"create"); argumentlist.Add(ws.Name.Quote()); + argumentlist.Add("displayname="); argumentlist.Add(ws.DisplayName.Quote()); + if (ws.Xml_IdentityType == ServiceAccount.User) + { + argumentlist.Add($"obj="); argumentlist.Add(ws.Xml_Username.Quote()); + argumentlist.Add("password="); argumentlist.Add(ws.Xml_Password.Quote()); + } + else + { + argumentlist.Add($"obj="); argumentlist.Add(ws.Xml_IdentityType.ToString().Quote()); + } + var dependonparametert = String.Join("/", ws.Xml_Dependon); + argumentlist.Add($"depend="); argumentlist.Add(dependonparametert.Quote()); + + var startparameter = + ws.Xml_StartMode == ServiceStartMode.Automatic ? "auto" + : ws.Xml_StartMode == ServiceStartMode.Manual ? "demand" + : ws.Xml_StartMode == ServiceStartMode.Disabled ? "disabled" + : ws.Xml_StartMode == ServiceStartMode.Boot ? "boot" + : "system"; + argumentlist.Add($"start="); argumentlist.Add(startparameter.Quote()); + + var registerarguments = ""; + switch (ws.Xml_RegistrationMode) + { + case nameof(WindowsService.XmlStructure.WindowsService.Attributes.RegistrationMode.Values.standard): + { + registerarguments = ws.Xml_Arguments; + } + break; + case nameof(WindowsService.XmlStructure.WindowsService.Attributes.RegistrationMode.Values.topshelf): + { + //"C:\Log4ProIS\VRH.iLogger\VRH.Common.iLogger.Topshelf.exe" -displayname "VRH iLogger for Log4ProIS" -servicename "VRH iLogger for Log4ProIS" -APPCONFIG appconfigILOGGER.config + registerarguments = "-displayname " + ws.Xml_DisplayName.Quote() + " -servicename " + ws.Name.Quote() + " " + ws.Xml_Arguments; + } + break; + case nameof(WindowsService.XmlStructure.WindowsService.Attributes.RegistrationMode.Values.redis): + { + //"C:\Log4ProIS\VRH.iLogger\VRH.Common.iLogger.Topshelf.exe" -displayname "VRH iLogger for Log4ProIS" -servicename "VRH iLogger for Log4ProIS" -APPCONFIG appconfigILOGGER.config + registerarguments = "--service-run " + ws.Xml_Arguments.Quote() + " --service-name " + ws.Name.Quote(); + } + break; + } + var binpathparameter = Path.Combine(ws.Xml_InstallDir, ws.Xml_Exe).Quote() + " " + registerarguments; + argumentlist.Add($"binpath="); argumentlist.Add(binpathparameter.Quote()); + + startInfo.Arguments = String.Join(" ", argumentlist); + + ColorConsole.WriteLine(startInfo.FileName + " " + startInfo.Arguments); + try + { + using (Process exeProcess = Process.Start(startInfo)) { exeProcess.WaitForExit(); } + } + catch + { + // Log error. + } + return true; + } + + public static bool Unregister(WindowsService ws) + { + return Unregister(ws.Name, ws.Xml_StopTimeout); + } + public static bool Unregister(string sname,int stoptimeout=10000) + { + using (var s = GetServiceController(sname)) { Stop(s.ServiceName, stoptimeout); } + + ProcessStartInfo startInfo = new ProcessStartInfo(); + startInfo.CreateNoWindow = false; + startInfo.UseShellExecute = true; + startInfo.FileName = "sc.exe"; + startInfo.WindowStyle = ProcessWindowStyle.Hidden; + + List argumentlist = new List(); + argumentlist.Add($"delete"); argumentlist.Add(sname.Quote()); + startInfo.Arguments = String.Join(" ", argumentlist); + + ColorConsole.WriteLine(startInfo.FileName + " " + startInfo.Arguments); + try + { + // Start the process with the info we specified. + // Call WaitForExit and then the using statement will close. + using (Process exeProcess = Process.Start(startInfo)) { exeProcess.WaitForExit(); } + } + catch + { + // Log error. + } + return true; + // sc.exe delete "ServiceName" + // sc.exe \\myserver delete NewService + // + // sc.exe + // [] + // delete + // [] + } + + public static bool Start(string sname, int starttimeout) + { + using (var service = WindowsServiceManagerCore.GetServiceController(sname)) + { + if (service.ServicesDependedOn.Any()) + { + bool result = true; + foreach (var sn in service.ServicesDependedOn) { result = Start(sn.ServiceName, starttimeout); } + } + var sl = new List() { ServiceControllerStatus.Running, ServiceControllerStatus.Stopped, ServiceControllerStatus.Paused, }; + WaitForStatus(service, sl, starttimeout); + if (service.Status.Equals(ServiceControllerStatus.Stopped)) { service.Start(); } + else if (service.Status.Equals(ServiceControllerStatus.Running)) {; } + else if (service.Status.Equals(ServiceControllerStatus.Paused)) { service.Continue(); } + else { throw new Exception($"Start service {service.ServiceName} failed because of incorrect service status!"); } + service.WaitForStatus(ServiceControllerStatus.Running, new TimeSpan(0, 0, 0, 0, starttimeout)); + if (!service.Status.Equals(ServiceControllerStatus.Running)) { throw new Exception($"Start service {service.ServiceName} failed!"); } + return true; + } + } + public static bool Stop(string sname, int stoptimeout) + { + using (var service = WindowsServiceManagerCore.GetServiceController(sname)) + { + if (service.DependentServices.Any()) + { + bool result = true; + foreach (var s in service.ServicesDependedOn) + { + string sn; + try + { + sn = s.ServiceName; + result = Stop(s.ServiceName, stoptimeout); + } + catch { } + } + } + var sl = new List() { ServiceControllerStatus.Running, ServiceControllerStatus.Stopped, ServiceControllerStatus.Paused, }; + WaitForStatus(service, sl, stoptimeout); + if (service.Status.Equals(ServiceControllerStatus.Running)) { service.Stop(); } + else if (service.Status.Equals(ServiceControllerStatus.Paused)) { service.Stop(); } + else if (service.Status.Equals(ServiceControllerStatus.Stopped)) {; } + else + { + try { Kill(sname); } catch { } + if (!service.Status.Equals(ServiceControllerStatus.Stopped)) + { + throw new Exception($"Stop service {service.ServiceName} failed because of incorrect service status!"); + } + } + service.WaitForStatus(ServiceControllerStatus.Stopped, new TimeSpan(0, 0, 0, 0, stoptimeout)); + if (!service.Status.Equals(ServiceControllerStatus.Stopped)) { throw new Exception($"Stop service {service.ServiceName} failed!"); } + return true; + } + } + private async static void WaitForStatus(ServiceController srvCtl, List sl, int toms) + { + CancellationTokenSource cts = new CancellationTokenSource(); + var ct = cts.Token; + List tasks = new List(); + var ts = new TimeSpan(0, 0, 0, 0, toms); + foreach (var s in sl) { if (srvCtl.Status.Equals(s)) { return; } }; + foreach (var s in sl) { tasks.Add(Task.Run(new Action(() => { try { srvCtl.WaitForStatus(s, ts); } catch { } }), ct)); }; + // When any of the tasks completes, it means the service reached on of the statuses you were tracking + var t = await Task.WhenAny(tasks); + // To cancel the rest of the tasks that are still waiting + cts.Cancel(); + } + + } + #endregion WindowsServiceManagerCore class + #region WindowsServiceManagerXmlProcessor class + public class WindowsServiceManagerXmlProcessor : XmlParser + { + List _winservicelist; + List _winservicelistinstartorder; + List _winservicelistinstoporder; + #region constructor + public WindowsServiceManagerXmlProcessor(string xmlcs, string basefolder, string lcid) : base(xmlcs, basefolder, lcid, null) + { + _winservicelist = new List(); + var wsxmllist = GetAllXElements(nameof(WindowsService.XmlStructure.WindowsService)); + if (wsxmllist != null && wsxmllist.Any()) + { + foreach (var wsxml in wsxmllist) { var ws = new WindowsService(wsxml); if (ws.Valid) { _winservicelist.Add(ws); } } + } + _winservicelistinstartorder = ProduceDefinitionListInStartOrder(); + _winservicelistinstoporder = ProduceDefinitionListInStartOrder(); _winservicelistinstoporder.Reverse(); + } + #endregion constructor + #region GetDefinitionList + public List GetDefinitionList() { return _winservicelist; } + public List GetDefinitionListInStartOrder() { return _winservicelistinstartorder; } + public List GetDefinitionListInStopOrder() { return _winservicelistinstoporder; } + private List ProduceDefinitionListInStartOrder() + { + List listinstartorder = new List(); + bool ready = false;//akkor lesz false, ha már minden + while (!ready) + { + ready = true; + foreach (var s in _winservicelist) + { + var namelistinstartorder = listinstartorder.Select(x => x.Name); + 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 + foreach (var dli in dl) + { + if (string.IsNullOrWhiteSpace(dli)) { continue; } + if (!namelistinstartorder.Contains(dli)) { continue; }//van egy olyan függősége, ami nincs benne a startorder listában + } + listinstartorder.Add(s); break;//minden függősége már benne van a start order listában, így ez is bekerül oda + } + } + return listinstartorder; + } + #endregion GetDefinitionList + } + #endregion WindowsServiceManagerXmlProcessor class + #region WindowsService class + public class WindowsService : XmlLinqBase + { + #region fields + public string Name; + public bool Valid = true; + public string DisplayName; + public string Description; + public string PathName; + public string[] ThisDependsOn; + public string[] ServicesDependOnThis; + public int ProcessId; + public ServiceStartMode StartMode; + public string State; + public string Status; + public string StartName; + public string PriorityClass; + + public string Xml_DisplayName; + public string Xml_Description; + public string Xml_Exe; + public string Xml_InstallDir; + public ServiceStartMode Xml_StartMode; + public string Xml_Priority; + public string Xml_Arguments; + public string[] Xml_Dependon; + public string Xml_RegistrationMode; + public ServiceAccount Xml_IdentityType; + public string Xml_Username; + public string Xml_Password; + public int Xml_StartTimeout; + public int Xml_StopTimeout; + #endregion fields + + #region basic constructor + public WindowsService() { } + #endregion basic constructor + #region xml constructor + public WindowsService(XElement winservicexml) + { + string ATTRIBUTEMANDATORY = nameof(XmlStructure.WindowsService) + " attribute is mandatory! Name: {0}"; + Name = winservicexml.Attribute(XName.Get(nameof(XmlStructure.WindowsService.Attributes.Name)))?.Value; + if (!ValidServiceName(Name)) + { + Valid = false; + return; + //throw new ApplicationException(string.Format(ATTRIBUTEMANDATORY, nameof(XmlStructure.WindowsService.Attributes.Name))); + } + Xml_DisplayName = GetValue(nameof(XmlStructure.WindowsService.Attributes.DisplayName), winservicexml, Name); + Xml_Description = GetValue(nameof(XmlStructure.WindowsService.Attributes.Description), winservicexml, Xml_DisplayName); + Xml_Exe = winservicexml.Attribute(XName.Get(nameof(XmlStructure.WindowsService.Attributes.Exe)))?.Value; + if (string.IsNullOrWhiteSpace(Xml_Exe)) { throw new ApplicationException(string.Format(ATTRIBUTEMANDATORY, nameof(XmlStructure.WindowsService.Attributes.Exe))); } + Xml_InstallDir = winservicexml.Attribute(XName.Get(nameof(XmlStructure.WindowsService.Attributes.InstallDir)))?.Value; + if (string.IsNullOrWhiteSpace(Xml_Exe)) { throw new ApplicationException(string.Format(ATTRIBUTEMANDATORY, nameof(XmlStructure.WindowsService.Attributes.InstallDir))); } + + var startModestr = GetValue(nameof(XmlStructure.WindowsService.Attributes.StartMode), winservicexml, ""); + if (string.IsNullOrWhiteSpace(startModestr)) { startModestr = nameof(ServiceStartMode.Manual); } + Xml_StartMode = GetValue(startModestr, ServiceStartMode.Manual); + + 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(); + 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); } + } + Xml_Dependon = XmlDependon.ToArray(); + + Xml_RegistrationMode = GetValue(nameof(XmlStructure.WindowsService.Attributes.RegistrationMode), winservicexml, XmlStructure.WindowsService.Attributes.RegistrationMode.Values.DEFAULT); + Xml_RegistrationMode = Xml_RegistrationMode.Replace('-', '_'); + try + { + Xml_IdentityType = GetValue(nameof(XmlStructure.WindowsService.Attributes.UserName), winservicexml, ServiceAccount.LocalSystem); + Xml_Username = null; + Xml_Password = null; + } + catch + { + Xml_IdentityType = ServiceAccount.User; + Xml_Username = GetValue(nameof(XmlStructure.WindowsService.Attributes.UserName), winservicexml, XmlStructure.WindowsService.Attributes.UserName.Values.DEFAULT); + Xml_Password = GetValue(nameof(XmlStructure.WindowsService.Attributes.Password), winservicexml, ""); + } + Xml_StartTimeout = GetValue(nameof(XmlStructure.WindowsService.Attributes.StartTimeout), winservicexml, XmlStructure.WindowsService.Attributes.StartTimeout.Values.DEFAULT); + 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] != '@'; } + #endregion xml constructor + #region cloner constructor + public WindowsService(WindowsService ws) + { + Name = ws.Name; + Valid = ws.Valid; + Xml_DisplayName = ws.Xml_DisplayName; + Xml_Description = ws.Xml_Description; + Xml_Exe = ws.Xml_Exe; + Xml_InstallDir = ws.Xml_InstallDir; + Xml_StartMode = ws.Xml_StartMode; + Xml_Priority = ws.Xml_Priority; + Xml_Arguments = ws.Xml_Arguments; + Xml_Dependon = ws.Xml_Dependon; + Xml_RegistrationMode = ws.Xml_RegistrationMode; + Xml_IdentityType = ws.Xml_IdentityType; + Xml_Username = ws.Xml_Username; + Xml_Password = ws.Xml_Password; + Xml_StartTimeout = ws.Xml_StartTimeout; + Xml_StopTimeout = ws.Xml_StopTimeout; + } + #endregion cloner constructor + #region XmlStructure + public static class XmlStructure + { + public static class WindowsService + { + public static class Attributes + { + public static class Name { } + public static class DisplayName { } + public static class Description { } + public static class Exe { } + public static class Priority + { + public static class Values + { + public static string DEFAULT = "20"; + } + } + public static class StartMode { } + public static class InstallDir { } + public static class DependOn { } + public static class UserName + { + public static class Values + { + public static string DEFAULT = nameof(ProcessModelIdentityType.LocalService); + } + } + public static class Password { } + public static class Arguments { } + public static class StartTimeout + { + public static class Values + { + public static int DEFAULT = 10000; + } + } + public static class StopTimeout + { + public static class Values + { + public static int DEFAULT = 10000; + } + } + public static class RegistrationMode + { + public static class Values + { + public static string DEFAULT = nameof(standard); + public class standard { }; + public class redis { }; + public class topshelf { }; + } + } + } + } + } + #endregion XmlStructure + } + #endregion WindowsService class + +} diff --git a/Vrh.Log4Pro.MaintenanceConsole/Program.cs b/Vrh.Log4Pro.MaintenanceConsole/Program.cs index a7fdf3a..5e4b0bc 100644 --- a/Vrh.Log4Pro.MaintenanceConsole/Program.cs +++ b/Vrh.Log4Pro.MaintenanceConsole/Program.cs @@ -28,6 +28,9 @@ 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.ItemSeparator('-')) + .AddMenuItem(new Menu.Item("TOL", "Maintenance tools", MaintenanceToolManager.Execute)) .SetSelectionMode(Menu.SelectionMode.Single); mm.ExecuteMenu(); diff --git a/Vrh.Log4Pro.MaintenanceConsole/Vrh.Log4Pro.MaintenanceConsole.csproj b/Vrh.Log4Pro.MaintenanceConsole/Vrh.Log4Pro.MaintenanceConsole.csproj index e26e386..e35d36c 100644 --- a/Vrh.Log4Pro.MaintenanceConsole/Vrh.Log4Pro.MaintenanceConsole.csproj +++ b/Vrh.Log4Pro.MaintenanceConsole/Vrh.Log4Pro.MaintenanceConsole.csproj @@ -1,5 +1,6 @@  + Debug @@ -12,6 +13,8 @@ 512 true true + + AnyCPU @@ -33,6 +36,12 @@ 4 + + ..\packages\EntityFramework.6.4.0\lib\net45\EntityFramework.dll + + + ..\packages\EntityFramework.6.4.0\lib\net45\EntityFramework.SqlServer.dll + ..\packages\Microsoft.Web.Administration.11.1.0\lib\netstandard1.5\Microsoft.Web.Administration.dll @@ -47,6 +56,7 @@ ..\packages\System.AppContext.4.1.0\lib\net46\System.AppContext.dll + ..\packages\System.Console.4.0.0\lib\net46\System.Console.dll @@ -135,6 +145,9 @@ + + ..\packages\VRH.Common.2.19.0\lib\net45\VRH.Common.dll + ..\packages\Vrh.XmlProcessing.1.23.0\lib\net45\Vrh.XmlProcessing.dll @@ -143,8 +156,10 @@ - - + + + + @@ -153,6 +168,7 @@ Always + @@ -164,4 +180,12 @@ + + + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + + \ No newline at end of file diff --git a/Vrh.Log4Pro.MaintenanceConsole/Vrh.NugetModuls.Documentations/VRH.Common/ReadMe.md b/Vrh.Log4Pro.MaintenanceConsole/Vrh.NugetModuls.Documentations/VRH.Common/ReadMe.md new file mode 100644 index 0000000..7b61748 --- /dev/null +++ b/Vrh.Log4Pro.MaintenanceConsole/Vrh.NugetModuls.Documentations/VRH.Common/ReadMe.md @@ -0,0 +1,297 @@ +# Vrh.Common +A modul a Vonalkód Rendszerház fejlesztési környezetében szabványosított és +hasznosan alkalmazható eszközeinek gyűjtőhelye. + +> Igényelt minimális framework verzió: **4.5** + +> Teljes funkcionalitás és hatékonyság kihasználásához szükséges legalacsonyabb framework verzió: **4.5** + +# Főbb összetevők +### Interfészek +* **[IManage](##IManage)** + +### Standard osztályok +* **[CheckListJSON](##CheckListJSON)** +* **[ReturnInfoJSON](##ReturnInfoJSON)** +* **[SelectListJSON](##SelectListJSON)** + +## IManage +Generikus interfész, melyben azt a típust kell megadni, amely menedzselését végzi. +```javascript +/// +/// Meghatározza és előírja egy karbantartást és hozzáférést +/// biztosító osztály elvárt tulajdonságait és módszereit. +/// +public interface IManage +{ + /// + /// A kezelt típust össze egyedét szolgáltató tulajdonság. + /// + List All { get; } + + /// + /// A kezelt típus egy elemét adja vissza az egyedi azonosító segítségével. + /// + /// Az elem egyedi azonosítója. + /// + T Get(int id); + /// + /// A kezelt típus egy elemét adja vissza a megadott név segítségével. + /// + /// Az elem egyedi neve. + /// + T Get(string name); + + /// + /// Létrehozza a kezelt típus egy elemét. + /// + /// A kezelt típus egy eleme, amit hozzá kell adni. + void Create(T item); + + /// + /// A kezelt típus egy elemét törli az egyedi azonosító alapján. + /// + /// A törlendő elem egyedi azonosítója. + void Delete(int id); + /// + /// A kezelt típus egy elemét törli az egyedi neve alapján. + /// + /// A törlendő elem egyedi neve. + void Delete(string name); + + /// + /// A kezelt típus egy elemének módosítása. + /// Ha nem létezik az hiba. + /// + /// A kezelt típus egy eleme. + void Update(T item); +} +``` + +## CheckListJSON +```javascript +/// +/// Egy meghívott akció válaszüzenetének egy lehetséges meghatározott szerkezete. +/// Valamely lista ellenőrzéshez használható, amelyben a Checked oszlopban jelölhető az ellenőrzés eredménye. +/// +public class CheckListJSON +{ + /// + /// Az ellenőrzendő illetve ellenőrzött azonosító. + /// + public string Value { get; set; } + + /// + /// Az ellenőrzéskor megtalált név vagy leíró. + /// + public string Text { get; set; } + + /// + /// Az ellenőrzés eredményét jelző logikai érték, mely a felhasználáskor + /// az üzleti logikától függ. + /// + public bool Checked { get; set; } +} +``` + +## ReturnInfoJSON +```javascript +/// +/// Egy meghívott akció válaszüzenetének egy lehetséges meghatározott szerkezete. +/// A válasz érték (ReturnValue) és üzenet (ReturnMessage) formájú. +/// Sikeres végrehajtás esetén mindig 0 legyen a ReturnValue. +/// Sikertelen esetben ettől eltérő, de ha nincs egyéb ok, akkor hiba esetén legyen -1. +/// Alapértelmezett érték: 0, "Az indított akció sikeresen lezajlott!" } +/// +public class ReturnInfoJSON +{ + /// + /// Egy reprezentatív értéke, mely a sikerességtől függ. + /// Ha nincs hiba az akció végrehajtásában, akkor 0 legyen az értéke. + /// Alapértelmezett értéke: 0 + /// + public int ReturnValue { get; set; } = 0; + + /// + /// Az akció üzenete. Hiba esetén a hibaüzenet szövege. + /// Alapértelmezett értéke: "Az indított akció sikeresen lezajlott!" + /// + public string ReturnMessage { get; set; } = "Az indított akció sikeresen lezajlott!"; +} +``` + +## SelectListJSON +```javascript +/// +/// Egy meghívott akció válaszüzenetének egy lehetséges meghatározott szerkezete. +/// Egy listához használható, mely értékeit és azonosítóit fel lehet használni. +/// +/// +/// Egyenértékű a System.Web.Mvc.SelectListItem osztállyal, de nem onnan származik. +/// Az ott szereplő leírás: +/// "Represents the selected item in an instance of the System.Web.Mvc.SelectList class." +/// +public class SelectListJSON +{ + /// + /// Jelzi, hogy ez az elem a listában letiltott. + /// + public bool Disabled { get; set; } + + /// + /// A csoport jelölése. Alapértelmezett értéke: null + /// + public SelectListGroup Group { get; set; } + + /// + /// Jelzi, hogy ez az elem a listában kiválasztott. + /// + public bool Selected { get; set; } + + /// + /// A listelem szövege, ami megjelenik. + /// + public string Text { get; set; } + + /// + /// A listelem értéke. + /// + public string Value { get; set; } +} + +#region SelectListGroup public class +/// +/// Represents the optgroup HTML element and its attributes. In a select list, +/// multiple groups with the same name are supported. +/// They are compared with reference equality. +/// +/// +/// A System.Mvc.SelectListItem-mel való kompatibilitás miatt van itt. +/// A 'summary' szövege is onnan másolt. +/// +public class SelectListGroup +{ + /// + /// Beállítja, hogy az adott csoport engedélyezett-e. + /// + public bool Disabled { get; set; } + + /// + /// A csoport neve. + /// + public string Name { get; set; } +} +#endregion SelectListGroup public class +``` + + +## Version History: +#### 2.13.2 (2020.03.27) Patches: +- NuGet csomag módosítása úgy, hogy a modul ReadMe.md "Build Action" tulajdonsága "None" legyen a telepítés után. Install.ps1 hozzáadása. + +#### 2.13.1 (2020.03.26) Patches: +- Felesleges függések törlése. +- XML comment dokumentáció pontosítása. + +#### 2.13.0 (2020.03.19) Compatible changes: +- Vrh.Web.Common.Lib egyes elemeinek átemelése ide + +#### 2.12.1 (2020.02.13) Patches: +- SelectListJSON egyenlőség vizsgálat javítása + +#### 2.12.0 (2020.02.13) Compatible changes: +- SelectListJSON struktúrába beépítésre került egy speciális egyenlőség vizsgálat, amely a Value, a Text és a Group mezők értékének egyenlősége +esetén ad igaz értéket; a Disabled és a Selected mezők értéke az egyenlőség vizsgálatban nem játszik szerepet +- CheckListJSON és ReturnInfoJSON strukturákhoz analóg módon, mely ugyanezekkel a feltételekkel dolgozik. + +#### 2.11.1-3 (2019.12.19) Compatible changes: +- CommandLine class hibák javítása. + +#### 2.11.0 (2019.12.17) Compatible changes: +- Topshelf formátumú parancssori paraméterek kezelése: -NAME:value + +#### 2.10.1 (2019.12.17) Patches: +- CommandLine osztályban egy javítás + +#### 2.10.1 (2019.12.05) Patches: +- SerializeObject metódusban a string-ek külön kezelése. + +#### 2.10.0 (2019.10.08) Compatible changes: +- ToEnum string extension hozzáadása, amelyik egy stringből megadott tipusú enumra konvertál, vagy a típus (Enum) defaultját adja + +#### 2.9.0 (2019.09.12) Compatible changes: +- EntryAsseblyFixer static class hozzáadása, ami beállítja amegfelelő EntryAssembly-t, ha az alakalmazás tér dinamikus hostolású, ahol null, vagy dynamic az EntryAssembly +- EntryAsseblyFixer egység tesztjei + +## 2.8.1 (2019.09.07): +### Patch: +- Name property típusa javítva. + +## v2.8.0 (2019.09.06): +### Compatibility API changes: +- ReturnDictJSON adatstruktúra hozzáadva. + +## 2.7.0 (2019.08.15) Compatible changes: +### Compatibility API changes: +- Az EntityFramework extension bővítése az AlreadyOrdered függvénynel, amely megmondja egy IQueryable-ről, hogy rendezett-e már (tehát a további rendezéséhez az OrderBy, vagy a ThenBy-t kell-e használni) + +## 2.6.0 (2019.08.01) Compatible changes: +### Compatibility API changes: +- Extensions bővítése az EntityFramework extension-nel, EntityFrameworkQueryHelper bővítő osztály, SmartOrder bővítő metódus (IQueryable típusra) + +## 2.5.0 (2019.07.10) Compatible changes: +### Compatibility API changes: +- ExtensionMethods bővítése az Enum extensionssel, Enumdata attribútum osztály + +## 2.3.0 (2019.05.14) Compatible changes: +- IManage interfész áthelyezése Vrh.Web.Common.Lib 1.18.1-es változatából. +- Standard osztályok (CheckListJSON, ReturnInfoJSON, SelectListJSON) áthelyezése Vrh.Web.Common.Lib 1.18.1-es változatából. + +## 2.2.0 (2018.12.17) +### Compatible changes: +- VrhConvert.SerializeObject Private metódus publikussá tétele. + +## 2.1.0 (2018.12.17) +### Compatible changes: +- Új függvények beillesztése a conversion részbe. + +## 2.0.1 (2018.12.12) +### Patches: +- ConnandLine osztály metóduasdinak kommentezése és egy apró javítás: a GetCommandLineArgument lekezeli, ha az argumentname paramétere üres string. + +## 2.0.0 (2018.11.28) +### Braking change: +- 3.5-ös .Net framwork verzi támogatásának megszüntetése új target verzió: 4.5 +### Compatibility API changes: +- CommandLine static segéd osztály hozzáadása + +## 1.13.0 (2017.04.04) +### Compatibility API changes: +- String Extension method: FromHexOrThis + +## 1.12.0 (2017.03.29) +### Compatibility API changes: +- FixStack class hozzáadása +### Patches: +- UnitTest method elnevezések javítása (konvenció kidolgozása) + +## 1.11.0 (2017.03.28) +### Compatibility API changes: +- Assembly Extension methodok: Version, AssemblyAttribute + +## 1.10.0 (2017.03.16) +### Compatibility API changes: +- StringBuilder Extension methodok: AppendWithSeparator, Reverse +### Patches: +- Extension methodok helyének hozzáadása. +- Test projekt hozzáadása + +## V1.9.2 (2017.02.21) +### Patches: +- Projekt könyvrtárszerkezet rendbetétele. +- AutoBuild Vrh Nuget csomaggá alakítás (összes Nuget-tel kapcsolatos elvárás átvezetése) +- MinFramweork meghatározás + + + + \ No newline at end of file diff --git a/Vrh.Log4Pro.MaintenanceConsole/WebApplicationManager.cs b/Vrh.Log4Pro.MaintenanceConsole/WebApplicationManager.cs deleted file mode 100644 index 85105ca..0000000 --- a/Vrh.Log4Pro.MaintenanceConsole/WebApplicationManager.cs +++ /dev/null @@ -1,939 +0,0 @@ -using System; -using System.IO; -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.XmlProcessing; -using System.Xml.Linq; - -namespace Vrh.Log4Pro.MaintenanceConsole -{ - #region WebApplicationManager - public static class WebApplicationManager - { - #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 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(); - - 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.Execute(sr.SelectedKeyList); - } - return null; - } - #endregion public method: Execute - #region private method: DisplayWebAppInfo - private static object DisplayWebAppInfo(object waobj,int lineix) - { - 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 - { - return null; - } - return ""; - } - #endregion private method: DisplayWebAppInfo - #region - private static object Restart(object dobj, object parameters) - { - WebApplication d = dobj as WebApplication; - using (ServerManager sm = new ServerManager()) - { - try { WebApplicationManagerCore.GetPool(sm, d.Xml_PoolName)?.Stop(); } catch { Console.WriteLine($"Pool {d.Xml_PoolName} already stopped."); } - try { WebApplicationManagerCore.GetSite(sm, d.Xml_SiteName)?.Stop(); } catch { Console.WriteLine($"Site {d.Xml_SiteName} already stopped."); } - - SiteStart(d, parameters); - PoolStart(d, parameters); - PoolRecycle(d, parameters); - - Console.WriteLine($"Pool {d.Xml_PoolName} and site {d.Xml_SiteName} restarted."); - return parameters; - } - } - private - static object PoolStart(object dobj, object parameters) - { - WebApplication d = dobj as WebApplication; - using (ServerManager sm = new ServerManager()) - { - bool success = false; - for (var i = 1; i <= 10; i++) - { - var p = WebApplicationManagerCore.GetPool(sm, d.Xml_PoolName); - if (p != null && p.State == ObjectState.Stopped) { p.Start(); success = true; break; } - else - { - Console.WriteLine($"Trying to start pool {d.Xml_PoolName} ... Press key 'X' to exit..."); - if (Console.KeyAvailable) { if (Console.ReadKey().KeyChar.ToString().ToUpper() == "X") { break; } } - - Thread.Sleep(1000); - } - } - var successstr = success ? "started" : "NOT started"; - Console.WriteLine($"{d.Xml_PoolName} {successstr}."); - return parameters; - } - } - private static object PoolRecycle(object dobj, object parameters) - { - WebApplication d = dobj as WebApplication; - using (ServerManager sm = new ServerManager()) - { - bool success = false; - for (var i = 1; i < 4; i++) - { - var p = WebApplicationManagerCore.GetPool(sm, d.Xml_PoolName); - if (p != null && p.State == ObjectState.Started) { p.Recycle(); success = true; break; } - else - { - Console.WriteLine($"Trying to recycle pool {d.Xml_PoolName} ... Press key 'X' to exit..."); - if (Console.KeyAvailable) { if (Console.ReadKey().KeyChar.ToString().ToUpper() == "X") { break; } } - Thread.Sleep(1000); - } - } - var successstr = success ? "recycled" : "NOT recycled"; - Console.WriteLine($"{d.Xml_PoolName} {successstr}."); - return parameters; - } - } - private static object PoolStop(object dobj, object parameters) - { - 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); - if (p != null && p.State == ObjectState.Started) { p.Stop(); success = true; break; } - else - { - Console.WriteLine($"Trying to stop pool {d.Xml_PoolName} ... Press key 'X' to exit..."); - if (Console.KeyAvailable) { if (Console.ReadKey().KeyChar.ToString().ToUpper() == "X") { break; } } - - Thread.Sleep(1000); - } - } - var successstr = success ? "stopped" : "NOT stopped"; - Console.WriteLine($"{d.Xml_PoolName} {successstr}."); - return parameters; - } - } - private static object SiteStart(object dobj, object parameters) - { - WebApplication d = dobj as WebApplication; - using (ServerManager sm = new ServerManager()) - { - bool success = false; - for (var i = 1; i < 4; i++) - { - var s = WebApplicationManagerCore.GetSite(sm, d.Xml_SiteName); - if (s != null && s.State == ObjectState.Stopped) { s.Start(); success = true; break; } - else - { - Console.WriteLine($"Trying to start site {d.Xml_SiteName} ... Press key 'X' to exit..."); - if (Console.KeyAvailable) { if (Console.ReadKey().KeyChar.ToString().ToUpper() == "X") { break; } } - Thread.Sleep(1000); - } - } - var successstr = success ? "started" : "NOT started"; - Console.WriteLine($"{d.Xml_SiteName} {successstr}."); - return parameters; - } - } - private static object SiteStop(object dobj, object parameters) - { - WebApplication d = dobj as WebApplication; - using (ServerManager sm = new ServerManager()) - { - bool success = false; - for (var i = 1; i < 4; i++) - { - var s = WebApplicationManagerCore.GetSite(sm, d.Xml_SiteName); - if (s != null && s.State == ObjectState.Started) { s.Stop(); success = true; break; } - else - { - Console.WriteLine($"Trying to stop site {d.Xml_SiteName} ... Press key 'X' to exit..."); - if (Console.KeyAvailable) { if (Console.ReadKey().KeyChar.ToString().ToUpper() == "X") { break; } } - Thread.Sleep(1000); - } - } - var successstr = success ? "stopped" : "NOT stopped"; - Console.WriteLine($"{d.Xml_SiteName} {successstr}."); - return parameters; - } - } - private static object Register(object dobj, object parameters) - { - 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); - Console.WriteLine($"{d.Xml_AppName} is registered in site {d.Xml_SiteName} using pool {d.Xml_PoolName}."); - return parameters; - } - private static object Unregister(object dobj, object parameters) - { - WebApplication d = dobj as WebApplication; - WebApplicationManagerCore.UnRegisterWebApplication(d.Xml_AppName, d.Xml_PoolName, d.Xml_SiteName, d.Xml_ForceRemovePool, d.Xml_ForceRemoveSite); - Console.WriteLine($"{d.Xml_AppName} is unregistered from site {d.Xml_SiteName} and from pool {d.Xml_PoolName}."); - return parameters; - } - private static object SetImpersonateIdentity(object dobj, object parameters) - { - WebApplication d = dobj as WebApplication; - string username="", password = "",impersonate="FALSE"; - bool parametersarealreadyset = parameters != null; - string olduserinfo = WebApplicationManagerCore.GetImpersonateIdentityInfo(d.Xml_IdentityConfigFile); - if (parametersarealreadyset) - { - impersonate = ((Dictionary)parameters)["impersonate"]; - username = ((Dictionary)parameters)["username"]; - password = ((Dictionary)parameters)["password"]; - } - else - { - while(true) - { - - Console.WriteLine($"Current user info: {olduserinfo}"); - Console.WriteLine("Set impersonate-on status (true/false), then [Enter], EX=exit."); - impersonate = Console.ReadLine().ToUpper(); - if (impersonate == "EX") { return null; } - else if (impersonate == "FALSE") { break; } - else if (impersonate == "TRUE") - { - Console.WriteLine("Enter username, then [Enter]."); - var un = !string.IsNullOrWhiteSpace(d.Xml_PoolUsername) ? $"empty={d.Xml_PoolUsername }," : ""; - Console.WriteLine($"{un}EX=exit"); - username = Console.ReadLine().ToUpper(); - if (impersonate == "EX") { return null; } - Console.WriteLine("Enter password, then [Enter]"); - var pw = !string.IsNullOrWhiteSpace(d.Xml_PoolPassword) ? $"empty={d.Xml_PoolPassword}," : ""; - Console.WriteLine($"{pw}EX=exit"); - password = Console.ReadLine().ToUpper(); - if (impersonate == "EX") { return null; } - break; - //bool valid = System.Web.ApplicationSerices.AuthenticationService.ValidateUser(username, password, mull); - } - else - { - Menu.IncorrectSelection(); - continue; - } - } - parameters = new Dictionary { { "impersonate", impersonate }, { "username", username }, { "password", password }, }; - } - WebApplicationManagerCore.SetImpersonateIdentity(d.Xml_IdentityConfigFile, impersonate, username, password); - Console.WriteLine($"Impersonate identity changed for webapp {d.Xml_AppName}."); - Console.WriteLine($"From '{olduserinfo}' to '{WebApplicationManagerCore.GetImpersonateIdentityInfo(d.Xml_IdentityConfigFile)}'"); - - return parameters; - } - private static object PoolSetUserAccount(object dobj, object parameters) - { - WebApplication d = dobj as WebApplication; - string username, password = ""; - bool parametersarealreadyset = parameters != null; - string olduserinfo = WebApplicationManagerCore.GetUserInfo(d.Xml_PoolName); - if (parametersarealreadyset) - { - username = ((Dictionary)parameters)["username"]; - password = ((Dictionary)parameters)["password"]; - } - else - { - Console.WriteLine($"Current user info: {olduserinfo}"); - Console.WriteLine("Enter username, then [Enter]."); - Console.WriteLine("Special usernames are: (Empty=API) "); - Console.WriteLine($" (API) {nameof(ProcessModelIdentityType.ApplicationPoolIdentity)}"); - Console.WriteLine($" (LSE) {nameof(ProcessModelIdentityType.LocalService)}"); - Console.WriteLine($" (LSY) {nameof(ProcessModelIdentityType.LocalSystem)}"); - Console.WriteLine($" (NSE) {nameof(ProcessModelIdentityType.NetworkService)}"); - ColorConsole.WriteLine(); - ColorConsole.Write(" (EX) ", ConsoleColor.Red); ColorConsole.WriteLine("Exit"); - username = Console.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); } - 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 - { - Console.WriteLine("Enter password, then [Enter]"); - password = Console.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); - Console.WriteLine($"Pool user changed from {olduserinfo} to {WebApplicationManagerCore.GetUserInfo(d.Xml_PoolName)} for pool {d.Xml_PoolName}."); - return parameters; - } - #endregion - } - - public static class WebApplicationManagerCore - { - #region private method: CollectWebAppInfo - public static WebApplication CollectWebAppInfo(SiteCollection sites,ApplicationPoolCollection pools, WebApplication wadef) - { - var wa = new WebApplication(wadef); - try - { - wa.Site = sites[wa.Xml_SiteName]; - if (wa.Site == null) { throw new Exception(); } - else - { - 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 = GetImpersonateIdentityInfo(wa.Xml_IdentityConfigFile); - } - } - } - 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 - { - 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 - { - wa.ApplicationPool = null; - wa.PoolState = "Unregistered/Unknown"; - wa.PoolAccount = ""; - } - return wa; - } - #endregion private method: CollectWebAppInfo - - #region private method:RegisterWebApplication - public static void RegisterWebApplication(string sitename, string poolname, string appname, string poolphypath, string sitephypath, int siteport, bool recreatepool, bool recreatesite, bool recreateapp,ManagedPipelineMode plmode) - { - using (ServerManager serverManager = new ServerManager()) - { - if (!isExistWebAppPool(serverManager, poolname)) { CreateWebAppPool(serverManager, poolname, plmode); } - else if (recreatepool) { RemoveWebAppPool(serverManager, poolname); CreateWebAppPool(serverManager, poolname, plmode); } - - if (!isExistWebSite(serverManager, sitename)) { CreateWebSite(serverManager, sitename, poolname, sitename, sitephypath, siteport); } - else if (recreatesite) { RemoveWebSite(serverManager, sitename); CreateWebSite(serverManager, sitename, poolname, sitename, sitephypath, siteport);} - - SetItemProperty(serverManager, poolname, "managedRuntimeVersion", "v4.0"); - SetItemProperty(serverManager, poolname, "enable32BitAppOnWin64", "true"); - - if (!isExistWebApp(serverManager, sitename, appname)) { CreateWebApp(serverManager, appname, poolname, sitename, poolphypath); } - else if (recreateapp) { RemoveWebApp(serverManager, appname, sitename); CreateWebApp(serverManager, appname, poolname, sitename, poolphypath); } - - CommitChanges(serverManager, poolname); - } - } - #endregion private method:RegisterWebApplication - #region private method:UnRegisterWebApplication - public static void UnRegisterWebApplication(string appname, string poolname, string sitename = "Default Web Site",bool forceremovepool=false, bool forceremovesite = false) - { - using (ServerManager sm = new ServerManager()) - { - if (isExistWebApp(sm, sitename, appname)) { RemoveWebApp(sm, appname, sitename); } - if (isExistWebAppPool(sm,poolname) && forceremovepool) { RemoveWebAppPool(sm,poolname); } - if (isExistWebSite(sm, sitename) && forceremovesite) { RemoveWebSite(sm, poolname); } - CommitChanges(sm, poolname); - } - } - #endregion private method:UnRegisterWebApplication - #region private method:SetImpersonateIdentity - public static void SetImpersonateIdentity(string filepath, string impersonate, string username, string password) - { - var identityxml = new XElement("identity"); - identityxml.Add(new XAttribute("impersonate", impersonate.ToLower())); - if (impersonate.ToLower() == "true") - { - if (!string.IsNullOrWhiteSpace(username)) - { - identityxml.Add(new XAttribute("userName", username)); - identityxml.Add(new XAttribute("password", string.IsNullOrWhiteSpace(password)?"":password)); - } - } - identityxml.Save(filepath); - } - #endregion private method:SetImpersonateIdentity - #region private method:SetPoolUserAccount - public static void SetPoolUserAccount(string appname, string sitename, string username, string password) - { - using (var sm = new ServerManager()) - { - //var pool = GetPool(GetPoolName(sitename, appname)); - var pool = GetPool(sm, sitename, appname); - if (username == nameof(ProcessModelIdentityType.ApplicationPoolIdentity) - || username == nameof(ProcessModelIdentityType.LocalService) - || username == nameof(ProcessModelIdentityType.LocalSystem) - || username == nameof(ProcessModelIdentityType.NetworkService)) - { - pool.ProcessModel.UserName = null; - pool.ProcessModel.Password = null; - pool.ProcessModel.IdentityType = (ProcessModelIdentityType)Enum.Parse(typeof(ProcessModelIdentityType), username); - } - else // if (ProcessModelIdentityType.SpecificUser) - { - pool.ProcessModel.UserName = username; - pool.ProcessModel.Password = password; - pool.ProcessModel.IdentityType = ProcessModelIdentityType.SpecificUser; - } - CommitChanges(sm, pool.Name); - } - } - #endregion private method:SetPoolUserAccount - #region private method:CommitChanges - private static void CommitChanges(ServerManager serverManager, string poolname) - { - serverManager.CommitChanges(); - if (isExistWebAppPool(poolname)) - { - var p = GetPool(serverManager, poolname); - if (p.State == ObjectState.Started) { p.Recycle(); } - } - } - #endregion private method:CommitChanges - - #region private methods: Get information (with no ServerManager parameter) - public static string GetImpersonateIdentityInfo(string filepath) - { - try - { - var xml = XElement.Load(filepath); - var identityXml = xml; //?.Element(XName.Get("identity")); - if (identityXml == null) { return "no info"; } - else - { - 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}"; - return retinfo; - } - } - catch { return "no info (exception)"; } - } - public static string GetUserInfo(string poolname) - { - using (var sm2 = new ServerManager()) - { - var pool = sm2.ApplicationPools[poolname]; - string userinfo = ""; - if (pool != null) - { - if (pool.ProcessModel.IdentityType == ProcessModelIdentityType.SpecificUser) - { - userinfo = $"{pool.ProcessModel.UserName}({pool.ProcessModel.Password})"; - } - else - { - userinfo = $"{pool.ProcessModel.IdentityType}"; - } - } - return userinfo; - } - } - private static string GetPoolName(string sitename,string appname) - { - using (ServerManager serverManager = new ServerManager()) - { - return GetPoolName(serverManager, sitename, appname); - } - } - public static ApplicationPool GetPool(string sitename, string appname) - { - using (ServerManager serverManager = new ServerManager()) - { - return GetPool(serverManager, sitename, appname); - } - } - public static ApplicationPool GetPool(string poolname) - { - using (ServerManager serverManager = new ServerManager()) - { - return GetPool(serverManager,poolname); - } - } - private static bool isExistWebAppPool(string poolname) - { - using (ServerManager serverManager = new ServerManager()) - { - return isExistWebAppPool(serverManager, poolname); - } - } - private static bool isExistWebApp(string sitename,string appname) - { - using (ServerManager serverManager = new ServerManager()) - { - return isExistWebApp(serverManager ,sitename, appname); - } - } - private static bool isExistWebSite(string sitename) - { - using (ServerManager serverManager = new ServerManager()) - { - return isExistWebSite(serverManager ,sitename); - } - } - #endregion private methods: Get information (with no ServerManager parameter) - #region private methods: Get information - public static string GetUserInfo(ServerManager sm, string poolname) - { - var pool = sm.ApplicationPools[poolname]; - string userinfo = ""; - if (pool != null) - { - if (pool.ProcessModel.IdentityType == ProcessModelIdentityType.SpecificUser) - { - userinfo = $"{pool.ProcessModel.UserName}({pool.ProcessModel.Password})"; - } - else - { - userinfo = $"{pool.ProcessModel.IdentityType}"; - } - } - return userinfo; - } - public static string GetPoolName(ServerManager serverManager,string sitename, string appname) - { - Site site = serverManager.Sites[sitename]; - Application application = site.Applications[Path.Combine("/", appname)]; - return application.ApplicationPoolName; - } - public static ApplicationPool GetPool(ServerManager serverManager, string sitename, string appname) - { - Site site = serverManager.Sites[sitename]; - Application application = site.Applications[Path.Combine("/",appname)]; - return serverManager.ApplicationPools[application.ApplicationPoolName]; - } - public static ApplicationPool GetPool(ServerManager serverManager, string poolname) - { - return serverManager.ApplicationPools[poolname]; - } - public static Site GetSite(ServerManager serverManager, string sitename) - { - return serverManager.Sites[sitename]; - } - private static bool isExistWebAppPool(ServerManager serverManager, string poolname) - { - try - { - var p = serverManager.ApplicationPools[poolname]; - if (p == null) { return false; } - return p.State != ObjectState.Unknown; - } - catch { return false; } - } - private static bool isExistWebApp(ServerManager serverManager, string sitename, string appname) - { - try - { - var an = Path.Combine(@"/",appname); - var app = serverManager.Sites[sitename].Applications[an]; - return app != null; - } - catch { return false; } - } - private static bool isExistWebSite(ServerManager serverManager, string sitename) - { - try - { - var s = serverManager.Sites[sitename]; - if (s == null) { return false; } - return s.State != ObjectState.Unknown; - } - catch { return false; } - } - #endregion private methods: Get information - #region private methods: Set information - private static void SetItemProperty(ServerManager serverManager, string poolname, string propertyname, string propertyvalue) - { - var pool = GetPool(serverManager, poolname); - pool.SetAttributeValue(propertyname, propertyvalue); //????????????????????????? - } - private static void CreateWebAppPool(ServerManager serverManager ,string poolname, ManagedPipelineMode plmode) - { - serverManager.ApplicationPools.Add(poolname); - ApplicationPool pool = serverManager.ApplicationPools[poolname]; - pool.ManagedPipelineMode = plmode; - } - private static void CreateWebApp(ServerManager serverManager, string appname, string poolname, string sitename, string poolphypath) - { - Site site = serverManager.Sites[sitename]; - Application application = site.Applications[Path.Combine("/",appname)]; - if (application != null) { site.Applications.Remove(application); } - application = site.Applications.Add(Path.Combine("/",appname), poolphypath); - application.ApplicationPoolName = poolname; - } - private static void CreateWebSite(ServerManager serverManager, string sitename, string poolname, string hostheader, string sitephypath, int siteport = 8000) - { - Site mySite = serverManager.Sites.Add(sitename, sitephypath, siteport); - mySite.Applications[0].ApplicationPoolName = poolname; - //mysite.Applications[0].VirtualDirectories[0].PhysicalPath = sitephypath; - mySite.ServerAutoStart = true; - } - private static void RemoveWebSite(ServerManager serverManager, string sitename) - { - Site mySite = serverManager.Sites[sitename]; - if (mySite != null) { serverManager.Sites.Remove(mySite); } - } - private static void RemoveWebAppPool(ServerManager serverManager,string poolname) - { - try - { - ApplicationPool pool = serverManager.ApplicationPools[poolname]; - serverManager.ApplicationPools.Remove(pool); - } - catch { } - } - private static void RemoveWebApp(ServerManager serverManager, string appname, string sitename) - { - Site site = serverManager.Sites[sitename]; - Application application = site.Applications[Path.Combine("/",appname)]; - site.Applications.Remove(application); - } - #endregion private methods: Set information (wit no ServerManager parameter) - #region private methods: Set information (with no ServerManager parameter) - private static void SetItemProperty(string poolname, string propertyname, string propertyvalue) - { - using (ServerManager serverManager = new ServerManager()) - { - SetItemProperty(serverManager, poolname, propertyname, propertyvalue); - CommitChanges(serverManager, poolname); - } - } - private static void CreateWebAppPool(string poolname, ManagedPipelineMode plmode) - { - using (ServerManager serverManager = new ServerManager()) - { - CreateWebAppPool(serverManager, poolname, plmode); - CommitChanges(serverManager, poolname); - } - } - private static void CreateWebApp(string appname, string poolname, string sitename, string poolphypath) - { - using (ServerManager serverManager = new ServerManager()) - { - CreateWebApp(serverManager, appname, poolname, sitename, poolphypath); - CommitChanges(serverManager, poolname); - } - } - private static void CreateWebSite(string sitename, string poolname, string hostheader, string sitephypath, int siteport = 8000) - { - using (ServerManager serverManager = new ServerManager()) - { - CreateWebSite(serverManager, sitename, poolname, hostheader, sitephypath, siteport); - CommitChanges(serverManager, poolname); - } - } - private static void RemoveWebSite(string sitename) - { - using (ServerManager serverManager = new ServerManager()) { RemoveWebSite(serverManager, sitename); } - } - private static void RemovePool(string poolname) - { - using (ServerManager sm = new ServerManager()) - { - RemoveWebAppPool(sm, poolname); - CommitChanges(sm, poolname); - } - } - private static void RemoveWebApp(string sitename, string appname) - { - using (ServerManager sm = new ServerManager()) - { - RemoveWebApp(sm, appname, sitename); - CommitChanges(sm, GetPoolName(sm,sitename, appname)); - } - } - #endregion private methods: Set information (with no ServerManager parameter) - - } - #region WebApplicationManagerXmlProcessor class - public class WebApplicationManagerXmlProcessor : XmlParser - { - #region constructor - public WebApplicationManagerXmlProcessor(string xmlcs, string basefolder, string lcid) : base(xmlcs, basefolder, lcid, null) - { - _webapplist = new List(); - var waxmllist = GetAllXElements(nameof(WebApplication.XmlStructure.WebApplication)); - if (waxmllist != null && waxmllist.Any()) - { - foreach (var waxml in waxmllist) { _webapplist.Add(new WebApplication(waxml)); } - } - } - #endregion constructor - #region properties - List _webapplist = null; - #endregion properties - - #region GetDefinitionList - public List GetDefinitionList() { return _webapplist; } - #endregion GetDefinitionList - } - #endregion WebApplicationManagerXmlProcessor class - #region WebApplication class - public class WebApplication : XmlLinqBase - { - #region properties from Xml definition - public string Xml_AppName; - public string Xml_Description; - public string Xml_PoolName; - public string Xml_SiteName; - public string Xml_AppPhysicalPath; - public ManagedPipelineMode Xml_PoolPipeLineMode; - public string Xml_SitePhysicalPath; - public string Xml_IdentityConfigFile; - public ProcessModelIdentityType Xml_PoolIdentitytype; - public string Xml_PoolUsername; - public string Xml_PoolPassword; - public bool Xml_RecreatePool; - public bool Xml_RecreateSite; - public bool Xml_RecreateApp; - public bool Xml_ForceRemovePool; - public bool Xml_ForceRemoveSite; - #endregion properties from Xml definition - - #region properties from environment - public Site Site; - public string SitePortList; - public string SiteState; - public ApplicationPool ApplicationPool; - public string PoolState; - public string PoolAccount; - public string AppImpersonateIdentity; - public Application Application; - public string ApplicationState; - public string ApplicationPath; - #endregion properties from environment - public WebApplication() { } - public WebApplication(XElement webappXml) - { - string ATTRIBUTEMANDATORY = nameof(XmlStructure.WebApplication) + " attribute is mandatory! Name: {0}"; - - 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))); } - - Xml_Description = GetValue(nameof(XmlStructure.WebApplication.Attributes.Description), webappXml, Xml_AppName); - Xml_PoolName = GetValue(nameof(XmlStructure.WebApplication.Attributes.AppPool), webappXml, XmlStructure.WebApplication.Attributes.AppPool.Values.DEFAULT); - Xml_SiteName = GetValue(nameof(XmlStructure.WebApplication.Attributes.WebSite), webappXml, XmlStructure.WebApplication.Attributes.WebSite.Values.DEFAULT); - - Xml_AppPhysicalPath = webappXml.Attribute(XName.Get(nameof(XmlStructure.WebApplication.Attributes.InstallDir)))?.Value; - if (string.IsNullOrWhiteSpace(Xml_AppPhysicalPath)) { throw new ApplicationException(string.Format(ATTRIBUTEMANDATORY, nameof(XmlStructure.WebApplication.Attributes.InstallDir))); } - - string PoolPipeLineModeStr = webappXml.Attribute(XName.Get(nameof(XmlStructure.WebApplication.Attributes.AppPoolPipeLineMode)))?.Value; - if (string.IsNullOrWhiteSpace(PoolPipeLineModeStr)) { Xml_PoolPipeLineMode = ManagedPipelineMode.Integrated; } - else - { - 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, ""); - try { Xml_PoolIdentitytype = (ProcessModelIdentityType)Enum.Parse(typeof(ProcessModelIdentityType), Xml_PoolUsername); } - catch { Xml_PoolIdentitytype = ProcessModelIdentityType.SpecificUser; } - if (Xml_PoolIdentitytype != ProcessModelIdentityType.SpecificUser) { Xml_PoolPassword = ""; Xml_PoolUsername = ""; } - - 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); - - Xml_ForceRemovePool = GetValue(nameof(XmlStructure.WebApplication.Attributes.ForceRemovePool), webappXml, false); - Xml_ForceRemoveSite = GetValue(nameof(XmlStructure.WebApplication.Attributes.ForceRemoveSite), webappXml, false); - } - public WebApplication(WebApplication wadef) - { - 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_PoolIdentitytype = wadef.Xml_PoolIdentitytype; - 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; - } - #region XmlStructure - public static class XmlStructure - { - public static class WebApplication - { - public static class Attributes - { - 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 AppPoolUsername { } - public static class AppPoolPassword { } - public static class AppPoolPipeLineMode { } - public static class RecreatePool { } - public static class RecreateSite { } - public static class RecreateApp { } - public static class ForceRemovePool { } - public static class ForceRemoveSite { } - } - } - } - #endregion XmlStructure - } - #endregion WebApplication class - #endregion WebApplicationManager -} diff --git a/Vrh.Log4Pro.MaintenanceConsole/WindowsServiceManager.cs b/Vrh.Log4Pro.MaintenanceConsole/WindowsServiceManager.cs deleted file mode 100644 index 43c86c2..0000000 --- a/Vrh.Log4Pro.MaintenanceConsole/WindowsServiceManager.cs +++ /dev/null @@ -1,952 +0,0 @@ -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.XmlProcessing; -using System.Xml.Linq; -using System.Text.RegularExpressions; - -namespace Vrh.Log4Pro.MaintenanceConsole -{ - #region WindowsServiceManager class - public static class WindowsServiceManager - { - #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 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.SetParameters(sr,config); - menufunctions.Execute(sr.SelectedKeyList); - } - 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) - { - var config = parameter as WindowsServiceManagerXmlProcessor; - while (true) - { - 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; } - var sl = WindowsServiceManagerCore.GetServiceControllers(mask); - 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); - - 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.DisplayItems(1); - var ms = menuservices.Select(); - if (ms.Result == Menu.SelectionResult.None) { continue; } - else if (ms.Result == Menu.SelectionResult.Error) { continue; } - else if (ms.Result == Menu.SelectionResult.Exit) { break; } - else - { - foreach (var p in ms.SelectedParameterList) - { - ColorConsole.Write($"Enter CONFIRM to delete service ", ConsoleColor.Yellow); - ColorConsole.Write($"{p}", ConsoleColor.White,bracket:"''"); - ColorConsole.Write($"!", ConsoleColor.Yellow); - var confirmation = ColorConsole.ReadLine(prefix: " ---> ").ToUpper(); - if (confirmation == "EX") { return o; } - else if (confirmation == "") - { - ColorConsole.WriteLine($"Service '{p}' skipped!", ConsoleColor.Green); - continue; - } - else if (confirmation == "CONFIRM") - { - WindowsServiceManagerCore.Unregister((string)p); - ColorConsole.WriteLine($"Service '{p}' deleted!", ConsoleColor.Green); - } - } - } - } - return 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); - - Menu.Selection sr = menuservices.Select(); - 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) - { - WindowsService ws = p 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); - } - } - return 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); - - Menu.Selection sr = menuservices.Select(); - 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) - { - WindowsService ws = p 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); - } - } - return 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); - - Menu.Selection sr = menuservices.Select(); - 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) - { - WindowsService ws = p 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); - } - } - return 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); - - Menu.Selection sr = menuservices.Select(); - 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) - { - WindowsService ws = p 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); - } - } - return 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); - - Menu.Selection sr = menuservices.Select(); - 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) - { - WindowsService ws = p 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); - } - } - 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); - - Menu.Selection sr = menuservices.Select(); - 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 { } - - string username = null, password = null; - foreach (var p in sr.SelectedParameterList) - { - WindowsService ws = p 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 (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); } - } - } - catch (Exception ex) { ColorConsole.WriteLine(ex.Message, ConsoleColor.Red); } - } - return o; - } - #endregion First level Executors with UI - } - #endregion WindowsServiceManager class - - #region WindowsServiceManagerCore class - public static class WindowsServiceManagerCore - { - public static string GetUserInfo(ManagementObject wmiService) - { - return (string)wmiService[nameof(WindowsService.StartName)]; - } - public static ManagementObject GetServiceObject(string servicename) { return new ManagementObject("Win32_Service.Name='" + servicename + "'"); } - public static ServiceController GetServiceController(string servicename) { return new ServiceController(servicename); } - public static ServiceController[] GetServiceControllers(string servicenamemask) - { - var servicenameregex = @"^" + Regex.Escape(servicenamemask).Replace("%",".*").Replace(@"\?",".")+ @"$"; - - var ServiceControllerList = new List(); - var allservicecontrollers = ServiceController.GetServices(); - foreach (var sc in allservicecontrollers) - { - try - { - if (Regex.Match(sc.ServiceName, servicenameregex).Success) { ServiceControllerList.Add(sc); } - } - catch { ColorConsole.WriteLine($"Error in mask '{servicenamemask}'!",ConsoleColor.Red); return null; } - } - return ServiceControllerList.ToArray(); - } - public static bool SetUserAccount(ManagementObject service, string username, string password) - { - object[] accountParams = new object[11]; - accountParams[6] = username; - accountParams[7] = password; - uint returnCode = (uint)service.InvokeMethod("Change", accountParams); - if (returnCode == 0) { return true; } - else { return false; } - } - - public static bool Kill(string sname) - { - using (var wmiService = WindowsServiceManagerCore.GetServiceObject(sname)) - { - string sstate = (string)wmiService[nameof(WindowsService.State)]; - if (sstate != nameof(ObjectState.Stopped)) - { - int pid = Convert.ToInt32(wmiService[nameof(WindowsService.ProcessId)]); - KillProcessAndChildren(pid); - } - return true; - } - } - - /// - /// Kill a process, and all of its children, grandchildren, etc. - /// - /// Process ID. - private static void KillProcessAndChildren(int pid) - { - // Cannot close 'system idle process'. - if (pid == 0) { return;} - ManagementObjectSearcher searcher = new ManagementObjectSearcher("Select * From Win32_Process Where ParentProcessID=" + pid); - ManagementObjectCollection moc = searcher.Get(); - foreach (ManagementObject mo in moc) { KillProcessAndChildren(Convert.ToInt32(mo["ProcessID"])); } - try { Process proc = Process.GetProcessById(pid); proc.Kill(); } - catch (ArgumentException) { } // Process already exited. - } - public static bool Register(WindowsService ws) - { - // 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 - // sc.exe create NewService binpath= c:\windows\system32\NewServ.exe type= share start= auto depend= +TDI NetBIOS - // - // sc.exe [] create [] - // [type= {own | share | kernel | filesys | rec | interact type= {own | share}}] - // [start= {boot | system | auto | demand | disabled | delayed-auto}] - // [error= {normal | severe | critical | ignore}] - // [binpath= ] - // [group= ] - // [tag= {yes | no}] - // [depend= ] - // [obj= { | }] - // [displayname= ] - // [password= ] - - ProcessStartInfo startInfo = new ProcessStartInfo(); - startInfo.CreateNoWindow = false; - startInfo.UseShellExecute = true; - startInfo.FileName = "sc.exe"; - startInfo.WindowStyle = ProcessWindowStyle.Hidden; - List argumentlist = new List(); - argumentlist.Add($"create"); argumentlist.Add(ws.Name.Quote()); - argumentlist.Add("displayname="); argumentlist.Add(ws.DisplayName.Quote()); - if (ws.Xml_IdentityType == ServiceAccount.User) - { - argumentlist.Add($"obj="); argumentlist.Add(ws.Xml_Username.Quote()); - argumentlist.Add("password="); argumentlist.Add(ws.Xml_Password.Quote()); - } - else - { - argumentlist.Add($"obj="); argumentlist.Add(ws.Xml_IdentityType.ToString().Quote()); - } - var dependonparametert = String.Join("/", ws.Xml_Dependon); - argumentlist.Add($"depend="); argumentlist.Add(dependonparametert.Quote()); - - var startparameter = - ws.Xml_StartMode == ServiceStartMode.Automatic ? "auto" - : ws.Xml_StartMode == ServiceStartMode.Manual ? "demand" - : ws.Xml_StartMode == ServiceStartMode.Disabled ? "disabled" - : ws.Xml_StartMode == ServiceStartMode.Boot ? "boot" - : "system"; - argumentlist.Add($"start="); argumentlist.Add(startparameter.Quote()); - - var registerarguments = ""; - switch (ws.Xml_RegistrationMode) - { - case nameof(WindowsService.XmlStructure.WindowsService.Attributes.RegistrationMode.Values.standard): - { - registerarguments = ws.Xml_Arguments; - } - break; - case nameof(WindowsService.XmlStructure.WindowsService.Attributes.RegistrationMode.Values.topshelf): - { - //"C:\Log4ProIS\VRH.iLogger\VRH.Common.iLogger.Topshelf.exe" -displayname "VRH iLogger for Log4ProIS" -servicename "VRH iLogger for Log4ProIS" -APPCONFIG appconfigILOGGER.config - registerarguments = "-displayname " + ws.Xml_DisplayName.Quote() + " -servicename " + ws.Name.Quote() + " " + ws.Xml_Arguments; - } - break; - case nameof(WindowsService.XmlStructure.WindowsService.Attributes.RegistrationMode.Values.redis): - { - //"C:\Log4ProIS\VRH.iLogger\VRH.Common.iLogger.Topshelf.exe" -displayname "VRH iLogger for Log4ProIS" -servicename "VRH iLogger for Log4ProIS" -APPCONFIG appconfigILOGGER.config - registerarguments = "--service-run " + ws.Xml_Arguments.Quote() + " --service-name " + ws.Name.Quote(); - } - break; - } - var binpathparameter = Path.Combine(ws.Xml_InstallDir, ws.Xml_Exe).Quote() + " " + registerarguments; - argumentlist.Add($"binpath="); argumentlist.Add(binpathparameter.Quote()); - - startInfo.Arguments = String.Join(" ", argumentlist); - - ColorConsole.WriteLine(startInfo.FileName + " " + startInfo.Arguments); - try - { - using (Process exeProcess = Process.Start(startInfo)) { exeProcess.WaitForExit(); } - } - catch - { - // Log error. - } - return true; - } - - public static bool Unregister(WindowsService ws) - { - return Unregister(ws.Name, ws.Xml_StopTimeout); - } - public static bool Unregister(string sname,int stoptimeout=10000) - { - using (var s = GetServiceController(sname)) { Stop(s.ServiceName, stoptimeout); } - - ProcessStartInfo startInfo = new ProcessStartInfo(); - startInfo.CreateNoWindow = false; - startInfo.UseShellExecute = true; - startInfo.FileName = "sc.exe"; - startInfo.WindowStyle = ProcessWindowStyle.Hidden; - - List argumentlist = new List(); - argumentlist.Add($"delete"); argumentlist.Add(sname.Quote()); - startInfo.Arguments = String.Join(" ", argumentlist); - - ColorConsole.WriteLine(startInfo.FileName + " " + startInfo.Arguments); - try - { - // Start the process with the info we specified. - // Call WaitForExit and then the using statement will close. - using (Process exeProcess = Process.Start(startInfo)) { exeProcess.WaitForExit(); } - } - catch - { - // Log error. - } - return true; - // sc.exe delete "ServiceName" - // sc.exe \\myserver delete NewService - // - // sc.exe - // [] - // delete - // [] - } - - public static bool Start(string sname, int starttimeout) - { - using (var service = WindowsServiceManagerCore.GetServiceController(sname)) - { - if (service.ServicesDependedOn.Any()) - { - bool result = true; - foreach (var sn in service.ServicesDependedOn) { result = Start(sn.ServiceName, starttimeout); } - } - var sl = new List() { ServiceControllerStatus.Running, ServiceControllerStatus.Stopped, ServiceControllerStatus.Paused, }; - WaitForStatus(service, sl, starttimeout); - if (service.Status.Equals(ServiceControllerStatus.Stopped)) { service.Start(); } - else if (service.Status.Equals(ServiceControllerStatus.Running)) {; } - else if (service.Status.Equals(ServiceControllerStatus.Paused)) { service.Continue(); } - else { throw new Exception($"Start service {service.ServiceName} failed because of incorrect service status!"); } - service.WaitForStatus(ServiceControllerStatus.Running, new TimeSpan(0, 0, 0, 0, starttimeout)); - if (!service.Status.Equals(ServiceControllerStatus.Running)) { throw new Exception($"Start service {service.ServiceName} failed!"); } - return true; - } - } - public static bool Stop(string sname, int stoptimeout) - { - using (var service = WindowsServiceManagerCore.GetServiceController(sname)) - { - if (service.DependentServices.Any()) - { - bool result = true; - foreach (var s in service.ServicesDependedOn) - { - string sn; - try - { - sn = s.ServiceName; - result = Stop(s.ServiceName, stoptimeout); - } - catch { } - } - } - var sl = new List() { ServiceControllerStatus.Running, ServiceControllerStatus.Stopped, ServiceControllerStatus.Paused, }; - WaitForStatus(service, sl, stoptimeout); - if (service.Status.Equals(ServiceControllerStatus.Running)) { service.Stop(); } - else if (service.Status.Equals(ServiceControllerStatus.Paused)) { service.Stop(); } - else if (service.Status.Equals(ServiceControllerStatus.Stopped)) {; } - else - { - try { Kill(sname); } catch { } - if (!service.Status.Equals(ServiceControllerStatus.Stopped)) - { - throw new Exception($"Stop service {service.ServiceName} failed because of incorrect service status!"); - } - } - service.WaitForStatus(ServiceControllerStatus.Stopped, new TimeSpan(0, 0, 0, 0, stoptimeout)); - if (!service.Status.Equals(ServiceControllerStatus.Stopped)) { throw new Exception($"Stop service {service.ServiceName} failed!"); } - return true; - } - } - private async static void WaitForStatus(ServiceController srvCtl, List sl, int toms) - { - CancellationTokenSource cts = new CancellationTokenSource(); - var ct = cts.Token; - List tasks = new List(); - var ts = new TimeSpan(0, 0, 0, 0, toms); - foreach (var s in sl) { if (srvCtl.Status.Equals(s)) { return; } }; - foreach (var s in sl) { tasks.Add(Task.Run(new Action(() => { try { srvCtl.WaitForStatus(s, ts); } catch { } }), ct)); }; - // When any of the tasks completes, it means the service reached on of the statuses you were tracking - var t = await Task.WhenAny(tasks); - // To cancel the rest of the tasks that are still waiting - cts.Cancel(); - } - - } - #endregion WindowsServiceManagerCore class - #region WindowsServiceManagerXmlProcessor class - public class WindowsServiceManagerXmlProcessor : XmlParser - { - List _winservicelist; - List _winservicelistinstartorder; - List _winservicelistinstoporder; - #region constructor - public WindowsServiceManagerXmlProcessor(string xmlcs, string basefolder, string lcid) : base(xmlcs, basefolder, lcid, null) - { - _winservicelist = new List(); - var wsxmllist = GetAllXElements(nameof(WindowsService.XmlStructure.WindowsService)); - if (wsxmllist != null && wsxmllist.Any()) - { - foreach (var wsxml in wsxmllist) { var ws = new WindowsService(wsxml); if (ws.Valid) { _winservicelist.Add(ws); } } - } - _winservicelistinstartorder = ProduceDefinitionListInStartOrder(); - _winservicelistinstoporder = ProduceDefinitionListInStartOrder(); _winservicelistinstoporder.Reverse(); - } - #endregion constructor - #region GetDefinitionList - public List GetDefinitionList() { return _winservicelist; } - public List GetDefinitionListInStartOrder() { return _winservicelistinstartorder; } - public List GetDefinitionListInStopOrder() { return _winservicelistinstoporder; } - private List ProduceDefinitionListInStartOrder() - { - List listinstartorder = new List(); - bool ready = false;//akkor lesz false, ha már minden - while (!ready) - { - ready = true; - foreach (var s in _winservicelist) - { - var namelistinstartorder = listinstartorder.Select(x => x.Name); - 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 - foreach (var dli in dl) - { - if (string.IsNullOrWhiteSpace(dli)) { continue; } - if (!namelistinstartorder.Contains(dli)) { continue; }//van egy olyan függősége, ami nincs benne a startorder listában - } - listinstartorder.Add(s); break;//minden függősége már benne van a start order listában, így ez is bekerül oda - } - } - return listinstartorder; - } - #endregion GetDefinitionList - } - #endregion WindowsServiceManagerXmlProcessor class - #region WindowsService class - public class WindowsService : XmlLinqBase - { - #region fields - public string Name; - public bool Valid = true; - public string DisplayName; - public string Description; - public string PathName; - public string[] ThisDependsOn; - public string[] ServicesDependOnThis; - public int ProcessId; - public ServiceStartMode StartMode; - public string State; - public string Status; - public string StartName; - public string PriorityClass; - - public string Xml_DisplayName; - public string Xml_Description; - public string Xml_Exe; - public string Xml_InstallDir; - public ServiceStartMode Xml_StartMode; - public string Xml_Priority; - public string Xml_Arguments; - public string[] Xml_Dependon; - public string Xml_RegistrationMode; - public ServiceAccount Xml_IdentityType; - public string Xml_Username; - public string Xml_Password; - public int Xml_StartTimeout; - public int Xml_StopTimeout; - #endregion fields - - #region basic constructor - public WindowsService() { } - #endregion basic constructor - #region xml constructor - public WindowsService(XElement winservicexml) - { - string ATTRIBUTEMANDATORY = nameof(XmlStructure.WindowsService) + " attribute is mandatory! Name: {0}"; - Name = winservicexml.Attribute(XName.Get(nameof(XmlStructure.WindowsService.Attributes.Name)))?.Value; - if (!ValidServiceName(Name)) - { - Valid = false; - return; - //throw new ApplicationException(string.Format(ATTRIBUTEMANDATORY, nameof(XmlStructure.WindowsService.Attributes.Name))); - } - Xml_DisplayName = GetValue(nameof(XmlStructure.WindowsService.Attributes.DisplayName), winservicexml, Name); - Xml_Description = GetValue(nameof(XmlStructure.WindowsService.Attributes.Description), winservicexml, Xml_DisplayName); - Xml_Exe = winservicexml.Attribute(XName.Get(nameof(XmlStructure.WindowsService.Attributes.Exe)))?.Value; - if (string.IsNullOrWhiteSpace(Xml_Exe)) { throw new ApplicationException(string.Format(ATTRIBUTEMANDATORY, nameof(XmlStructure.WindowsService.Attributes.Exe))); } - Xml_InstallDir = winservicexml.Attribute(XName.Get(nameof(XmlStructure.WindowsService.Attributes.InstallDir)))?.Value; - if (string.IsNullOrWhiteSpace(Xml_Exe)) { throw new ApplicationException(string.Format(ATTRIBUTEMANDATORY, nameof(XmlStructure.WindowsService.Attributes.InstallDir))); } - - var startModestr = GetValue(nameof(XmlStructure.WindowsService.Attributes.StartMode), winservicexml, ""); - if (string.IsNullOrWhiteSpace(startModestr)) { startModestr = nameof(ServiceStartMode.Manual); } - Xml_StartMode = GetValue(startModestr, ServiceStartMode.Manual); - - 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(); - 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); } - } - Xml_Dependon = XmlDependon.ToArray(); - - Xml_RegistrationMode = GetValue(nameof(XmlStructure.WindowsService.Attributes.RegistrationMode), winservicexml, XmlStructure.WindowsService.Attributes.RegistrationMode.Values.DEFAULT); - Xml_RegistrationMode = Xml_RegistrationMode.Replace('-', '_'); - try - { - Xml_IdentityType = GetValue(nameof(XmlStructure.WindowsService.Attributes.UserName), winservicexml, ServiceAccount.LocalSystem); - Xml_Username = null; - Xml_Password = null; - } - catch - { - Xml_IdentityType = ServiceAccount.User; - Xml_Username = GetValue(nameof(XmlStructure.WindowsService.Attributes.UserName), winservicexml, XmlStructure.WindowsService.Attributes.UserName.Values.DEFAULT); - Xml_Password = GetValue(nameof(XmlStructure.WindowsService.Attributes.Password), winservicexml, ""); - } - Xml_StartTimeout = GetValue(nameof(XmlStructure.WindowsService.Attributes.StartTimeout), winservicexml, XmlStructure.WindowsService.Attributes.StartTimeout.Values.DEFAULT); - 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] != '@'; } - #endregion xml constructor - #region cloner constructor - public WindowsService(WindowsService ws) - { - Name = ws.Name; - Valid = ws.Valid; - Xml_DisplayName = ws.Xml_DisplayName; - Xml_Description = ws.Xml_Description; - Xml_Exe = ws.Xml_Exe; - Xml_InstallDir = ws.Xml_InstallDir; - Xml_StartMode = ws.Xml_StartMode; - Xml_Priority = ws.Xml_Priority; - Xml_Arguments = ws.Xml_Arguments; - Xml_Dependon = ws.Xml_Dependon; - Xml_RegistrationMode = ws.Xml_RegistrationMode; - Xml_IdentityType = ws.Xml_IdentityType; - Xml_Username = ws.Xml_Username; - Xml_Password = ws.Xml_Password; - Xml_StartTimeout = ws.Xml_StartTimeout; - Xml_StopTimeout = ws.Xml_StopTimeout; - } - #endregion cloner constructor - #region XmlStructure - public static class XmlStructure - { - public static class WindowsService - { - public static class Attributes - { - public static class Name { } - public static class DisplayName { } - public static class Description { } - public static class Exe { } - public static class Priority - { - public static class Values - { - public static string DEFAULT = "20"; - } - } - public static class StartMode { } - public static class InstallDir { } - public static class DependOn { } - public static class UserName - { - public static class Values - { - public static string DEFAULT = nameof(ProcessModelIdentityType.LocalService); - } - } - public static class Password { } - public static class Arguments { } - public static class StartTimeout - { - public static class Values - { - public static int DEFAULT = 10000; - } - } - public static class StopTimeout - { - public static class Values - { - public static int DEFAULT = 10000; - } - } - public static class RegistrationMode - { - public static class Values - { - public static string DEFAULT = nameof(standard); - public class standard { }; - public class redis { }; - public class topshelf { }; - } - } - } - } - } - #endregion XmlStructure - } - #endregion WindowsService class - -} diff --git a/Vrh.Log4Pro.MaintenanceConsole/packages.config b/Vrh.Log4Pro.MaintenanceConsole/packages.config index 9b561d7..3432258 100644 --- a/Vrh.Log4Pro.MaintenanceConsole/packages.config +++ b/Vrh.Log4Pro.MaintenanceConsole/packages.config @@ -1,5 +1,6 @@  + @@ -54,5 +55,6 @@ + \ No newline at end of file -- libgit2 0.21.2