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