diff --git a/Vrh.Log4Pro.MaintenanceConsole/ConsoleFunction - Tools - Http.cs b/Vrh.Log4Pro.MaintenanceConsole/ConsoleFunction - Tools - Http.cs deleted file mode 100644 index ab90753..0000000 --- a/Vrh.Log4Pro.MaintenanceConsole/ConsoleFunction - Tools - Http.cs +++ /dev/null @@ -1,94 +0,0 @@ -using System; -using System.IO; -using System.IO.Compression; -using System.Collections.Generic; -using System.Linq; -using System.Security.Principal; -using System.Text; -using System.Text.RegularExpressions; -using System.Threading.Tasks; -using System.Threading; - -using Microsoft.Web.Administration; -using System.Management; -using System.Diagnostics; - -using Vrh.XmlProcessing; -using System.Xml.Linq; -using Vrh.Log4Pro.MaintenanceConsole.ColorConsoleNS; -using VRH.Common; -using Microsoft.Win32; -using System.Reflection; -using Vrh.Log4Pro.MaintenanceConsole.CommandLineParserNS; -using System.Net.Http; -using System.Net.Http.Headers; -using System.Collections.Generic; -using Newtonsoft.Json; - -namespace Vrh.Log4Pro.MaintenanceConsole.ToolsNS -{ - public static class HttpTools - { - public enum RequestType { GET,POST,} - public static ReturnInfoJSON GetReturninfoJSON(string url, int timeoutinseconds,RequestType mode = RequestType.GET, List dictparameterlist=null) - { - string returninfojsonstring = ""; - timeoutinseconds = timeoutinseconds <= 0 ? 100: timeoutinseconds; - try - { - return mode == RequestType.GET? _GetReturninfoJSON(url, timeoutinseconds,out returninfojsonstring) : _PostReturninfoJSON(url, timeoutinseconds, out returninfojsonstring, dictparameterlist); - } - catch (Exception ex) { return new ReturnInfoJSON() { ReturnValue = -1, ReturnMessage = ex.Message + "\n" + returninfojsonstring, }; } - } - - private static ReturnInfoJSON _GetReturninfoJSON(string url, int timeoutinseconds, out string returninfojsonstring) - { - Stream returninfojsonstream; - using (var httpclient = new HttpClient()) - { - httpclient.Timeout = new TimeSpan(0, 0, timeoutinseconds); - returninfojsonstream = Task.Run(async () => await httpclient.GetStreamAsync(url)).GetAwaiter().GetResult(); - } - - returninfojsonstring = GetStreamAsString(returninfojsonstream); - ReturnInfoJSON returninfojson = (ReturnInfoJSON)JsonConvert.DeserializeObject(returninfojsonstring,typeof(ReturnInfoJSON)); - //ReturnInfoJSON returninfojson = Task.Run(async () => await JsonSerializer.DeserializeAsync(returninfojsonstream)).GetAwaiter().GetResult(); - return returninfojson; - } - private static ReturnInfoJSON _PostReturninfoJSON(string url, int timeoutinseconds, out string returninfojsonstring, List dictparameterlist = null) - { - var jsonstring = JsonConvert.SerializeObject(dictparameterlist.Where(p => p.PassTo == Vrh.XmlProcessing.UrlElement.ParameterTypes.dict)); - HttpContent requestcontent = new StringContent(jsonstring); - - HttpResponseMessage returninfojsonhttpresponsemessage; - using (var httpclient = new HttpClient()) - { - httpclient.Timeout = new TimeSpan(0, 0, timeoutinseconds); - returninfojsonhttpresponsemessage = Task.Run(async () => await httpclient.PostAsync(url, requestcontent)).GetAwaiter().GetResult(); - } - - var returninfojsonstream = Task.Run(async () => await returninfojsonhttpresponsemessage.Content.ReadAsStreamAsync()).GetAwaiter().GetResult(); - returninfojsonstring = GetStreamAsString(returninfojsonstream); - ReturnInfoJSON returninfojson = (ReturnInfoJSON)JsonConvert.DeserializeObject(returninfojsonstring, typeof(ReturnInfoJSON)); - //var returninfojson = Task.Run(async () => await JsonSerializer.DeserializeAsync(returninfojsonstream)).GetAwaiter().GetResult(); - return returninfojson; - } - private static string GetStreamAsString(Stream stream) - { - - StreamReader reader = new StreamReader(stream); - return reader.ReadToEnd(); - - byte[] bytes = new byte[stream.Length]; - stream.Position = 0; - stream.Read(bytes, 0, (int)stream.Length); - return Encoding.ASCII.GetString(bytes); // this is your string - } - public class ReturnInfoJSON - { - public int ReturnValue { get; set; } - - public string ReturnMessage { get; set; } - } - } -} \ No newline at end of file diff --git a/Vrh.Log4Pro.MaintenanceConsole/ConsoleFunction - Tools - Membership.cs b/Vrh.Log4Pro.MaintenanceConsole/ConsoleFunction - Tools - Membership.cs deleted file mode 100644 index 099165e..0000000 --- a/Vrh.Log4Pro.MaintenanceConsole/ConsoleFunction - Tools - Membership.cs +++ /dev/null @@ -1,1218 +0,0 @@ -using System; -using System.Data.Linq.SqlClient; -using System.IO; -using System.IO.Compression; -using System.Collections.Generic; -using System.Linq; -using System.Security.Principal; -using System.Text; -using System.Text.RegularExpressions; -using System.Threading.Tasks; -using System.Threading; - -using Microsoft.Web.Administration; -using System.Management; -using System.Diagnostics; - -using Vrh.XmlProcessing; -using System.Xml.Linq; -using Vrh.Log4Pro.MaintenanceConsole.ColorConsoleNS; -using VRH.Common; - -using System.Data.Entity; -using System.ComponentModel.DataAnnotations; -using System.ComponentModel.DataAnnotations.Schema; - -namespace Vrh.Log4Pro.MaintenanceConsole.ToolsNS -{ - using System.Web.Security; - - public static class MembershipTools - { - public static void SetConnectionString(string sqlcs) - { - MembershipDBContext = new DAL.MembershipContext(sqlcs); - m_MembershipProvider = System.Web.Security.Membership.Provider; - m_roleProvider = System.Web.Security.Roles.Provider; - } - private static MembershipProvider m_MembershipProvider; - private static RoleProvider m_roleProvider; - private static DAL.MembershipContext MembershipDBContext; - - #region Constants - public class Constants - { - public const string SCHEMA_NAME = "UAdmin"; - - public const string ROLENAME_ADMINISTRATOR = "Administrator"; - public const string ROLENAME_ADMIN = "Admin"; - public const string USERNAME_ADMINISTRATOR = "Administrator"; - public const string PASSWORD_ADMINISTRATOR = "Admin123"; - public const string USERNAME_ADMIN = "Admin"; - public const string PASSWORD_ADMIN = "Admin123"; - public static readonly string[] SYSTEMUSERNAMELIST = new string[] { ROLENAME_ADMIN, USERNAME_ADMINISTRATOR }; - public static readonly DateTime NEVERONLINE = new DateTime(2000, 1, 1); - } - #endregion Constants - - #region Users - public static class Users - { - #region IsSecondaryUser - /// - /// true-val tér vissza, ha léteznek ehhez az elsődleges userhez másodlagos user-ek - /// - /// - /// - public static bool IsSecondaryUserOfUser(string primaryusername) - { - var sUserList = MembershipDBContext.SecondaryUsers.Where(x => x.User != null && x.User.UserName == primaryusername); - return (sUserList != null && sUserList.Any()); - } - #endregion IsSecondaryUser - #region DeleteSecondaryUsersOfUser methods - /// - /// Másodlagos felhasználó törlése a funkció nevének és a felhasználó nevének megadásával. - /// - /// Elsődleges felhasználó neve. - /// Ha nem található a törlendő másodlagos felhasználó. - public static void DeleteSecondaryUsersOfUser(string primaryusername) - { - var sUserList = MembershipDBContext.SecondaryUsers.Where(x => x.User!=null && x.User.UserName == primaryusername); - if (sUserList == null || !sUserList.Any()) - { - throw new ApplicationException($"Secondary users for primary user '{primaryusername}' not found!"); - } - else - { - foreach (var suser in sUserList) - { - var sllist = MembershipDBContext.SecondaryLogins.Where(sl => sl.SecondaryUserId == suser.Id); - if (sllist != null && sllist.Any()) { foreach (var sl in sllist) { MembershipDBContext.SecondaryLogins.Remove(sl); } } - MembershipDBContext.SecondaryUsers.Remove(suser); - } - MembershipDBContext.SaveChanges(); - } - } - #endregion DeleteSecondaryUsersOfUser methods - #region Create - /// - /// Felhasználó létrehozása a paraméterlistában felsorolt paraméterek megadásával. - /// - /// Felhasználó neve. - /// Felhasználó jelszava. - /// hozzárendeli a usert az Admin és az Administrator szerepekhez - /// hozzárendeli a usert minden létező szerephez és szerepkörhöz - /// a felhasználóhoz hozzárendelendő role nevek listája; ha a lista tartalmazza a * tagot, akkor minden role. - /// a felhasználóhoz hozzárendelendő rolegroup nevek listája; ha a lista tartalmazza a * tagot, akkor minden rolegroup. - /// A létrehozott felhasználó MembershipUser objektuma. - public static MembershipUser Create(string username, string password, bool administrator=false,bool superuser=false, string[] rolenames=null,string[]rolegroupnames=null) - { - #region ellenőrzések - if (String.IsNullOrWhiteSpace(username)) { throw new MembershipCreateUserException("Username is required!"); } - - string wrPrefix = "WebReq_"; - string adPrefix = "AD_"; - if (username.StartsWith(wrPrefix, StringComparison.OrdinalIgnoreCase) || username.StartsWith(adPrefix, StringComparison.OrdinalIgnoreCase)) - { - throw new MembershipCreateUserException($"Username format is incorrect, it can not start with {wrPrefix}, {adPrefix}"); - } - #endregion ellenőrzések - - CreateAdminRolesAndUsers(); - MembershipUser user = Membership.GetUser(username); - if (user == null) - { - user = Membership.CreateUser(username, password); - user.LastActivityDate = Constants.NEVERONLINE; - user.LastLoginDate = Constants.NEVERONLINE; - user.Comment = ""; - user.Email = ""; - user.IsApproved = true; - Membership.UpdateUser(user); - //user.ChangePasswordQuestionAndAnswer(password, "", ""); - } - if (superuser) - { - string rgnamelist = string.Join(",", MembershipDBContext.RoleGroups.Select(rg => rg.Name).ToArray()); - if (!string.IsNullOrWhiteSpace(rgnamelist)) { Assign.RoleGroupsToUsers(rgnamelist, username); } - foreach (var rn in System.Web.Security.Roles.GetAllRoles()) - { - if (!Users.IsInRole(username, rn)) { System.Web.Security.Roles.AddUserToRole(username, rn); } - } - } - else if (administrator) - { - if (!System.Web.Security.Roles.IsUserInRole(username, Constants.ROLENAME_ADMINISTRATOR)) { System.Web.Security.Roles.AddUserToRole(username, Constants.ROLENAME_ADMINISTRATOR); } - if (!System.Web.Security.Roles.IsUserInRole(username, Constants.ROLENAME_ADMIN)) { System.Web.Security.Roles.AddUserToRole(username, Constants.ROLENAME_ADMIN); } - } - - string[] selectedrolenames; - if (rolenames != null && rolenames.Any()) - { - selectedrolenames = rolenames.Contains("*") ? System.Web.Security.Roles.GetAllRoles() : rolenames; - if (selectedrolenames != null && selectedrolenames.Any()) - { - foreach (var rname in selectedrolenames) - { - if (string.IsNullOrWhiteSpace(rname)) { continue; } - if (!System.Web.Security.Roles.IsUserInRole(username, rname)) { System.Web.Security.Roles.AddUserToRole(username, rname); } - } - } - } - string[] selectedrolegroupnames; - if (rolegroupnames != null && rolegroupnames.Any()) - { - selectedrolegroupnames = rolegroupnames.Contains("*") ? RoleGroups.GetAllNames().ToArray() : rolegroupnames; - if (selectedrolegroupnames != null && selectedrolegroupnames.Any()) - { - foreach (var rgname in selectedrolegroupnames) - { - if (string.IsNullOrWhiteSpace(rgname)) { continue; } - if (!RoleGroups.IsUserInRoleGroup(username, rgname)) { Assign.RoleGroupsToUsers(rgname, username); } - } - } - } - return user; - } - #endregion Create - #region CreateAdminRolesAndUsers - public static void CreateAdminRolesAndUsers() - { - MembershipUser user; - if (!System.Web.Security.Roles.RoleExists(Constants.ROLENAME_ADMINISTRATOR)) { System.Web.Security.Roles.CreateRole(Constants.ROLENAME_ADMINISTRATOR); } - if (!System.Web.Security.Roles.RoleExists(Constants.ROLENAME_ADMIN)) { System.Web.Security.Roles.CreateRole(Constants.ROLENAME_ADMIN); } - - user = Membership.GetUser(Constants.USERNAME_ADMIN); - if (user == null) - { - user = Membership.CreateUser(Constants.USERNAME_ADMIN, Constants.PASSWORD_ADMIN); - } - if (!System.Web.Security.Roles.IsUserInRole(Constants.USERNAME_ADMIN, Constants.ROLENAME_ADMINISTRATOR)) { System.Web.Security.Roles.AddUserToRole(Constants.USERNAME_ADMIN, Constants.ROLENAME_ADMINISTRATOR); } - if (!System.Web.Security.Roles.IsUserInRole(Constants.USERNAME_ADMIN, Constants.ROLENAME_ADMIN)) { System.Web.Security.Roles.AddUserToRole(Constants.USERNAME_ADMIN, Constants.ROLENAME_ADMIN); } - - user = Membership.GetUser(Constants.USERNAME_ADMINISTRATOR); - if (user == null) - { - user = Membership.CreateUser(Constants.USERNAME_ADMINISTRATOR, Constants.PASSWORD_ADMINISTRATOR); - } - if (!System.Web.Security.Roles.IsUserInRole(Constants.USERNAME_ADMINISTRATOR, Constants.ROLENAME_ADMINISTRATOR)) { System.Web.Security.Roles.AddUserToRole(Constants.USERNAME_ADMINISTRATOR, Constants.ROLENAME_ADMINISTRATOR); } - if (!System.Web.Security.Roles.IsUserInRole(Constants.USERNAME_ADMINISTRATOR, Constants.ROLENAME_ADMIN)) { System.Web.Security.Roles.AddUserToRole(Constants.USERNAME_ADMINISTRATOR, Constants.ROLENAME_ADMIN); } - } - #endregion CreateAdminRolesAndUsers - #region IsInRole public method - /// - /// Annak jelzése, hogy a -ben megadott nevű felhasználó - /// rendelkezik-e a -ben megadott nevű szereppel. - /// - /// A felhasználó neve. - /// A szerep neve. - /// Igaz, ha a felhasználó rendelekezik a megadott szereppel. - public static bool IsInRole(string userName, string roleName) - { - return m_roleProvider.IsUserInRole(userName, roleName); - } - #endregion IsInRole public method - #region Get - public static MembershipUser Get(string userName) - { - return m_MembershipProvider.GetUser(userName, false); - } - #endregion Get - #region GetNameList - /// - /// A maszknak megfelelő felhasználónevek listáját adja vissza. - /// - /// SQL LIKE-ba illeszhető maszk - /// - public static List GetNameList(string usernamemask) - { - if (usernamemask == null) { usernamemask = "%"; } - usernamemask = usernamemask.Replace("%", ".*").Replace("?", "."); - return MembershipDBContext.Users - .Select(u=>u.UserName) - .ToList() - .Where(un => Regex.Match(un, usernamemask).Success) - .ToList(); - } - #endregion GetNameList - #region GetList - /// - /// Az összes felhasználót tartalmazó listát ad vissza. - /// - /// Ha hamis, akkor az ideiglenes felhasználók nincsenek a listában. - /// - public static List GetList(string usernamemask,bool includetempuser = false) - { - var result = new List(); - if (!includetempuser) - { // az ideiglenes felhasználók nélkül - var qry = MembershipDBContext.Users // primary - .Where(u => SqlMethods.Like(u.UserName, usernamemask)) - .GroupJoin(MembershipDBContext.UserSupplements, //foreign - pk => pk.UserId, // primary key - fk => fk.UserId, // foreign key - (pka, fkb) => new { u = pka, us = fkb }) - .SelectMany(sm => sm.us.DefaultIfEmpty(), (sm, d) => new { User = sm.u, UserSupplement = d }) - .Where(x => x.UserSupplement == null || x.UserSupplement.IsTemporary == false) - .Select(s => s.User); - if (qry != null && qry.Any()) - { - foreach (var dbuser in qry) - { - MembershipUser user = m_MembershipProvider.GetUser(dbuser.UserId, false); - if (user != null) - { - result.Add(user); - } - } - } - } - else - { // itt mehet mind, nem kell szűrögetni - foreach (MembershipUser user in m_MembershipProvider.GetAllUsers(0, int.MaxValue, out int totalRecords)) - { - result.Add(user); - } - } - return result; - } - #endregion GetList - #region CheckPassword - public static bool CheckPassword(string username, string userpassword) - { - var user = Membership.GetUser(username); - return user.GetPassword()==userpassword; - } - #endregion CheckPassword - #region Remove - /// - /// Törli a megadott nevű user-t és minden kapcsolatát - /// - /// - /// - /// - /// - public static void Remove(string username) - { - if (string.IsNullOrWhiteSpace(username)) { throw new Exception("Username can not be null or empty or whitespace!"); } - if (Get(username) == null) { throw new ApplicationException($"User {username} does not exist!"); } - if (Constants.SYSTEMUSERNAMELIST.Contains(username)) { throw new MembershipCreateUserException($"System user {username} are not allowed to delete!"); } - Assign.RemoveOfUser(username); - if (Users.IsSecondaryUserOfUser(username)) { Users.DeleteSecondaryUsersOfUser(username); } - m_MembershipProvider.DeleteUser(username, true); - } - #endregion Remove - } - #endregion Users - #region RoleGroups - public static class RoleGroups - { - #region Get methods - /// - /// Szerepkör lekérése az egyedi azonosítója alapján. - /// - /// A keresett funkció azonosítója. - /// A kért szerepkör, egyébként null. - public static DAL.RoleGroup Get(int id) - { - return MembershipDBContext.RoleGroups.FirstOrDefault(x => x.Id == id); - } - /// - /// Szerepkör lekérése az egyedi neve alapján. - /// - /// A keresett szerepkör egyedi neve. - /// A kért szerepkör, egyébként null. - public static DAL.RoleGroup Get(string name) - { - return MembershipDBContext.RoleGroups.FirstOrDefault(x => x.Name == name); - } - /// - /// Szerepkör lekérése az egyedi neve alapján. - /// - /// A keresett szerepkör egyedi neve. - /// A kért szerepkör, egyébként null. - public static List GetAllNames() - { - return MembershipDBContext.RoleGroups.Select(rg=>rg.Name).ToList(); - } - public static bool IsUserInRoleGroup(string username,string rolegroupname) - { - return MembershipDBContext.RoleGroupUsers.Select(rguass => rguass.User.UserName == username && rguass.RoleGroup.Name == rolegroupname).ToList().Any(); - } - #endregion Get methods - - #region Create method - /// - /// Szerepkör létrehozása. - /// - /// A létrehozandó szerepkör. - /// - /// Ha üres vagy null a szerepkör neve. - /// Ha már létezik a megadott név. - /// - public static void Create(DAL.RoleGroup roleGroup) - { - if (String.IsNullOrWhiteSpace(roleGroup.Name)) { throw new ApplicationException("RoleGroup név megadása kötelező!"); } - - if (MembershipDBContext.RoleGroups.Any(x => x.Name == roleGroup.Name)) { throw new ApplicationException($"RoleGroup {roleGroup.Name} already exist!"); } - - MembershipDBContext.RoleGroups.Add(roleGroup); - MembershipDBContext.SaveChanges(); - } - /// - /// Szerepkör létrehozása. - /// - /// A létrehozandó szerepkör. - /// - /// Ha üres vagy null a szerepkör neve. - /// Ha már létezik a megadott név. - /// - public static void Create(string name) - { - if (String.IsNullOrWhiteSpace(name)) { throw new ApplicationException("RoleGroup név megadása kötelező!"); } - if (MembershipDBContext.RoleGroups.Any(x => x.Name == name)) { throw new ApplicationException($"RoleGroup {name} already exist!"); } - MembershipDBContext.RoleGroups.Add(new DAL.RoleGroup { Name = name, }); - MembershipDBContext.SaveChanges(); - } - #endregion Create method - - #region Remove methods - /// - /// Szerepkör törlése az egyedi azonosítója megadásával. - /// A szerepkörhöz tartozó összerendelések is megszűnnek! - /// - /// Törlendő szerep egyedi azonosítója. - /// Ha nem található a törlendő szerepkör. - public static void Remove(int id) - { - var row = MembershipDBContext.RoleGroups.Find(id); - if (row == null) { throw new ApplicationException("RoleGroup does not exist!!"); } - else { MembershipDBContext.RoleGroups.Remove(row); MembershipDBContext.SaveChanges(); } - } - /// - /// Szerepkör törlése az egyedi név megadásával. - /// A szerepkörhöz tartozó összerendelések is megszűnnek! - /// - /// Törlendő szerepkör egyedi neve. - /// Ha nem található a törlendő szerepkör. - public static void Remove(string name) - { - var row = MembershipDBContext.RoleGroups.FirstOrDefault(x => x.Name == name); - if (row == null) { Remove(-1); } - else { Remove(row.Id); } - } - #endregion Remove methods - } - #endregion RoleGroups - #region Roles - public static class Roles - { - #region Get methods - /// - /// Szerep lekérése az egyedi azonosítója alapján. - /// - /// A keresett funkció azonosítója. - /// A kért szerepkör, egyébként null. - public static DAL.Role Get(Guid id) - { - return MembershipDBContext.Roles.FirstOrDefault(x => x.RoleId == id); - } - /// - /// Szerep lekérése az egyedi neve alapján. - /// - /// A keresett szerep egyedi neve. - /// A kért szerep, egyébként null. - public static DAL.Role Get(string name) - { - return MembershipDBContext.Roles.FirstOrDefault(x => x.RoleName== name); - } - /// - /// Szerepek neveinek lekérése. - /// - /// A szerepek neveinek listája. - public static List GetAllNames() - { - return MembershipDBContext.Roles.Select(r => r.RoleName).ToList(); - } - /// - /// A megadott nevű szerep benne van-e a megadott szerepkörben tartozik-e. - /// - /// - /// - /// true, ha igen - public static bool IsRoleInRoleGroup(string rolename, string rolegroupname) - { - return MembershipDBContext.RoleGroupRoles.Select(rtorg => rtorg.Role.RoleName == rolename && rtorg.RoleGroup.Name == rolegroupname).ToList().Any(); - } - #endregion Get methods - - #region Create method - /// - /// Szerep létrehozása. - /// - /// A létrehozandó szerep neve. - /// - /// Ha üres vagy null a szerep neve. - /// Ha már létezik a megadott név. - /// - public static void Create(string rolename, string appname=null) - { - if (String.IsNullOrWhiteSpace(rolename)) { throw new ApplicationException("Role név megadása kötelező!"); } - if (appname==null) { appname = MembershipDBContext.Applications.FirstOrDefault(a => a.ApplicationName == "/")?.ApplicationName; } - if (appname == null) { appname = MembershipDBContext.Applications.First()?.ApplicationName; } - if (appname==null) { throw new ApplicationException("Application nem létezik!"); } - var app = MembershipDBContext.Applications.FirstOrDefault(a => a.ApplicationName == appname); - - if (MembershipDBContext.Roles.Any(x => x.RoleName == rolename)) { throw new ApplicationException($"Role {rolename} already exist!"); } - - System.Web.Security.Roles.CreateRole(rolename); - var rolecreated = MembershipDBContext.Roles.First(x => x.RoleName == rolename); - if (rolecreated==null) { throw new ApplicationException($"Creating role failed. Role name:{rolename}!"); } - //MembershipDBContext.Roles.Add(new DAL.Role() { RoleName = rolename, ApplicationId=app.ApplicationId,Description=null, }); - rolecreated.ApplicationId = app.ApplicationId; - MembershipDBContext.SaveChanges(); - } - #endregion Create method - - #region Remove methods - /// - /// Szerep törlése az egyedi azonosítója megadásával. - /// A szerephez tartozó összerendelések is megszűnnek! - /// - /// Törlendő szerep egyedi azonosítója. - /// Ha nem található a törlendő szerep. - public static void Remove(int id) - { - var row = MembershipDBContext.Roles.Find(id); - if (row == null) { throw new ApplicationException("Role does not exist!!"); } - else { MembershipDBContext.Roles.Remove(row); MembershipDBContext.SaveChanges(); } - } - /// - /// Szerep törlése az egyedi neve megadásával. - /// A szerephez tartozó összerendelések is megszűnnek! - /// - /// Törlendő szerep egyedi neve. - /// Ha nem található a törlendő szerep. - public static void Remove(string name) - { - var row = MembershipDBContext.Roles.FirstOrDefault(x => x.RoleName == name); - if (row == null) { throw new ApplicationException("Role does not exist!!"); } - else - { - System.Web.Security.Roles.DeleteRole(name); - MembershipDBContext.Roles.Remove(row); - MembershipDBContext.SaveChanges(); - } - } - #endregion Remove methods - } - #endregion Roles - #region Assign - public static class Assign - { - #region RemoveOfUser - public static void RemoveOfUser(string username) - { - if (string.IsNullOrWhiteSpace(username)) { throw new Exception("Username can not be empty!"); } - var user = MembershipDBContext.Users.FirstOrDefault(u => u.UserName == username); - if (user==null) { throw new Exception($"User '{username}' does not exist!"); } - var rguasslist = MembershipDBContext.RoleGroupUsers.Where(rg => rg.UserId == user.UserId); - if (rguasslist == null || !rguasslist.Any()) { return; } - foreach (var rguass in rguasslist) { MembershipDBContext.RoleGroupUsers.Remove(rguass); } - } - #endregion RemoveOfUser - #region RolesToUser public method - /// - /// Role-RoleGroup-User összerendelések - /// - /// az összerendelés módját határozza meg - /// ezeket kell összerendelni... - /// ...ezekkel - /// - public static VRH.Common.ReturnInfoJSON RolesToUser(string rolenamecommalist, string usernamecommalist) - { - ReturnInfoJSON result = new ReturnInfoJSON() { ReturnMessage = "Assignment was successful!" }; - try - { - if (m_roleProvider != null) { throw new Exception("RoleService is not enabled!"); } - var rolenamelist = rolenamecommalist != null ? new List(rolenamecommalist.Split(',')) : new List(); - var usernamelist = usernamecommalist != null ? new List(usernamecommalist.Split(',')) : new List(); - foreach (var rolename in rolenamelist) - { - CheckRoleExists(rolename); - foreach (var username in usernamelist) - { - CheckUsersExists(username); - if (!Users.IsInRole(username, rolename)) { System.Web.Security.Roles.AddUserToRole(username, rolename); } - } - } - } - catch (Exception ex) - { - result.ReturnValue = -1; - result.ReturnMessage = ex.Message; - } - return result; - } - #endregion RolesToUser public method - #region RolesToRoleGroups public method - public static VRH.Common.ReturnInfoJSON RolesToRoleGroups(string rolenamecommalist, string rolegroupnamecommalist) - { - DAL.RoleGroup urg; - ReturnInfoJSON result = new ReturnInfoJSON() { ReturnMessage = "Assignment was successful!" }; - try - { - if (m_roleProvider != null) { throw new Exception("RoleService is not enabled!"); } - var rolenamelist = rolenamecommalist != null ? new List(rolenamecommalist.Split(',')) : new List(); - var rolegroupnamelist = rolegroupnamecommalist != null ? new List(rolegroupnamecommalist.Split(',')) : new List(); - foreach (var rolename in rolenamelist) - { - CheckRoleExists(rolename); - foreach (var rolegroupname in rolegroupnamelist) - { - CheckRoleGroupExists(rolegroupname); - DAL.Role role = MembershipDBContext.Roles.FirstOrDefault(x => x.RoleName == rolename); - urg = MembershipDBContext.RoleGroups.FirstOrDefault(x => x.Name == rolegroupname); - if (role != null && urg != null) - { - if (!urg.Roles.Any(x => x.Role.RoleName == rolename)) - { - urg.Roles.Add(new DAL.RoleGroupRole { Role = role }); - MembershipDBContext.SaveChanges(); - UpdateUsersForUserRoleGroup(urg.Id); - } - } - } - } - } - catch (Exception ex) - { - result.ReturnValue = -1; - result.ReturnMessage = ex.Message; - } - return result; - } - #endregion RolesToRoleGroups public method - #region RoleGroupsToUsers public method - public static VRH.Common.ReturnInfoJSON RoleGroupsToUsers(string rolegroupnamecommalist, string usernamecommalist) - { - DAL.RoleGroup urg; - ReturnInfoJSON result = new ReturnInfoJSON() { ReturnMessage = "Assignment was successful!" }; - try - { - if (m_roleProvider != null) { throw new Exception("RoleService is not enabled!"); } - var rolegroupnamelist = rolegroupnamecommalist != null ? new List(rolegroupnamecommalist.Split(',')) : new List(); - var usernamelist = usernamecommalist != null ? new List(usernamecommalist.Split(',')) : new List(); - foreach (var rolegroupname in rolegroupnamelist) - { - CheckRoleGroupExists(rolegroupname); - foreach (var username in usernamelist) - { - CheckUsersExists(username); - Guid userId = Guid.Empty; - if (Guid.TryParse(Users.Get(username).ProviderUserKey.ToString(), out userId)) - { - urg = MembershipDBContext.RoleGroups.FirstOrDefault(x => x.Name == rolegroupname); - DAL.User u = MembershipDBContext.Users.FirstOrDefault(x => x.UserId == userId); - if (u != null && urg != null) - { - if (!urg.Users.Any(x => x.UserId == userId)) - { - urg.Users.Add(new DAL.RoleGroupUser { User = u }); - MembershipDBContext.SaveChanges(); - UpdateRolesForUser(u.UserId); - } - } - } - } - } - } - catch (Exception ex) - { - result.ReturnValue = -1; - result.ReturnMessage = ex.Message; - } - return result; - } - #endregion RoleGroupsToUsers public method - #region private CheckRoleGroupExists,CheckRoleExists,CheckUsersExists - /// - /// Ellenőrzi, van-e ilyen role group - /// - /// ellenőrizendő role group - private static void CheckRoleGroupExists(string roleGroup) - { - if (!MembershipDBContext.RoleGroups.Any(x => x.Name == roleGroup)) { throw new Exception($"RoleGroup {roleGroup} does not exist!"); } - } - /// - /// Ellenőrzi, van-e ilyen role - /// - /// az ellenőrizendő role - private static void CheckRoleExists(string role) - { - if (!System.Web.Security.Roles.GetAllRoles().ToList().ConvertAll(r => r.ToUpper()).Contains(role.ToUpper())) - { - throw new Exception($"Role {role} does not exist!"); - } - } - /// - /// Ellenőrzi van-e ilyen usernevű user - /// - /// Ellenőrizendő user userneve - private static void CheckUsersExists(string userName) - { - bool exists = false; - foreach (MembershipUser user in System.Web.Security.Membership.GetAllUsers()) - { - if (user.UserName.ToUpper() == userName.ToUpper()) { exists = true; break; } - } - if (!exists) { throw new Exception($"User {userName} does not exist!"); } - } - #endregion private CheckRoleGroupExists,CheckRoleExists,CheckUsersExists - - #region private UpdateRolesForUser - /// - /// Frissíti a megadott felhasználó szerepeit a felhasználó szerepkörei alapján - /// - /// felhasználó UserID-ja - private static void UpdateRolesForUser(Guid userId) - { - MembershipUser user = System.Web.Security.Membership.GetUser(userId, false); - if (user != null) - { - // eltávolítjuk az összes szerepkörét a felhasználónak, majd a felhasználóhoz tartozó UserRoleGroup-okban lévő Roles-okat adjuk hozzá a felhasználóhoz - if (System.Web.Security.Roles.GetRolesForUser(user.UserName).Any()) - { - System.Web.Security.Roles.RemoveUserFromRoles(user.UserName, System.Web.Security.Roles.GetRolesForUser(user.UserName)); - } - foreach (DAL.RoleGroup urg in MembershipDBContext.RoleGroups.Where(x => x.Users.Any(y => y.UserId == userId))) - { - foreach (string roleName in urg.Roles.Select(x => x.Role.RoleName)) - { - if (!System.Web.Security.Roles.IsUserInRole(user.UserName, roleName)) - { - System.Web.Security.Roles.AddUserToRole(user.UserName, roleName); - } - } - } - } - } - #endregion private UpdateRolesForUser - #region private UpdateUsersForUserRoleGroup - /// - /// Frissíti a megadott szerepkörhöz tartozó felhasználók szerepeit a szerepkörök alapján - /// - /// UserRoleGroup Id-ja - private static void UpdateUsersForUserRoleGroup(int userRoleGroupId) - { - DAL.RoleGroup urg = MembershipDBContext.RoleGroups.SingleOrDefault(x => x.Id == userRoleGroupId); - if (urg != null) - { - foreach (Guid userId in urg.Users.Select(x => x.UserId)) - { - UpdateRolesForUser(userId); - } - } - } - #endregion private UpdateUsersForUserRoleGroup - } - #endregion Assign - #region DAL - public static class DAL - { - #region tables - #region table-User - /// - /// DefaultMembershipProvider által létrehozott User tábla. - /// Ha változik az aktuális verzió, és emiatt a tábla szerkezete, akkor ezt módosítani kell. - /// - [Table("Users", Schema = "dbo")] - public partial class User - { - /// - /// Felhasználó egyedi azonosítója. - /// - [Key, DatabaseGenerated(DatabaseGeneratedOption.None)] - public Guid UserId { get; set; } - - /// - /// Melyik alkalmazás felhasználója. - /// - public Guid ApplicationId { get; set; } - - /// - /// Felhasználó neve. - /// - [Required, MaxLength(50)] - public string UserName { get; set; } - - /// - /// Felhasználó névtelenül bejelentjezhet-e. - /// - public bool IsAnonymous { get; set; } - - /// - /// Felhasználó utolsó aktivitésénak időpontja. - /// - public DateTime LastActivityDate { get; set; } - - #region Virtual Collections - - /// - /// A felhasználó szerepkörei. - /// - public virtual ICollection UserRoleGroupUsers { get; set; } - - #endregion Virtual Collections - - } - #endregion table-User - #region table-RoleGroupUser - /// - /// Szerepkörök és felhasználók összerendelése. - /// - [Table(nameof(MembershipContext.RoleGroupUsers), Schema = Constants.SCHEMA_NAME)] - public partial class RoleGroupUser - { - /// - /// Szerepkör egyedi azonosítója. - /// - [Key, Column(Order = 0), DatabaseGenerated(DatabaseGeneratedOption.None)] - public int RoleGroupId { get; set; } - - /// - /// Felhasználó egyedi azonosítója. - /// - [Key, Column(Order = 1), DatabaseGenerated(DatabaseGeneratedOption.None)] - public Guid UserId { get; set; } - - #region Virtual foreignkeys - - [ForeignKey(nameof(RoleGroupId))] - public virtual RoleGroup RoleGroup { get; set; } - - [ForeignKey(nameof(UserId))] - public virtual User User { get; set; } - - #endregion Virtual foreignkeys - } - #endregion table-RoleGroupUser - #region table-RoleGroupRole - /// - /// Szerepkörök és szerepek összerendelése. - /// - [Table(nameof(MembershipContext.RoleGroupRoles), Schema = Constants.SCHEMA_NAME)] - public partial class RoleGroupRole - { - /// - /// Szerepkör egyedi azonosítója. - /// - [Key, Column(Order = 0), DatabaseGenerated(DatabaseGeneratedOption.None)] - public int RoleGroupId { get; set; } - - /// - /// Szerep egyedi azonosítója. - /// - [Key, Column(Order = 1), DatabaseGenerated(DatabaseGeneratedOption.None)] - public Guid RoleId { get; set; } - - #region Virtual foreignkeys - - [ForeignKey(nameof(RoleGroupId))] - public virtual RoleGroup RoleGroup { get; set; } - - [ForeignKey(nameof(RoleId))] - public virtual Role Role { get; set; } - - #endregion Virtual foreignkeys - } - #endregion table-RoleGroupRole - #region table-RoleGroup - /// - /// Szerepkörök táblázata. - /// - [Table(nameof(MembershipContext.RoleGroups), Schema = Constants.SCHEMA_NAME)] - public partial class RoleGroup - { - #region Properties - - /// - /// Szerepkör egyedi azonosítója. - /// - [Key] - public int Id { get; set; } - - /// - /// Szerepkör egyedi megnevezése. - /// - [Required, MaxLength(256), Index(IsUnique = true)] - public string Name { get; set; } - - #endregion Properties - - #region Virtual Collections - - /// - /// A szerepkörhöz ezek a szerepek tartoznak. - /// - public virtual ICollection Roles { get; set; } - - /// - /// A szerepkörhöz ezek a felhasználók tartoznak. - /// - public virtual ICollection Users { get; set; } - - #endregion Virtual Collections - - #region Constructor - public RoleGroup() - { - Roles = new HashSet(); - Users = new HashSet(); - } - #endregion Constructor - } - #endregion table-RoleGroup - #region table-Role - /// - /// DefaultMembershipProvider által létrehozott User tábla. - /// - [Table("Roles", Schema = "dbo")] - public partial class Role - { - /// - /// Szerep egyedi azonosítója. - /// - [Key, DatabaseGenerated(DatabaseGeneratedOption.None)] - public Guid RoleId { get; set; } - - /// - /// Melyik alkalmazás szerepe. - /// - public Guid ApplicationId { get; set; } - - /// - /// Szerep neve. - /// - [Required, MaxLength(256)] - public string RoleName { get; set; } - - /// - /// Alkalmazás rövid leírása. - /// - [MaxLength(256)] - public string Description { get; set; } - } - #endregion table-Role - #region table-Application - /// - /// DefaultMembershipProvider által létrehozott User tábla. - /// - [Table("Applications", Schema = "dbo")] - public partial class Application - { - /// - /// Alkalmazás egyedi azonosítója. - /// - [Key, DatabaseGenerated(DatabaseGeneratedOption.None)] - public Guid ApplicationId { get; set; } - - /// - /// Szerep neve. - /// - [Required, MaxLength(256)] - public string ApplicationName { get; set; } - - /// - /// Alkalmazás rövid leírása. - /// - [MaxLength(256)] - public string Description { get; set; } - } - #endregion table-Application - #region table-SecondaryFunction - /// - /// Lehetséges funkciókat tartalmazó táblázat, mely funkciókhoz - /// tartozhat a másodlagos felhasználó. - /// - [Table(nameof(MembershipContext.SecondaryFunctions), Schema = Constants.SCHEMA_NAME)] - public partial class SecondaryFunction - { - #region Properties - - /// - /// A funkció egyedi azonosítója. - /// - [Key] - public int Id { get; set; } - - /// - /// A funkció egyedi megnevezése. - /// - [Required, MaxLength(30), Index(IsUnique = true)] - public string Name { get; set; } - - #endregion Properties - - #region Virtual Collections - - /// - /// A funkcióhoz ezek a másodlagos felhasználók tartoznak tartoznak. - /// - public virtual ICollection SecondaryUsers { get; set; } - - #endregion Virtual Collections - - #region Constructor - public SecondaryFunction() - { - SecondaryUsers = new HashSet(); - } - #endregion Constructor - } - #endregion table-SecondaryFunction - #region table-SecondaryUser - /// - /// Másodlagos felhasználók adatait tartalmazó táblázat. - /// - [Table(nameof(MembershipContext.SecondaryUsers), Schema = Constants.SCHEMA_NAME)] - public partial class SecondaryUser - { - private const string INDEX_FUNCTION_NAME = "IX_SecondaryUser_SecondaryFunctionId_Name"; - - #region Properties - - /// - /// Másodlagos felhasználó belső egyedi azonosítója. - /// - [Key, Index(IsClustered = false)] - public int Id { get; set; } - - /// - /// Az elsődleges felhasználó egyedi azonosítója a dbo.Users táblából. - /// Ő hozzá tartozik a másodlagos felhasználó. - /// - public Guid UserId { get; set; } - - /// - /// Melyik funkcióhoz tartozik a másodlagos felhasználó. - /// - [Index(INDEX_FUNCTION_NAME, 1, IsUnique = true, IsClustered = true)] - public int SecondaryFunctionId { get; set; } - - /// - /// Másodlagos felhasználó neve. - /// - [Required, MaxLength(255)] - [Index(INDEX_FUNCTION_NAME, 2, IsUnique = true, IsClustered = true)] - public string Name { get; set; } - - /// - /// Másodlagos felhasználó jelszava. - /// - [MaxLength(255)] - public string Password { get; set; } - - /// - /// Másodlagos felhasználó érvényes-e jelenleg. - /// - public bool Active { get; set; } = true; - - #endregion Properties - - #region Virtual foreignkeys - - /// - /// A másodlagos felhasználó ehhez az elsődleges felhasználóhoz tartozik. - /// - [ForeignKey(nameof(UserId))] - public virtual User User { get; set; } - - /// - /// A másodlagos felhasználó ehhez a funkcióhoz tartozik. - /// - [ForeignKey(nameof(SecondaryFunctionId))] - public virtual SecondaryFunction SecondaryFunction { get; set; } - - #endregion Virtual foreignkeys - - #region Constructor - public SecondaryUser() - { - } - #endregion Constructor - - public override string ToString() - { - return String.Concat("{", - nameof(Id), "=", this.Id.ToString(), "; ", - nameof(UserId), "=", this.UserId, "; ", - nameof(SecondaryFunctionId), "=", this.SecondaryFunctionId.ToString(), "; ", - nameof(Name), "=", this.Name, "; ", - nameof(Password), "=", this.Password, "; ", - nameof(Active), "=", this.Active.ToString(), - "}" - ); - } - } - #endregion table-SecondaryUser - #region table-SecondaryLogin - /// - /// Másodlagos felhasználók bejelentkezéseit nyilvántartó táblázat. - /// Egy másodlagos felhasználónak egy bejelentkezése tartozhat egy célhoz. - /// Vagyis a UserID+TargetId együtt egyedi kulcsot alkot. - /// - [Table(nameof(MembershipContext.SecondaryLogins), Schema = Constants.SCHEMA_NAME)] - public partial class SecondaryLogin - { - private const string INDEX_USER_TARGET = "IX_SecondaryLogin_UserId_TargetKey"; - - #region Properties - - /// - /// A bejelentkezés belső egyedi azonosítója. - /// - [Key] - public int Id { get; set; } - - /// - /// Másodlagos felhasználó azonosítója, akinek a nevében történt a bejelentkezés. - /// - [Index(INDEX_USER_TARGET, 1, IsUnique = true)] - public int SecondaryUserId { get; set; } - - /// - /// A bejelentkezéshez tartozó azonosító. Értelmezése: - /// Mi célból történt a bejelentkezés? - /// - [MaxLength(20), Index(INDEX_USER_TARGET, 2, IsUnique = true)] - public string TargetKey { get; set; } - - /// - /// Bejelentkezés időpontja. - /// - public DateTime LoginTime { get; set; } - - /// - /// A legutóbbi aktivitás időpontja. - /// - public DateTime LastActivityTime { get; set; } - - #endregion Properties - - #region Virtual foreignkeys - - /// - /// A másodlagos felhasználóra mutató tulajdonság. - /// - [ForeignKey(nameof(SecondaryUserId))] - public virtual SecondaryUser SecondaryUser { get; set; } - - #endregion Virtual foreignkeys - - public override string ToString() - { - return String.Concat("{", - nameof(Id), "=", this.Id.ToString(), "; ", - nameof(SecondaryUserId), "=", this.SecondaryUserId.ToString(), "; ", - nameof(DAL.SecondaryUser.Name), "=", this.SecondaryUser.Name, "; ", - nameof(TargetKey), "=", this.TargetKey ?? "null", "; ", - nameof(LoginTime), "=", this.LoginTime.ToString("G"), "; ", - nameof(LastActivityTime), "=", this.LastActivityTime.ToString("G"), - "}" - ); - } - - } - #endregion table-SecondaryLogin - #region table-UserSupplement - /// - /// A DefaultMembershipProvider 'User' táblájában nem szabad változtatásokat eszközölni - /// a jövőbeni esetleges Microsoft fejlesztések miatt. - /// Ez a tábla arra való, hogy a felhasználóra vonatkozó egyéb kiegészítő adatokat - /// legyen hol tárolni. - /// - /// - /// Ha nincsenek a felhasználónak kiegészítő adatai akkor nem lesz itt rekordja. - /// - [Table(nameof(MembershipContext.UserSupplements), Schema = Constants.SCHEMA_NAME)] - public partial class UserSupplement - { - #region Properties - - /// - /// A felhasználó egyedi azonosítója a 'User' táblából. - /// Itt is csak 1 db azonosító lehet. - /// - [Key, DatabaseGenerated(DatabaseGeneratedOption.None)] - public Guid UserId { get; set; } - - /// - /// Annak jelzése, hogy a felhasználó ideiglenesen létrehozott felhasználó. - /// Ha igaz, akkor ideiglenes, egyébként hamis. Ha nem létezik a felhasználónak - /// itt rekordja, akkor nem ideiglenes felhasználó. - /// Alapértelmezett érték: true. - /// - public bool IsTemporary { get; set; } = true; - - #endregion Properties - - #region Virtual foreignkeys - - [ForeignKey(nameof(UserId))] - public virtual User User { get; set; } - - #endregion Virtual foreignkeys - } - #endregion table-UserSupplement - #endregion tables - - #region MembershipContext - public class MembershipContext : DbContext - { - #region Constructors - // Your context has been configured to use a 'VrhWebMembership' connection string from your application's - // configuration file (App.config or Web.config). - public MembershipContext(string sqlcs) : base(sqlcs) - { - } - #endregion Constructors - - #region DbSets - - #region !!! A migrációból kivett táblák. Ezeket a DefaultMembershipProvider kezeli és hozza létre. !!! - public virtual DbSet Applications { get; set; } - public virtual DbSet Roles { get; set; } - public virtual DbSet Users { get; set; } - #endregion !!! A migrációból kivett két tábla. Ezeket a DefaultMembershipProvider kezeli és hozza létre. !!! - - // Saját táblák, melyek a Global.SCHEMA_NAME állandó szerinti sémában vannak. - public virtual DbSet RoleGroups { get; set; } - public virtual DbSet RoleGroupRoles { get; set; } - public virtual DbSet RoleGroupUsers { get; set; } - public virtual DbSet SecondaryFunctions { get; set; } - public virtual DbSet SecondaryLogins { get; set; } - public virtual DbSet SecondaryUsers { get; set; } - public virtual DbSet UserSupplements { get; set; } - #endregion DbSets - - #region OnModelCreating - protected override void OnModelCreating(DbModelBuilder modelBuilder) - { - //modelBuilder.HasDefaultSchema("GoodBill"); - - //WA20160124: Sajnos az EF a kötelező idegen kulcsnál alapértelmezésként cascadeDelete értékét true-ra állítja, - // ami sok esetben nem megfelelő (nem is értem, miért true a default :(( ) - // Ahol ez előfordul, ott a ForeignKey-eket itt kell definiálni. - // HasRequired = many oldal virtual property - // WithMany = ha a one oldalon lett definiálva ICollection a many-ra, akkor azt kell ide írni, egyébként üres - // HasForeignKey = many oldalon a foreign key mező - } - #endregion OnModelCreating - } - #endregion MembershipContext - } - #endregion DAL - } -} \ No newline at end of file diff --git a/Vrh.Log4Pro.MaintenanceConsole/ConsoleFunction - Tools - TcpIp.cs b/Vrh.Log4Pro.MaintenanceConsole/ConsoleFunction - Tools - TcpIp.cs deleted file mode 100644 index cf0a2de..0000000 --- a/Vrh.Log4Pro.MaintenanceConsole/ConsoleFunction - Tools - TcpIp.cs +++ /dev/null @@ -1,1034 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.IO; -using System.Linq; -using System.Net; -using System.Net.NetworkInformation; -using System.Net.Sockets; -using System.Text; -using System.Threading.Tasks; -using System.Timers; -using System.Xml.Linq; - -namespace Vrh.Log4Pro.MaintenanceConsole.ToolsNS -{ - /// - /// A pinger objektum ping ciklusokat indít (egy ping ciklusban több ping kérés van/lehet), és ezek eredményét - /// tárolja tömörített formátumban elsősorban abból a célból, hogy a tárolt adatok alapján trend diagramot lehessen - /// készíteni a kapcsolat minőségének kimutatására. - /// - public class Pinger : IDisposable - { - /// - /// Egy Pinger objektum létrehozása xml-ből - /// - /// a ping célállomása - /// a pinger konfigurációs paramétereit tartalmazó xml struktúra - public Pinger(string hostNameOrAddress, XElement pingerconfig) : this(hostNameOrAddress, new PingerConfig(pingerconfig)) { } - - /// - /// Egy Pinger objektum létrehozása PrinterConfig osztályból - /// - /// a ping célállomása - /// a konfigurációt tartalmazó pinger objektum - private Pinger(string hostNameOrAddress, PingerConfig pc) - { - this.HostNameOrAddress = hostNameOrAddress; - this.History = new PingHistory(hostNameOrAddress, pc); - this.PingTimeout = pc.pingtimeout; - this.PingCycleFrequency = pc.pingcyclefrequency; - this.PingCycleNumberOfPackages = pc.pingcyclenumofpackages; - this.PingerActiveLength = pc.pingeractivlength; - this.Configuration = pc; - if (pc.RoundTripTimeLimits!=null) - { - Pinger.RoundTripTimeLimits = pc.RoundTripTimeLimits; - Pinger.MaxRoundTripTimeoutCategory = pc.RoundTripTimeLimits.Last(); - Pinger.RoundTripTimeyCategoryLimits = pc.RoundTripTimeyCategoryLimits; - } - } - /// - /// A maximális ping timeout kategória értéke - /// - public static int MaxRoundTripTimeoutCategory = 5000; - - /// - /// A FINOM válaszidő kategóriákat tartalmazza; egy válasz az i. válaszidő kategóriába tartozik, ha a pontos válaszidő nagyobb, vagy egyenlő, - /// mint az i. elem értéke, de kisebb, mint az i+1. elem értéke.A sor első elemének értéke mindig 0!!!! - /// Ha a sor értékei: 0:0,1:100,2:200,3:300,4:400,5:500, a pontos válaszidő 350, akkor ez a 2. kategóriába tartozik, ha pontos válaszidő. - /// - public static List RoundTripTimeLimits = new List { 0, 25, 50, 75, 100, 150, 200, 250, 300, 400, 500, 750, 1000, 1250, 1500, 1750, 2000, 2500, 3000, 3500, 4000, 4500, Pinger.MaxRoundTripTimeoutCategory, }; - - /// - /// A DURVA válaszidő kategóriákat tartalmazza; egy válasz az i. válaszidő kategóriába tartozik, ha a pontos válaszidő nagyobb, vagy egyenlő, - /// mint az i. elem értéke, de kisebb, mint az i+1. elem értéke.A sor első elemének értéke mindig 0!!!! - /// Ha a sor értékei: 0:0,1:100,2:200,3:300,4:400,5:500, a pontos válaszidő 350, akkor ez a 2. kategóriába tartozik, ha pontos válaszidő. - /// - public static List RoundTripTimeyCategoryLimits = new List { 0, 50, 250, 750, }; - - /// - /// A pinger indítása/újraindítása; elindítja a ping ciklus időzítőt, és elkezdi/folytatja a ping státusz adatok letárolását - /// - /// pinger konfig xml struktúra, amely - /// (jellemzően újraindítás esetén) a Pinger részleges átkonfigurálását teszi lehetővé - public void Start(XElement pingerconfig = null) - { - lock (pingcyclelocker) - { - CycleTimerStop(); - Reconfigure(pingerconfig); - CycleTimerStart(); - - if (this.PingerActiveLength > 0) - { - AutoStopTimerStop(); - AutoStopTimerStart(); - } - } - } - - /// - /// A pinger leállítása; kikapcsolja a ping ciklus időzítőt, és leállítja a ping státusz adatok letárolását - /// - public void Stop() - { - CycleTimerStop(); - } - - /// - /// A Pinge objektum átkonfigurálás a a megadott xml struktúra alapján - /// - /// - private void Reconfigure(XElement pingerconfig = null) - { - lock (pingcyclelocker) - { - if (pingerconfig != null) - { - var pc = new PingerConfig(pingerconfig); - this.PingTimeout = pc.pingtimeout; - this.PingCycleFrequency = pc.pingcyclefrequency; - this.PingCycleNumberOfPackages = pc.pingcyclenumofpackages; - this.PingerActiveLength = pc.pingeractivlength; - this.History.SetHistoryLength(pc.pingerhistorylength); - if (pc.RoundTripTimeLimits != null) - { - Pinger.RoundTripTimeLimits = pc.RoundTripTimeLimits; - Pinger.MaxRoundTripTimeoutCategory = pc.RoundTripTimeLimits.Last(); - Pinger.RoundTripTimeyCategoryLimits = pc.RoundTripTimeyCategoryLimits; - } - } - } - } - - /// - /// A pinger autostop lejártakor végrehajtandó metódus - /// - /// - /// - private void AutoStop(Object source, ElapsedEventArgs e) { CycleTimerStop(); } - - private void CycleTimerStop() - { - lock (pingcyclelocker) { if (this.CycleTimer != null) { this.CycleTimer.Enabled = false; } this.Operating = false; } - } - private void CycleTimerStart() - { - lock (pingcyclelocker) - { - if (this.CycleTimer == null) { this.CycleTimer = new System.Timers.Timer(); this.CycleTimer.Elapsed += StartPingCycle; this.CycleTimer.AutoReset = true; } - this.CycleTimer.Interval = this.PingCycleFrequency; - this.CycleTimer.Enabled = true; - this.Operating = true; - } - } - private void AutoStopTimerStop() - { - lock (pingcyclelocker) - { - if (this.AutoStopTimer != null) { this.AutoStopTimer.Enabled = false; } - } - } - private void AutoStopTimerStart() - { - lock (pingcyclelocker) - { - if (this.AutoStopTimer == null) { this.AutoStopTimer = new System.Timers.Timer(); this.AutoStopTimer.Elapsed += AutoStop; this.AutoStopTimer.AutoReset = false; } - this.AutoStopTimer.Interval = this.PingerActiveLength; - this.AutoStopTimer.Enabled = true; - } - } - /// - /// Dispose - /// - public void Dispose() - { - Stop(); - if (this.CycleTimer != null) { this.CycleTimer.Dispose(); this.CycleTimer = null; } - if (this.AutoStopTimer != null) { this.AutoStopTimer.Dispose(); this.AutoStopTimer = null; } - this.History.Dispose(); - } - - /// - /// Visszadja a history listát - /// - /// - public Pinger.PingHistory GetHistory() - { - lock (pingcyclelocker) { this.History.PingerState = this.CycleTimer != null && this.CycleTimer.Enabled ? PingerStatus.Operating : PingerStatus.Still; return this.History; } - } - - #region public fields - /// - /// A ping célállomása - /// - public string HostNameOrAddress; - /// - /// true: a pingcycle timer működik, a pingelés folyamataos - /// false: a pingcycle timer NEM működik, a pingelés áll - /// - public bool Operating; - /// - /// Egy ciklusban kiadott ping kérések száma. - /// - public PingerConfig Configuration; - #endregion public fields - - #region private metódusok - /// - /// A ping ciklus időzítés lejártakor elindított metódus, ami végrehajt egy ping ciklust és eredményét bedolgozza a PingStateQueue sorba - /// - /// - /// - private void StartPingCycle(Object source, ElapsedEventArgs e) - { - lock (pingcyclelocker) - { - this.CycleTimer.Enabled = false; // kikapcsoljuk a timer-t a ciklus végrehajtása alatt - var newpc = new PingCycle(this.HostNameOrAddress, this.PingCycleNumberOfPackages, this.PingTimeout).Execute(); - this.History.Merge(newpc); - this.CycleTimer.Interval = this.PingCycleFrequency;// ha esetleg közben újrakonfigurálták.... - this.CycleTimer.Enabled = true; // a ciklus végrehajtása után ismét elindítjuk az időzítőt - } - } - #endregion private metódusok - - #region private fields - /// - /// Az egyes ping kérések maximális timeout-ja (millisecundum) - /// - private int PingTimeout; - /// - /// A ping ciklus befejeződése után ennyi idővel indítja a következőt (másodpercben) - /// - private int PingCycleFrequency; - /// - /// A ping vizsgálat teljes időtartama; Ennyi idő eltelte után nem indít több több ping ciklust. - /// Érték percben. Ha az érték 0, akkor végtelen hosszú időn keresztül indít ping ciklusokat. - /// - private int PingerActiveLength; - /// - /// Egy ciklusban kiadott ping kérések száma. - /// - private int PingCycleNumberOfPackages; - /// - /// A ping ciklusok keveredését megakadályozó locker objektum - /// - private object pingcyclelocker = new object(); - /// - /// A Pinger működési periódusának hossza (az autostop timer kikapcsolási ideje) (perc) - /// - private System.Timers.Timer AutoStopTimer; - /// - /// A Ping ciklus timere - /// - private System.Timers.Timer CycleTimer; - /// - /// Ping history - /// - private PingHistory History; - #endregion private fields - - #region PingerConfig class - /// - /// PingerConfig osztály - /// - public class PingerConfig - { - /// - /// példány létrehozása xml struktúra alapján - /// - /// - public PingerConfig(XElement pingerconfig) - { - if (pingerconfig != null) - { - var _pingtimeout = GetPositiveIntFromXml(PINGTIMEOUT, pingerconfig); - var _pingcyclefrequency = GetPositiveIntFromXml(PINGCYCLEFREQUENCY, pingerconfig); - var _pingcyclenumofpackages = GetPositiveIntFromXml(PINGCYCLENUMOFPACKAGES, pingerconfig); - var _pingerlifetime = GetPositiveIntFromXml(PINGERACTIVELENGTHTOSTOPPERIOD, pingerconfig); - var _pingerhistorylength = GetPositiveIntFromXml(PINGERHISTORYLENGTH, pingerconfig); - var _optimizehistorylength = pingerconfig.Element(OPTIMIZEHISTORYLENGTH)?.Value; ; - var _roundtriptimelimits = pingerconfig.Element(ROUNDTRIPTIMELIMITS)?.Value; - var _roundtriptimecategorylimits = pingerconfig.Element(ROUNDTRIPTIMECATEGORYLIMITS)?.Value; - SetValues(_pingtimeout, _pingcyclefrequency, _pingcyclenumofpackages, _pingerlifetime, _pingerhistorylength, _roundtriptimelimits, _roundtriptimecategorylimits,_optimizehistorylength); - } - else { SetValues(); } - } - - /// - /// Példány létrehozása paraméterek alapján; a konstruktor célja a mértékegységek és a default értékek kezelése - /// - /// millisecond - /// seconds - /// pcs - /// minutes - /// minutes - public PingerConfig(int pingtimeout = 0, int pingcyclefrequency = 0, int pingcyclenumofpackages = 0, int pingeractivelength = 0, int pingerhistorylength = 0,string rttlimits=null, string rttcatlimits=null,string optimizehlength=null) - { - SetValues(pingtimeout, pingcyclefrequency, pingcyclenumofpackages, pingeractivelength, pingerhistorylength, rttlimits , rttcatlimits, optimizehlength); - } - - /// - /// Beállítja a field-ek értékét a megfelelő mértékegységben a paraméterek, illetve az alapértelmezések szerint - /// - /// millisecond - /// seconds - /// pcs - /// minutes - /// minutes - private void SetValues(int pingtimeout = 0, int pingcyclefrequency = 0, int pingcyclenumofpackages = 0, int pingeractivelength = 0, int pingerhistorylength = 0, string rttlimits = null, string rttcatlimits = null,string optimizehlength=null) - { - this.pingcyclenumofpackages = pingcyclenumofpackages <= 0 ? PingerConfig.DEFAULT_PINGCYCLENUMOFPACKAGES : pingcyclenumofpackages; - this.pingeractivlength = (pingeractivelength <= 0 ? PingerConfig.DEFAULT_PINGERACTIVELENGTH : pingeractivelength) * 60 * 1000; - this.pingerhistorylength = (pingerhistorylength <= 0 ? PingerConfig.DEFAULT_PINGERHISTORYLENGTH : pingerhistorylength) * 60 * 1000; - bool optimizehlengthbool=true; - if (optimizehlength != null) { optimizehlengthbool = bool.TryParse(optimizehlength.ToLower(), out optimizehlengthbool) ? optimizehlengthbool : true; } - this.optimizehistorylength = optimizehlengthbool; - - try - { - // ha a megadott sor nem ok, akkor nem változtat a default-on - List rttl = rttlimits.Split(new char[] { ' ', ',', ';', '/', }, StringSplitOptions.RemoveEmptyEntries).ToList().Select(x => int.Parse(x)).ToList(); - if (rttl.Count <4) { throw new Exception(); } - if (rttl.ElementAt(0) != 0) { throw new Exception(); } - int lastelementvalue = -1; - for(var i=0;i rttcl = rttcatlimits.Split(new char[] { ' ', ',', ';', '/', }, StringSplitOptions.RemoveEmptyEntries).ToList().Select(x => int.Parse(x)).ToList(); - if (rttcl.Count != 4) { throw new Exception(); } - if (rttcl.ElementAt(0) != 0) { throw new Exception(); } - lastelementvalue = -1; - for (var i = 0; i < rttcl.Count; i++) { if (rttcl.ElementAt(i) <= lastelementvalue) { throw new Exception(); } lastelementvalue = rttcl.ElementAt(i); } - - this.RoundTripTimeLimits = rttl; - this.RoundTripTimeyCategoryLimits = rttcl; - } - catch - { - this.RoundTripTimeLimits = Pinger.RoundTripTimeLimits; - this.RoundTripTimeyCategoryLimits = Pinger.RoundTripTimeyCategoryLimits; - } - this.pingtimeout = pingtimeout <= 0 ? rttlimits.Last() : pingtimeout; - this.pingcyclefrequency = pingcyclefrequency * 1000; - if (this.pingcyclefrequency < this.pingtimeout) { this.pingcyclefrequency = this.pingtimeout; } - } - - /// - /// Egy int értéket kiemel a megadott xml struktúrából, ha nincs ott a keresett érték, - /// vagy nem integer, vagy nem pozitív, akkor az alapértelmezést adja vissza - /// - /// az xml struktúrában a keresett elem neve - /// az xml struktúra - /// az alapértelmezett érték - /// - private static int GetPositiveIntFromXml(string xname, XElement pingerconfig, int defaultvalue=0) - { - string valstr = pingerconfig?.Element(XName.Get(xname))?.Value; - int val = defaultvalue; - if (valstr != null && int.TryParse(valstr, out int val1) && val1 > 0) { val = val1; } - return val; - } - - public List RoundTripTimeLimits=null; - public List RoundTripTimeyCategoryLimits=null; - public int pingtimeout; - public int pingcyclefrequency; - public int pingcyclenumofpackages; - public int pingeractivlength; - public int pingerhistorylength; - public bool optimizehistorylength; - - const string PINGTIMEOUT = "PingTimeout"; - const string PINGCYCLEFREQUENCY = "PingCycleFrequency"; - const string PINGCYCLENUMOFPACKAGES = "PingCycleNumOfPackages"; - const string PINGERACTIVELENGTHTOSTOPPERIOD = "PingerActiveLength"; - const string PINGERHISTORYLENGTH = "PingerHistoryLength"; - const string OPTIMIZEHISTORYLENGTH = "OptimizeHistoryLength"; - const string ROUNDTRIPTIMELIMITS = "RoundTripTimeLimits"; - const string ROUNDTRIPTIMECATEGORYLIMITS = "RoundTripCategoryLimits"; - public const int DEFAULT_PINGTIMEOUT = 0; - public const int DEFAULT_PINGCYCLENUMOFPACKAGES = 4; - public const int DEFAULT_PINGERACTIVELENGTH = 60; - public const int DEFAULT_PINGERHISTORYLENGTH = 60; - } - #endregion PingerConfig class - - #region PingHistory class - /// - /// Ping history struktúra - /// - public class PingHistory : IDisposable - { - /// - /// Ping állapot-sor. Minden eleme egy kezdő-időponttól fogva a következő elem kezdőidopontjáig fennálló állapotot ír le. - /// Ha az új státusz állapot-ban a RoundtripTimeCategory vagy StatusCategory értéke a sorban levő legutolsó elemben levő értékekhez képes - /// KÜLÖNBÖZIK, akkor Új elem kerül be a sorba; - /// AZONOS, akkor a legutolsó elemben a PackagesSent és PackagesLost értékekhez hozzáadódik az új elemben levő megfelelő érték, de új elem nem kerül hozzáadásra - /// - public List PingStateQueue; - /// - /// A PingStateQueue utolsó eleme - /// - private PingCycle LastPingCycle; - - /// - /// A tárolt history hossza percben - /// - public int Length; - - /// - /// A ping ciklusok gyakorisága - /// - public int PingCycleFrequency; - - /// - /// Az érvényes configuráció - /// - public PingerConfig PingerConfig; - - public string HostNameOrAddress; - public PingerStatus PingerState = PingerStatus.Still; - public DateTime StartTime; - - private object historylocker = new object(); - - public PingHistory(string hostnameoraddress, PingerConfig pingerconfig) - { - this.HostNameOrAddress = hostnameoraddress; - this.PingStateQueue = new List(); - this.LastPingCycle = null; - this.Length = pingerconfig.pingerhistorylength; - this.PingCycleFrequency = pingerconfig.pingcyclefrequency; - this.PingerConfig = pingerconfig; - } - public PingHistory(PingHistory ph) - { - this.HostNameOrAddress = ph.HostNameOrAddress; - this.PingStateQueue = ph.PingStateQueue.Select(x=>new PingCycle(x)).ToList(); - this.LastPingCycle = ph.LastPingCycle; - this.Length = ph.Length; - this.PingCycleFrequency = ph.PingCycleFrequency; - this.PingerConfig = ph.PingerConfig; - } - - public void Dispose() - { - this.PingStateQueue = null; - this.LastPingCycle = null; - } - /// - /// A PrintCycle beillesztése a sor végére, vagy "hozzáadása" az utolsó elemhez - /// - /// - public void Merge(PingCycle newpc) - { - lock (historylocker) - { - if (!this.PingerConfig.optimizehistorylength || (this.LastPingCycle?.isDifferent(newpc) ?? true)) { this.PingStateQueue.Add(newpc); this.LastPingCycle = newpc; } - else - { - var totalrtt = ((this.LastPingCycle.RoundtripTimeAverage * this.LastPingCycle.NumberOfCycles) + newpc.RoundtripTimeAverage); - this.LastPingCycle.NumberOfCycles++; - this.LastPingCycle.RoundtripTimeAverage = totalrtt / this.LastPingCycle.NumberOfCycles; - this.LastPingCycle.PackagesSent += newpc.PackagesSent; - this.LastPingCycle.PackagesLost += newpc.PackagesLost; - this.LastPingCycle.PackagesSentCategory = this.LastPingCycle.GetLostPackageCategory(); - this.LastPingCycle.LastTimestamp = newpc.StartTimestamp; - if (newpc.RoundtripTimeMax != -1 && this.LastPingCycle.RoundtripTimeMax != -1) - { - if (this.LastPingCycle.RoundtripTimeMax < newpc.RoundtripTimeMax) { this.LastPingCycle.RoundtripTimeMax = newpc.RoundtripTimeMax; } - if (this.LastPingCycle.RoundtripTimeMin > newpc.RoundtripTimeMin) { this.LastPingCycle.RoundtripTimeMin = newpc.RoundtripTimeMin; } - } - } - - var borderts = newpc.StartTimestamp.AddMilliseconds(-1 * this.Length); - this.PingStateQueue.RemoveAll(x => x.LastTimestamp <= borderts); - var firstelement = this.PingStateQueue.FirstOrDefault(); - if (firstelement != null && firstelement.StartTimestamp < borderts) - { - var partiallength = (firstelement.LastTimestamp - borderts).TotalMilliseconds; - var fulllength = (firstelement.LastTimestamp - firstelement.StartTimestamp).TotalMilliseconds; - firstelement.PackagesSent = (int)((double)firstelement.PackagesSent * partiallength / fulllength); - firstelement.PackagesLost = (int)((double)firstelement.PackagesLost * partiallength / fulllength); - firstelement.NumberOfCycles = (int)((double)firstelement.NumberOfCycles * partiallength / fulllength); - if (firstelement.NumberOfCycles == 0 || firstelement.PackagesSent == 0) { this.PingStateQueue.Remove(firstelement); firstelement = this.PingStateQueue.FirstOrDefault(); } - - firstelement.PackagesSentCategory = firstelement.GetLostPackageCategory(); - firstelement.StartTimestamp = borderts; - } - StartTime = firstelement?.StartTimestamp ?? DateTime.MaxValue; - } - } - - /// - /// Beállítja a history hosszát - /// - /// - public void SetHistoryLength(int pingerhistoryperiod) - { - lock (historylocker) { this.Length = pingerhistoryperiod; } - } - } - #endregion PingHistory class - - #region PingCycle class - /// - /// A ping history-ban szereplő elemek típusa - /// - public class PingCycle - { - /// - /// Ping ciklus objektum létrehozása - /// - /// a pingek célja - /// ennyi ping-et kell végrehajtani - /// ennyi az egyes ping-ek timeout-ja - public PingCycle(string hostnameoraddress, int numofpings, int pingtimeout) - { - this.HostNameOrAddress = hostnameoraddress; - this.PackagesSent = numofpings; - this.PingTimeout = pingtimeout; - this.PackagesLost = 0; - this.PackagesSentCategory = LostPackageCategory.Excellent; - this.NumberOfCycles = 1; - this.StatusCategory = IPStatusCategory.NotExecuted; - this.RoundtripTimeAverage = 0; - this.RoundtripTimeMin = -1; - this.RoundtripTimeMax = -1; - } - public PingCycle(PingCycle pc) - { - this.HostNameOrAddress = pc.HostNameOrAddress; - this.PackagesSent = pc.PackagesSent; - this.PingTimeout = pc.PingTimeout; - this.PackagesLost = pc.PackagesLost; - this.PackagesSentCategory = pc.PackagesSentCategory; - this.NumberOfCycles = pc.NumberOfCycles; - this.StatusCategory = pc.StatusCategory; - this.RoundtripTime = pc.RoundtripTime; - this.RoundtripTimeAverage = pc.RoundtripTimeAverage; - this.RoundtripTimeMax = pc.RoundtripTimeMax; - this.RoundtripTimeMin= pc.RoundtripTimeMin; - this.RoundtripTimeCategory = pc.RoundtripTimeCategory; - } - - #region public fields,enums - /// - /// A Ping állapot ezen időpillanattól kezdődően állt/áll fenn - /// - public DateTime StartTimestamp; - /// - /// A Ping állapot ezen időpillanattól kezdődően állt/áll fenn - /// - public DateTime LastTimestamp; - /// - /// Az állapot ilyen válaszidőt jelent (valójában ez is egy kategória, de egy konkrét idő érték jellemzi) - /// - public int RoundtripTime; - - /// - /// A ping ciklusban végrehajtott ping-ek maximális válaszideje - /// - public int RoundtripTimeMax=-1; - /// - /// A ping ciklusban végrehajtott ping-ek minimális válaszideje - /// - public int RoundtripTimeMin=-1; - - /// - /// A pontos válaszidők átlaga - /// - public int RoundtripTimeAverage; - - /// - /// Az állapot ilyen válaszidő kategóriát jelent - /// - public RoundTripTimeCategory RoundtripTimeCategory; - /// - /// Az állapot ilyen IPStatus kategóriát jelent - /// - public IPStatusCategory StatusCategory; - /// - /// Ebben a státus állapotban ennyi csomag került kiküldésre - /// - public int PackagesSent; - /// - /// Ebben a státus állapotban ennyi csomag veszett el nem Success - /// - public int PackagesLost; - /// - /// Ebben a státus állapotban az elveszett csomagokra utaló státusz - /// - public LostPackageCategory PackagesSentCategory; - /// - /// A ping ciklusok száma ebben az egységben - /// - public int NumberOfCycles; - - /// - /// Válasz státusz kategóriák; minél nagyobb az érték, annál kevesebbet tudunk a hiba okáról. - /// - public enum IPStatusCategory { Success = 0, TimedOut = 10, PortUnreachable = 20, HostUnreachable = 30, NetworkUnreachable = 40, Failed = 50, NotExecuted = 100, } - public enum LostPackageCategory { Excellent = 0, Good = 1, Acceptable = 2, Bad = 3, } - public enum RoundTripTimeCategory { Q1 = 0, Q2 = 1, Q3 = 2, Q4 = 3, } - #endregion public fields,enums - - #region isDifferent - /// - /// Eldönti, hogy a két objektum azonosnak tekinthető-e, vagy sem - /// - /// - /// - public bool isDifferent(PingCycle pc) - { - return this.StatusCategory != pc.StatusCategory - || this.RoundtripTime != pc.RoundtripTime; - } - #endregion isDifferent - - #region Execute - /// - /// Egy ping ciklus végrehajtása; - /// - /// - /// StatusCategory: értéke NotExecuted értéktől különbözni fog. - /// StartTimestamp: értéke a hívás időpillanata lesz. - /// PackagesLost: a nem Success-sel visszatérő ping-ek száma - /// RoundtripTimeCategory: a válaszidő kategória értéke - /// - public PingCycle Execute() - { - this.StartTimestamp = DateTime.Now; - this.LastTimestamp = this.StartTimestamp; - PingReply pr; - for (var i = 0; i < this.PackagesSent; i++) - { - pr = null; - try { pr = PingTool.Ping(this.HostNameOrAddress, (int)PingTimeout); }//egy ping kérés feladása - catch { } - AddResponse(pr, i + 1);//a ping válasz "bedolgozása" a pingciklus-állapotba - } - - this.PackagesSentCategory = GetLostPackageCategory(); - this.RoundtripTime = Pinger.RoundTripTimeLimits.LastOrDefault(x => x <= this.RoundtripTimeAverage); - var RoundTripTimeyCategoryValue = Pinger.RoundTripTimeyCategoryLimits.LastOrDefault(x => x < this.RoundtripTimeAverage); - var RoundTripTimeyCategoryIndex = Pinger.RoundTripTimeyCategoryLimits.FindIndex(x => x == RoundTripTimeyCategoryValue); - this.RoundtripTimeCategory = RoundTripTimeyCategoryIndex == 0 ? RoundTripTimeCategory.Q1 - : RoundTripTimeyCategoryIndex == 1 ? RoundTripTimeCategory.Q2 - : RoundTripTimeyCategoryIndex == 2 ? RoundTripTimeCategory.Q3 - : RoundTripTimeCategory.Q4; - return this; - } - #endregion Execute - - #region private elemek - /// - /// a ping célcíme - /// - private string HostNameOrAddress; - /// - /// Az egyes ping kérések timeout-ja - /// - private int PingTimeout; - /// - /// A ping válasz bedolgozása a pingciklus státuszba - /// - /// a ping válasza - /// a ping kérés indexe; 1,2,.... - private void AddResponse(PingReply pr, int i) - { - var ipsCat = GetIPStatusCategory(pr); - if (ipsCat==IPStatusCategory.Success) - { - int prroundtriptime = pr.RoundtripTime >= int.MaxValue ? int.MaxValue : (int)pr.RoundtripTime; - this.RoundtripTimeMin = prroundtriptime < this.RoundtripTimeMin || this.RoundtripTimeMin ==-1 ? prroundtriptime : this.RoundtripTimeMin; - this.RoundtripTimeMax = prroundtriptime > this.RoundtripTimeMax || this.RoundtripTimeMax == -1 ? prroundtriptime : this.RoundtripTimeMax; - this.RoundtripTimeAverage = ((i - 1) * this.RoundtripTimeAverage + prroundtriptime) / i;// az átlagos válaszidőt tárolja - } - else { this.PackagesLost++; } - if (ipsCat < this.StatusCategory) { this.StatusCategory = ipsCat; }// a legjobb státuszt tárolja - } - - /// - /// Visszaadja az elveszett és összes csomagok száma alapján a lostpackagecategory értéket - /// - /// az elveszett csomagok száma - /// az összes csomagok száma - /// - public LostPackageCategory GetLostPackageCategory() - { - double packagelostratio = (double)this.PackagesLost / (double)this.PackagesSent; - return packagelostratio == 0 ? PingCycle.LostPackageCategory.Excellent - : packagelostratio < 0.1 ? PingCycle.LostPackageCategory.Good - : packagelostratio < 0.3 ? PingCycle.LostPackageCategory.Acceptable - : PingCycle.LostPackageCategory.Bad; - } - /// - /// Visszaadja, hogy a PingReply adat alapján a válasz melyik státusz kategóriába tartozik - /// - /// - /// - private static IPStatusCategory GetIPStatusCategory(PingReply pr) - { - //if (new Random().Next(0, 9) < 3) { return IPStatusCategory.Failed; } - if (pr == null) { return IPStatusCategory.Failed; } - switch (pr.Status) - { - case IPStatus.Success: return IPStatusCategory.Success;//Success = 0,The ICMP echo request succeeded; an ICMP echo reply was received. When you get this status code, the other System.Net.NetworkInformation.PingReply properties contain valid data. - - case IPStatus.DestinationNetworkUnreachable: //DestinationNetworkUnreachable = 11002,The ICMP echo request failed because the network that contains the destination computer is not reachable. - return IPStatusCategory.NetworkUnreachable; - - case IPStatus.BadRoute: //BadRoute = 11012,The ICMP echo request failed because there is no valid route between the source and destination computers. - case IPStatus.DestinationUnreachable: //DestinationUnreachable = 11040,The ICMP echo request failed because the destination computer that is specified in an ICMP echo message is not reachable; the exact cause of problem is unknown. - case IPStatus.DestinationHostUnreachable: //DestinationHostUnreachable = 11003,The ICMP echo request failed because the destination computer is not reachable. - return IPStatusCategory.HostUnreachable; - - case IPStatus.TtlReassemblyTimeExceeded://TtlReassemblyTimeExceeded = 11014,The ICMP echo request failed because the packet was divided into fragments for transmission and all of the fragments were not received within the time allottedfor reassembly. RFC 2460 (available at www.ietf.org) specifies 60 seconds as the time limit within which all packet fragments must be received. - case IPStatus.TtlExpired://TtlExpired = 11013,The ICMP echo request failed because its Time to Live (TTL) value reached zero, causing the forwarding node (router or gateway) to discard the packet. - case IPStatus.TimeExceeded: //TimeExceeded = 11041,The ICMP echo request failed because its Time to Live (TTL) value reached zero, causing the forwarding node (router or gateway) to discard the packet. - case IPStatus.TimedOut: //TimedOut = 11010,The ICMP echo Reply was not received within the allotted time. The default time allowed for replies is 5 seconds. You can change this value using theOverload:System.Net.NetworkInformation.Ping.Send or Overload:System.Net.NetworkInformation.Ping.SendAsync methods that take a timeout parameter. - return IPStatusCategory.TimedOut; - - //DestinationProhibited = 11004,The ICMPv6 echo request failed because contact with the destination computer is administratively prohibited. This value applies only to IPv6. - case IPStatus.DestinationProtocolUnreachable://DestinationProtocolUnreachable = 11004, The ICMP echo request failed because the destination computer that is specified in an ICMP echo message is not reachable, because it does not support the packet'sprotocol. This value applies only to IPv4. This value is described in IETF RFC 1812 as Communication Administratively Prohibited. - case IPStatus.DestinationPortUnreachable: //DestinationPortUnreachable = 11005,Summary: The ICMP echo request failed because the port on the destination computer is not available. - case IPStatus.Unknown://Unknown = -1,The ICMP echo request failed for an unknown reason. - case IPStatus.NoResources: //NoResources = 11006,Summary: The ICMP echo request failed because of insufficient network resources. - case IPStatus.BadOption: //BadOption = 11007,The ICMP echo request failed because it contains an invalid option. - case IPStatus.HardwareError: //HardwareError = 11008,The ICMP echo request failed because of a hardware error. - case IPStatus.PacketTooBig: //PacketTooBig = 11009,The ICMP echo request failed because the packet containing the request is larger than the maximum transmission unit (MTU) of a node (router or gateway) located between the source and destination. The MTU defines the maximum size of a transmittable packet. - case IPStatus.ParameterProblem: //ParameterProblem = 11015,The ICMP echo request failed because a node (router or gateway) encountered problems while processing the packet header. This is the status if, for example, the header contains invalid field data or an unrecognized option. - case IPStatus.SourceQuench: //SourceQuench = 11016,The ICMP echo request failed because the packet was discarded. This occurs when the source computer's output queue has insufficient storage space, or when packetsarrive at the destination too quickly to be processed. - case IPStatus.BadDestination: //BadDestination = 11018,The ICMP echo request failed because the destination IP address cannot receive ICMP echo requests or should never appear in the destination address field ofany IP datagram. For example, calling Overload:System.Net.NetworkInformation.Ping.Send and specifying IP address "000.0.0.0" returns this status. - case IPStatus.BadHeader: //BadHeader = 11042,The ICMP echo request failed because the header is invalid. - case IPStatus.UnrecognizedNextHeader://UnrecognizedNextHeader = 11043,The ICMP echo request failed because the Next Header field does not contain a recognized value. The Next Header field indicates the extension header type (ifpresent) or the protocol above the IP layer, for example, TCP or UDP. - case IPStatus.IcmpError: //IcmpError = 11044,The ICMP echo request failed because of an ICMP protocol error. - case IPStatus.DestinationScopeMismatch://DestinationScopeMismatch = 11045, The ICMP echo request failed because the source address and destination address that are specified in an ICMP echo message are not in the same scope. This istypically caused by a router forwarding a packet using an interface that is outside the scope of the source address. Address scopes (link-local, site-local, andglobal scope) determine where on the network an address is valid. } - return IPStatusCategory.Failed; - } - return IPStatusCategory.Failed; - } - #endregion private elemek - } - #endregion PingCycle class - - public enum PingerStatus { NotExisting = 2, Still = 1, Operating = 0, } - } - - /// - /// TCP Ping eszközök - /// - public static class PingTool - { - /// - /// Elérhető e az állomás? - /// - /// Ip, vagy host név - /// timeout - /// - public static bool IsHostAccessible(string hostNameOrAddress, int timeOut = 1000) - { - PingReply reply = Ping(hostNameOrAddress, timeOut); - return reply.Status == IPStatus.Success; - } - - /// - /// Visszadja az állomás ping idejét (millisecundum) - /// - /// Ip, vagy host név - /// timeout - /// - public static long GetPingTime(string hostNameOrAddress, int timeOut = 1000) - { - PingReply reply = Ping(hostNameOrAddress, timeOut); - return reply.RoundtripTime; - } - - /// - /// Visszadja az állomás ping szerinti státuszát (IPStatus) - /// - /// Ip, vagy host név - /// timeout - /// - - /// - public static IPStatus GetPingStatus(string hostNameOrAddress, int timeOut = 1000) - { - PingReply reply = Ping(hostNameOrAddress, timeOut); - return reply.Status; - } - - /// - /// Ping - /// - /// Ip, vagy host név - /// timeout - /// PingReply - public static PingReply Ping(string hostNameOrAddress, int timeOut = 1000) - { - Ping ping = new Ping(); - return ping.Send(hostNameOrAddress, timeOut); - } - - /// - /// Ping specifikált adatokkal - /// - /// Ip, vagy host név - /// timeout - /// ping adatok - /// PingReply - public static PingReply Ping(string hostNameOrAddress, int timeOut, byte[] buffer) - { - if (buffer.Length > 65500) - { - throw new ArgumentException("Ping data too big! Maximum 65500 bytes allowed!"); - } - Ping ping = new Ping(); - return ping.Send(hostNameOrAddress, timeOut, buffer); - } - - /// - /// Ping specifikált adatokkal és beállításokkal (PingOptions) - /// - /// Ip, vagy host név - /// timeout - /// ping adatok - /// ping beállítások - /// PingReply - public static PingReply Ping(string hostNameOrAddress, int timeOut, byte[] buffer, PingOptions options) - { - if (buffer.Length > 65500) - { - throw new ArgumentException("Ping data too big! Maximum 65500 bytes allowed!"); - } - Ping ping = new Ping(); - return ping.Send(hostNameOrAddress, timeOut, buffer, options); - } - } - /// - /// IPv4 kezeléssel kapcsolatos eszközök - /// - public static class IPv4Tool - { - /// - /// Visszad egy IPAddress osztályt, amit a megadott byte értékekből épít fel - /// - /// - /// - public static IPAddress BuildIPAddress(params byte[] ip) - { - if (ip.Length != 4) - { - throw new ArgumentException("Invalid IP! Specific 4 byte value for valid IP address!"); - } - return new IPAddress(ip); - } - - public static IPAddress BuildIPAddress(string ipOrHostname) - { - IPAddress ip; - - if (IPAddress.TryParse(ipOrHostname, out ip)) - { - // IP - return ip; - } - else - { - // Hostname - try - { - IPHostEntry hostEntry; - hostEntry = Dns.GetHostEntry(ipOrHostname); - foreach (var address in hostEntry.AddressList) - { - if (address.AddressFamily == AddressFamily.InterNetwork) - { - return address; - } - } - throw new ArgumentException(String.Format("Bad input argument! (Argument is not Ip or DNS resorvable host name.)", ipOrHostname)); - } - catch (Exception ex) - { - throw new ArgumentException(String.Format("Bad input argument! (Argument is not Ip or DNS resorvable host name.)", ipOrHostname), ex); - } - } - } - } - - /// - /// MAC address lekérdezése IP alapján - /// - public static class MACTool - { - /// - /// Gets the MAC address () associated with the specified IP. - /// - /// The remote IP address. - /// The remote machine's MAC address. - public static PhysicalAddress GetMacAddress(IPAddress ipAddress) - { - const int MacAddressLength = 6; - int length = MacAddressLength; - var macBytes = new byte[MacAddressLength]; - SendARP(BitConverter.ToInt32(ipAddress.GetAddressBytes(), 0), 0, macBytes, ref length); - return new PhysicalAddress(macBytes); - } - - public static PhysicalAddress GetMacAddress(string ipAddressOrHostName) - { - return MACTool.GetMacAddress(IPv4Tool.BuildIPAddress(ipAddressOrHostName)); - } - - public static PhysicalAddress GetMacAddress(params byte[] ipAddress) - { - return MACTool.GetMacAddress(IPv4Tool.BuildIPAddress(ipAddress)); - } - - public static string ToString(this PhysicalAddress mac, char byteSeparator) - { - return HexString.ByteArrayToHexViaLookup32(mac.GetAddressBytes(), byteSeparator); - } - - /// - /// Netbiostól kér a mac címet, csak netbiost megvalósító eszközökre működik!!! - /// Elég lassú... - /// - /// - /// - public static string GetMacAddressFromNetBios(string ipAddress) - { - string macAddress = string.Empty; - - if (!PingTool.IsHostAccessible(ipAddress)) - { - return String.Empty; - } - try - { - ProcessStartInfo processStartInfo = new ProcessStartInfo(); - Process process = new Process(); - if (Environment.Is64BitOperatingSystem) - { - string filePath = Environment.GetFolderPath(Environment.SpecialFolder.Windows) + "\\sysnative"; - processStartInfo.FileName = Path.Combine(filePath, "nbtstat"); - } - else - { - processStartInfo.FileName = "nbtstat"; - } - processStartInfo.RedirectStandardInput = false; - processStartInfo.RedirectStandardOutput = true; - processStartInfo.Arguments = "-a " + ipAddress; - processStartInfo.UseShellExecute = false; - process = Process.Start(processStartInfo); - string line = null; - do - { - line = macAddress = process.StandardOutput.ReadLine(); - if (line != null) - { - if (macAddress.Trim().ToLower().IndexOf("mac address", 0) > -1) - { - macAddress = line; - break; - } - } - } while (line != null); - process.WaitForExit(); - if (macAddress.IndexOf('=') > -1) - { - macAddress = macAddress.Substring(macAddress.IndexOf('=') + 1); - } - macAddress = macAddress.Trim(); - } - catch (Exception e) - { - // Something unexpected happened? Inform the user - // The possibilities are: - // 1.That the machine is not on the network currently - // 2. The IP address/hostname supplied are not on the same network - // 3. The host was not found on the same subnet or could not be - // resolved - } - return macAddress; - } - - /// - /// ARP query kiküldése - /// - /// - /// - /// - /// - /// - // http://www.codeproject.com/KB/IP/host_info_within_network.aspx - [System.Runtime.InteropServices.DllImport("iphlpapi.dll", ExactSpelling = true)] - static extern int SendARP(int DestIP, int SrcIP, byte[] pMacAddr, ref int PhyAddrLen); - } - - - public static class HexString - { - private static readonly uint[] _lookup32 = CreateLookup32(); - - private static uint[] CreateLookup32() - { - var result = new uint[256]; - for (int i = 0; i < 256; i++) - { - string s = i.ToString("X2"); - result[i] = ((uint)s[0]) + ((uint)s[1] << 16); - } - return result; - } - - public static string ByteArrayToHexViaLookup32(byte[] bytes, char separator) - { - var lookup32 = _lookup32; - byte multipier = 2; - int length = bytes.Length * 2; - if (separator != '\0') - { - length = bytes.Length * 3 - 1; - multipier = 3; - } - var result = new char[length]; - for (int i = 0; i < bytes.Length; i++) - { - var val = lookup32[bytes[i]]; - result[multipier * i] = (char)val; - result[multipier * i + 1] = (char)(val >> 16); - if (separator != '\0' && i != bytes.Length - 1) - { - result[multipier * i + 2] = separator; - } - } - return new string(result); - } - } -} \ No newline at end of file diff --git a/Vrh.Log4Pro.MaintenanceConsole/ConsoleFunction - Tools.cs b/Vrh.Log4Pro.MaintenanceConsole/ConsoleFunction - Tools.cs deleted file mode 100644 index 64dfeb5..0000000 --- a/Vrh.Log4Pro.MaintenanceConsole/ConsoleFunction - Tools.cs +++ /dev/null @@ -1,498 +0,0 @@ -using System; -using System.IO; -using System.IO.Compression; -using System.Collections.Generic; -using System.Linq; -using System.Security.Principal; -using System.Text; -using System.Text.RegularExpressions; -using System.Threading.Tasks; -using System.Threading; - -using Microsoft.Web.Administration; -using System.Management; -using System.Diagnostics; - -using Vrh.XmlProcessing; -using System.Xml.Linq; -using Vrh.Log4Pro.MaintenanceConsole.ColorConsoleNS; -using VRH.Common; -using Microsoft.Win32; -using System.Reflection; -using Vrh.Log4Pro.MaintenanceConsole.CommandLineParserNS; - -namespace Vrh.Log4Pro.MaintenanceConsole.ToolsNS -{ - public static class OtherTools - { - public static bool IsRunAsAdmin() - { - WindowsIdentity id = WindowsIdentity.GetCurrent(); - WindowsPrincipal pr = new WindowsPrincipal(id); - return pr.IsInRole(WindowsBuiltInRole.Administrator); - } - public static void StartAsAdmin() - { - if (!OtherTools.IsRunAsAdmin()) - { - ProcessStartInfo proc = new ProcessStartInfo(); - - proc.UseShellExecute = true; - proc.WorkingDirectory = Environment.CurrentDirectory; - proc.FileName = Assembly.GetEntryAssembly().CodeBase; - proc.Verb = "runas"; - try - { - Process.Start(proc); - System.Environment.Exit(1); - } - catch (Exception ex) - { - Console.WriteLine("This program must be run as an administrator! \n\n" + ex.ToString()); - } - } - } - - public static void StartAsSystem(bool interactivemode=false) - { - if (interactivemode) - { - var ans = ColorConsole.ReadLine("NT AUTHORITY\\SYSTEM", prefix: "Start as ",f:ConsoleColor.Yellow, suffix: "?", bracket: "[]",validitylist:new List { "yes","no"},exitvalue:"EX",defaultvalue:"no"); - if (ans?.ToLower() != "yes") { return; } - } - string runasusername = System.Security.Principal.WindowsIdentity.GetCurrent().Name; - if (runasusername=="NT AUTHORITY\\SYSTEM") { return; } - - Process p = new System.Diagnostics.Process(); - p.StartInfo.FileName = @"C:\Log4ProIS\MAINTENANCECONSOLE\PsTools\psexec.exe"; - p.StartInfo.UseShellExecute = false; - - p.StartInfo.Arguments = @"-sid C:\Log4ProIS\MAINTENANCECONSOLE\Vrh.Log4Pro.MaintenanceConsole.exe " + CLP.CMD_STARTASSYSTEM + " YES"; - p.Start(); - System.Environment.Exit(1); - } - } - public static class ZipTools - { - public static void Extract1stFileFromZIP(string targetfilefullpath, string ZIPfilefullpath) - { - if (File.Exists(targetfilefullpath)) { File.Delete(targetfilefullpath); } - using (ZipArchive archive = ZipFile.Open(ZIPfilefullpath, ZipArchiveMode.Read)) - { - foreach (var zipentry in archive.Entries) - { - zipentry.ExtractToFile(targetfilefullpath); - return; - } - } - } - public static void ExtractAllFileFromZIP(string targetdirectorypath, string ZIPfilefullpath) - { - if (!Directory.Exists(targetdirectorypath)) { Directory.CreateDirectory(targetdirectorypath); } - using (ZipArchive archive = ZipFile.Open(ZIPfilefullpath, ZipArchiveMode.Read)) - { - foreach (var zipentry in archive.Entries) - { - zipentry.ExtractToFile(Path.Combine(targetdirectorypath, zipentry.FullName)); - } - } - } - - public static void CreateEntriesFromDirectoryContent(string sourcefolderpath, string ZIPfilefullpath, string includefilenamemask, string includefullpathregex, bool removearchivedfiles = false,bool storepathinzip = true) - { - if (File.Exists(ZIPfilefullpath)) { File.Delete(ZIPfilefullpath); } - DirectoryInfo di = new DirectoryInfo(sourcefolderpath); - var rgx = new Regex(includefullpathregex??""); - var archivedfiles = new List(); - using (ZipArchive archive = ZipFile.Open(ZIPfilefullpath, ZipArchiveMode.Create)) - { - ColorConsole.WriteLine($"ZIP-ping directory '{sourcefolderpath}'...", ConsoleColor.Yellow); - FileInfo[] fis = di.GetFiles(includefilenamemask, SearchOption.AllDirectories); - int maxfilefullpathlength = 0; - int cpt = ColorConsole.CursorTop; - int cpl = ColorConsole.CursorLeft; - foreach (var fi in fis) - { - var entryname = storepathinzip - ? fi.FullName.Substring((Path.GetPathRoot(fi.FullName)?.Length) ?? 0) - : fi.Name; - if (rgx.Match(fi.FullName).Success) - { - try - { - archive.CreateEntryFromFile(fi.FullName, entryname, CompressionLevel.Optimal); - ColorConsole.Write(fi.FullName, ConsoleColor.Yellow); - if (maxfilefullpathlength > fi.FullName.Length) - { - ColorConsole.Write(new string(' ', maxfilefullpathlength - fi.FullName.Length)); - } - else { maxfilefullpathlength = fi.FullName.Length; } - ColorConsole.SetCursorPosition(cpl, cpt); - archivedfiles.Add(fi.FullName); - } - catch (Exception ex) - { - ColorConsole.WriteLine($"Error when accessing/zipping file '{fi.FullName}'!", ConsoleColor.Red); - ColorConsole.WriteLine(ex.Message, ConsoleColor.Red,prefix: "Exception message: ", bracket:"[]"); - } - } - cpt = ColorConsole.CursorTop; - cpl = ColorConsole.CursorLeft; - } - ColorConsole.Write(new string(' ', maxfilefullpathlength)); - ColorConsole.SetCursorPosition(cpl, cpt); - } - if (removearchivedfiles) - { - archivedfiles.ForEach(x => File.Delete(x)); - string[] dirs = System.IO.Directory.GetDirectories(sourcefolderpath); - string[] files = System.IO.Directory.GetFiles(sourcefolderpath); - if (dirs.Length + files.Length == 0) { Directory.Delete(sourcefolderpath); } - } - } - } - public static class Tools - { - public static T GetPropertyValue(object obj, string propName) { return (T)obj.GetType().GetProperty(propName).GetValue(obj, null); } - - public static Dictionary Merge(IEnumerable> dictionaries) - { - return dictionaries.SelectMany(x => x) - .GroupBy(d => d.Key) - .ToDictionary(x => x.Key, y => y.First().Value); - } - - public static bool IsElevated - { - get - { - return new WindowsPrincipal(WindowsIdentity.GetCurrent()).IsInRole(WindowsBuiltInRole.Administrator); - } - } - public static string ExecuteAndGetStdIo(string exepath, string args) - { - StringBuilder outputBuilder = new StringBuilder(); - StringBuilder erroroutputBuilder = new StringBuilder(); - ProcessStartInfo startInfo = new ProcessStartInfo() { }; - using (Process exeProcess = new Process()) - { - startInfo.CreateNoWindow = true; - startInfo.WindowStyle = ProcessWindowStyle.Hidden; - startInfo.RedirectStandardOutput = true; - startInfo.RedirectStandardError= true; - startInfo.RedirectStandardInput = true; - startInfo.UseShellExecute = false; - startInfo.FileName = exepath; - startInfo.Verb= "runas"; - startInfo.Arguments = args; - - exeProcess.StartInfo = startInfo; - // enable raising events because Process does not raise events by default - exeProcess.EnableRaisingEvents = true; - exeProcess.OutputDataReceived += new DataReceivedEventHandler - ( - delegate (object sender, DataReceivedEventArgs e) - { - // append the new data to the data already read-in - outputBuilder.Append(e.Data + "\r\n"); - } - ); - exeProcess.ErrorDataReceived += new DataReceivedEventHandler - ( - delegate (object sender, DataReceivedEventArgs e) - { - // append the new data to the data already read-in - erroroutputBuilder.Append(e.Data + "\r\n"); - } - ); - // start the process - // then begin asynchronously reading the output - // then wait for the process to exit - // then cancel asynchronously reading the output - exeProcess.Start(); - exeProcess.BeginOutputReadLine(); - exeProcess.WaitForExit(); - exeProcess.CancelOutputRead(); - return outputBuilder.ToString(); - } - } - - public static string GetTemporaryFoldername(string directorypath) - { - return Path.Combine(directorypath, DateTime.Now.ToString($"TMP_yyyyMMddHHmmssfffffff")); - } - public static string GetTemporaryfilename(string directorypath, string extension) - { - if (extension == null) { extension = ".tmp"; } - return Path.Combine(directorypath, DateTime.Now.ToString($"TMP_yyyyMMddHHmmssfffffff.{extension}")); - } - public static void ShutDown(ShutDownMode oparation) - { - string filename = string.Empty; - string arguments = string.Empty; - switch (oparation) - { - case ShutDownMode.ShutDown: - filename = "shutdown.exe"; - arguments = "-s"; - break; - case ShutDownMode.Restart: - filename = "shutdown.exe"; - arguments = "-r"; - break; - case ShutDownMode.Logoff: - filename = "shutdown.exe"; - arguments = "-l"; - break; - case ShutDownMode.Lock: - filename = "Rundll32.exe"; - arguments = "User32.dll, LockWorkStation"; - break; - case ShutDownMode.Hibernation: - filename = @"%windir%\system32\rundll32.exe"; - arguments = "PowrProf.dll, SetSuspendState"; - break; - case ShutDownMode.Sleep: - filename = "Rundll32.exe"; - arguments = "powrprof.dll, SetSuspendState 0,1,0"; - break; - } - ProcessStartInfo startinfo = new ProcessStartInfo(filename, arguments); - Process.Start(startinfo); - } - public enum ShutDownMode { Sleep, Hibernation,Lock,Logoff,Restart,ShutDown,} - private static string HKLM_GetString(string path, string key) - { - try - { - Microsoft.Win32.RegistryKey rk = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(path); - if (rk == null) return ""; - return (string)rk.GetValue(key); - } - catch { return null; } - } - - public static string GetOSFriendlyNameA() - { - string ProductName = HKLM_GetString(@"SOFTWARE\Microsoft\Windows NT\CurrentVersion", "ProductName"); - string CSDVersion = HKLM_GetString(@"SOFTWARE\Microsoft\Windows NT\CurrentVersion", "CSDVersion"); - if (!string.IsNullOrWhiteSpace(ProductName)) - { - return (ProductName.StartsWith("Microsoft") ? "" : "Microsoft ") + ProductName + (CSDVersion != "" ? " " + CSDVersion : ""); - } - return null; - } - - public static string GetOSFriendlyNameB() - { - string result = string.Empty; - ManagementObjectSearcher searcher = new ManagementObjectSearcher("SELECT Caption FROM Win32_OperatingSystem"); - foreach (ManagementObject os in searcher.Get()) { result = os["Caption"].ToString(); break; } - return string.IsNullOrWhiteSpace(result)? null : result; - } - public static string GetOSFriendlyNameC() - { - return new Microsoft.VisualBasic.Devices.ComputerInfo().OSFullName; - } - public static string GetOSType() - { - string os = null; - IEnumerable list64 = System.IO.Directory.GetDirectories(Environment.GetEnvironmentVariable("SystemRoot")).Where(s => s.Equals(@"C:\Windows\SysWOW64")); - IEnumerable list32 = System.IO.Directory.GetDirectories(Environment.GetEnvironmentVariable("SystemRoot")).Where(s => s.Equals(@"C:\Windows\System32")); - if (list32.Count() > 0) { if (list64.Count() > 0) { os = "64bit"; } else { os = "32bit"; } } - return os; - } - public static bool ResolveArguments(string parameterkvpstring, string stringwithparameters, out string resolvedtext, bool interactive = true) - { - var argumentparametersdictionary = parameterkvpstring.Split(new char[] { ';', ',' }, StringSplitOptions.RemoveEmptyEntries) - .Select(kvp => CreateKVP(kvp)) - .Where(kvp => kvp.Key != null) - .ToDictionary(kvp => kvp.Key, kvp => kvp.Value); - Dictionary resolveddictionary = new Dictionary(); - resolvedtext = stringwithparameters; - foreach (var kvp in argumentparametersdictionary) - { - if (kvp.Value.StartsWith("?") && interactive) - { - string prompt = $"Enter value for {kvp.Key}:"; - string kvpdefaultvalue = null; - if (kvp.Value.Length > 1) - { - prompt = kvp.Value.Substring(1).Split(new char[] { '?' }, StringSplitOptions.RemoveEmptyEntries)[0]; - if (kvp.Value.Substring(1).IndexOf('?') != -1) kvpdefaultvalue = kvp.Value.Substring(1).Split(new char[] { '?' }, StringSplitOptions.RemoveEmptyEntries)[1]; - } - string value = ColorConsole.ReadLine(prompt, ConsoleColor.Yellow, defaultvalue: kvpdefaultvalue); - if (value.ToLower() == "ex") { return false; } - resolveddictionary.Add(kvp.Key, value); - } - else if (kvp.Value.StartsWith("?") && !interactive) resolveddictionary.Add(kvp.Key, $"{{{kvp.Key}}}"); - else { resolveddictionary.Add(kvp.Key, kvp.Value); } - } - resolvedtext = VRH.Common.StringConstructor.ResolveConstructorR(resolveddictionary, stringwithparameters, "{}@@"); - return true; - } - private static KeyValuePair CreateKVP(string kvpstring) - { - string kvpk = null; - string kvpv = null; - try - { - kvpk = kvpstring.Split(new char[] { '=' }, StringSplitOptions.RemoveEmptyEntries)[0]; if (string.IsNullOrWhiteSpace(kvpk)) { kvpk = null; } - kvpv = kvpstring.Split(new char[] { '=' }, StringSplitOptions.RemoveEmptyEntries)[1]; - KeyValuePair r = new KeyValuePair(kvpk, kvpv); - return r; - } - catch { return new KeyValuePair(kvpk, null); } - } - } - - class ComputerInfo - { - public string PageHeader; - public string ComputerName; - public string DNSHostName; - public string UserName; - public string DomainUserName; - public List IpAddressList; - public string ProcessorArchitecture; - public string OSType; - public string NumOfPhysicalProcessors; - public string NumOfLogicalProcessors; - public string NumOfCores; - public string OSPlatform; - public string OSServicePack; - public string OSVersionString; - public List OSFriendlyNames; - public static void DisplayThis() { new ComputerInfo().Display(); } - public ComputerInfo() - { - var ci = this; - const string XMLCONNECTIONSTRING = "config=MAINTENANCECONSOLE;"; - //const string XMLCONNECTIONSTRING_DEFAULT = "file=Config.Xml;"; - var config = new MaintenanceConsoleXmlProcessor(XMLCONNECTIONSTRING, "", "hu-HU"); - - ci.PageHeader = config.Xml_Header; - ci.ComputerName = System.Environment.MachineName; - ci.DNSHostName = System.Net.Dns.GetHostName(); - ci.UserName = Environment.UserName; - ci.DomainUserName = System.Security.Principal.WindowsIdentity.GetCurrent().Name; - ci.IpAddressList = System.Net.Dns.GetHostEntry(ci.DNSHostName).AddressList.Where(ip => ip.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork).ToList(); - ci.ProcessorArchitecture = System.Environment.GetEnvironmentVariable("PROCESSOR_ARCHITECTURE"); - ci.OSType = Tools.GetOSType(); - foreach (var item in new System.Management.ManagementObjectSearcher("Select * from Win32_ComputerSystem").Get()) - { - ci.NumOfPhysicalProcessors = item["NumberOfProcessors"].ToString(); - ci.NumOfLogicalProcessors = item["NumberOfLogicalProcessors"].ToString(); - break; - } - - var numofcores = 0; - foreach (var item in new System.Management.ManagementObjectSearcher("Select * from Win32_Processor").Get()) { numofcores += int.Parse(item["NumberOfCores"].ToString()); } - ci.NumOfCores = numofcores.ToString(); - ci.OSPlatform = System.Environment.OSVersion.Platform.ToString(); - ci.OSServicePack = System.Environment.OSVersion.ServicePack; - ci.OSVersionString = System.Environment.OSVersion.VersionString; - - string fn; - ci.OSFriendlyNames = new List(); - fn = Tools.GetOSFriendlyNameA(); if (!string.IsNullOrWhiteSpace(fn) && !ci.OSFriendlyNames.Contains(fn)) ci.OSFriendlyNames.Add(fn); - fn = Tools.GetOSFriendlyNameB(); if (!string.IsNullOrWhiteSpace(fn) && !ci.OSFriendlyNames.Contains(fn)) ci.OSFriendlyNames.Add(fn); - fn = Tools.GetOSFriendlyNameC(); if (!string.IsNullOrWhiteSpace(fn) && !ci.OSFriendlyNames.Contains(fn)) ci.OSFriendlyNames.Add(fn); - } - public void Display() - { - const string XMLCONNECTIONSTRING = "config=MAINTENANCECONSOLE;"; - //const string XMLCONNECTIONSTRING_DEFAULT = "file=Config.Xml;"; - var config = new MaintenanceConsoleXmlProcessor(XMLCONNECTIONSTRING, "", "hu-HU"); - - ColorConsole.WriteLine(PageHeader, ConsoleColor.Yellow, bracket: "[]"); - - //computername - ColorConsole.WriteLine(""); - ColorConsole.Write("Computer name: "); - ColorConsole.Write(ComputerName, ConsoleColor.Yellow, bracket: "[]", prefix: "", suffix: ","); - ColorConsole.Write(DNSHostName, ConsoleColor.Yellow, bracket: "[]", prefix: "DNS hostname:"); - ColorConsole.WriteLine(""); - - //username - ColorConsole.Write("Username:"); - ColorConsole.Write(UserName, ConsoleColor.Yellow, bracket: "[]", prefix: "RunAs:", suffix: ","); - ColorConsole.Write(DomainUserName, ConsoleColor.Yellow, bracket: "[]", prefix: "LoggedIn:"); - ColorConsole.WriteLine(""); - - //ip address - ColorConsole.Write("IP addresses: "); - if (IpAddressList.Any()) { foreach (var ip in IpAddressList) { ColorConsole.Write(ip.ToString(), ConsoleColor.Yellow, bracket: "[]", prefix: $"{ip.AddressFamily}:", suffix: ","); } } - else { ColorConsole.Write("N/A", ConsoleColor.Yellow, bracket: "[]"); } - - ColorConsole.WriteLine(""); - - // processor architecture - ColorConsole.Write("Processors: "); - ColorConsole.Write(System.Environment.GetEnvironmentVariable("PROCESSOR_ARCHITECTURE"), ConsoleColor.Yellow, bracket: "[]", prefix: "Architecture: "); - ColorConsole.Write(OSType ?? "N/A", ConsoleColor.Yellow, bracket: "[]", suffix: ", "); - ColorConsole.Write(NumOfPhysicalProcessors, ConsoleColor.Yellow, bracket: "[]", prefix: "Physical:", suffix: ", "); - ColorConsole.Write(NumOfLogicalProcessors, ConsoleColor.Yellow, bracket: "[]", prefix: "Logical:", suffix: ", "); - ColorConsole.Write(NumOfCores, ConsoleColor.Yellow, bracket: "[]", prefix: "Cores:"); - ColorConsole.WriteLine(""); - - - // os version - ColorConsole.Write("Operating system: "); - ColorConsole.Write(OSPlatform.ToString(), ConsoleColor.Yellow, bracket: "[]", prefix: "Platform:", suffix: ","); - ColorConsole.Write(OSServicePack, ConsoleColor.Yellow, bracket: "[]", prefix: "Service pack:", suffix: ","); - ColorConsole.Write(OSVersionString, ConsoleColor.Yellow, bracket: "[]", prefix: "Version string:"); - ColorConsole.WriteLine(""); - - ColorConsole.Write("", ConsoleColor.Yellow, prefix: "OS Friendly name versions:"); - if (OSFriendlyNames.Any()) { foreach (var fn in OSFriendlyNames) { ColorConsole.Write(fn, ConsoleColor.Yellow, bracket: "[]"); } } - else { ColorConsole.Write("N/A", ConsoleColor.Yellow, bracket: "[]"); } - - ColorConsole.WriteLine(""); - ColorConsole.WriteLine(""); - ColorConsole.WriteLine(""); - } - } - - - #region StringExtension class - public static class StringExtension - { - /// - /// Behelyezzesíti a megadott stringben előforduló Environment.SpecialFolder enum neveket - /// az Environment.GetFolderPath által visszadott tényleges értékükre - /// - /// - /// - /// - public static string SubstituteSpecialFolderName(this string s, Environment.SpecialFolder n) { return s.Replace("@" + n.ToString() + "@", Environment.GetFolderPath(n)); } - } - #endregion StringExtension class - - #region ExceptionExtension class - public static class ExceptionExtension - { - /// - /// Az exception és belső exceptionjeinek összefűzése - /// - /// - /// - public static string MessageNested(this Exception ex) - { - string rexmsg = ""; - string indent = ""; - const string indentof1level = " "; - Exception excl = ex; - while (true) - { - rexmsg += indent + excl.Message; - excl = excl.InnerException; - indent += (indent==""?"\n":"")+indentof1level; - if (excl == null) { break; } - } - return rexmsg.Replace("\n\n","\n"); - } - } - - #endregion ExceptionExtension class -} diff --git a/Vrh.Log4Pro.MaintenanceConsole/Manager - BackupPackageManager.cs b/Vrh.Log4Pro.MaintenanceConsole/Manager - BackupPackageManager.cs index 27568ed..d649979 100644 --- a/Vrh.Log4Pro.MaintenanceConsole/Manager - BackupPackageManager.cs +++ b/Vrh.Log4Pro.MaintenanceConsole/Manager - BackupPackageManager.cs @@ -90,7 +90,7 @@ namespace Vrh.Log4Pro.MaintenanceConsole.BackupPackageManagerNS foreach (var bf in bp.Xml_BackupFolderList) { BackupPackageManagerCore.FolderZipBackup(bf, tempfolderpath); } foreach (var sqldb in bp.Xml_BackupSQLDataBaseList) { SQLDataBaseManagerNS.SQLDataBaseManager.Execute(sqldb.Xml_Key,sqldb.Xml_DBBackup,sqldb.Xml_ScriptBackup,sqldb.Xml_TableDataBackup, tempfolderpath, timestamp); } - BackupPackageManagerCore.CreatePackageFile(bp.Xml_PackageName, tempfolderpath, destinationfilename,destinationfolder, bp.Xml_CreateExe, bp.Xml_SourceIncludeFilenameMaskList); + BackupPackageManagerCore.CreatePackageFile(bp.Xml_PackageName, tempfolderpath, destinationfilename,destinationfolder, bp.Xml_CreateExe, bp.Xml_SourceIncludeFilenameMaskList, bp.Xml_ExcludeMaskList); if (Directory.Exists(tempfolderpath)) { Directory.Delete(tempfolderpath,true); } } catch (Exception ex) { ColorConsole.WriteLine(ex.MessageNested(), ConsoleColor.Red); } @@ -138,7 +138,8 @@ namespace Vrh.Log4Pro.MaintenanceConsole.BackupPackageManagerNS } if (lineix == 2) { - ColorConsole.Write($"{bp.Xml_SourceIncludeFilenameMaskList}", ConsoleColor.White, prefix: "Mask:"); + ColorConsole.Write($"{bp.Xml_SourceIncludeFilenameMaskList}", ConsoleColor.White, prefix: "Incl.mask:"); + ColorConsole.Write($"{bp.Xml_ExcludeMaskList}", ConsoleColor.White, prefix: " Excl.mask:"); ColorConsole.Write($"{bp.SizePackageTotal}", ConsoleColor.White, prefix: ", Bytes to include:"); ColorConsole.WriteLine(""); return " "; @@ -157,7 +158,7 @@ namespace Vrh.Log4Pro.MaintenanceConsole.BackupPackageManagerNS if (bf.FolderExists) { var di = new DirectoryInfo(bf.Xml_Path); - bp.SizePackageTotal += Vrh.Log4Pro.MaintenanceConsole.FileCleanerManagerNS.FileCleanerManagerCore.DirSize(di, bf.Xml_IncludeFileNameMask, bf.Xml_IncludeFileFullPathRegex, recurse: true); + bp.SizePackageTotal += Vrh.Log4Pro.MaintenanceConsole.FileCleanerManagerNS.FileCleanerManagerCore.DirSize(di, bf.Xml_IncludeFileNameMask, bf.Xml_ExcludeFileNameMaskList, bf.Xml_IncludeFileFullPathRegex, recurse: true); } } return bp; @@ -183,6 +184,7 @@ namespace Vrh.Log4Pro.MaintenanceConsole.BackupPackageManagerNS string destinationbackupfile = bf.Xml_BackupToFile; if (string.IsNullOrEmpty(destinationbackupfile)) { destinationbackupfile = (new DirectoryInfo(foldertobackuppath)).Name + ".zip"; } string includefilenamemask = bf.Xml_IncludeFileNameMask; + string excludefilenamemask = bf.Xml_ExcludeFileNameMaskList; string includefullpathregex = bf.Xml_IncludeFileFullPathRegex; var destinationfile = Path.GetFileNameWithoutExtension(destinationbackupfile); @@ -192,7 +194,7 @@ namespace Vrh.Log4Pro.MaintenanceConsole.BackupPackageManagerNS if (File.Exists(destinationbackupfile)) { File.Delete(destinationbackupfile); } if (!Path.IsPathRooted(foldertobackuppath)) { foldertobackuppath = Path.Combine(Directory.GetCurrentDirectory(), foldertobackuppath); } - ZipTools.CreateEntriesFromDirectoryContent(foldertobackuppath, destinationbackupfile, includefilenamemask,includefullpathregex); + ZipTools.CreateEntriesFromDirectoryContent(foldertobackuppath, destinationbackupfile, includefilenamemask, excludefilenamemask,includefullpathregex); ColorConsole.WriteLine($"Folder backup created. Name:{foldertobackuppath}", ConsoleColor.DarkGreen); } /// @@ -205,7 +207,7 @@ namespace Vrh.Log4Pro.MaintenanceConsole.BackupPackageManagerNS /// substitution vars /// if true, exe self extractor will be created, otherwise zip file; the extension of the package file is zip or exe /// comma separated list of masks for the files to include (NOT regex! "old fashioned" masking characters, like ?/* can be used) - public static void CreatePackageFile(string packagename,string sourcedirectorypath, string destinationfilename =null,string destinationfolder=null,bool createexe=true,string sourceincludefilenamemaskList=null) + public static void CreatePackageFile(string packagename,string sourcedirectorypath, string destinationfilename =null,string destinationfolder=null,bool createexe=true,string sourceincludefilenamemaskList=null,string excludeliststring = null) { string[] sourceinclfnamemasklist = sourceincludefilenamemaskList.Split(','); bool createselfextractor = createexe; @@ -231,18 +233,23 @@ namespace Vrh.Log4Pro.MaintenanceConsole.BackupPackageManagerNS string addfilecommand = "a"; string response; string packagefile; + + string[] excludelist = excludeliststring.Split(new char[] { ',', ';' }, StringSplitOptions.RemoveEmptyEntries); + string excludeswitches = ""; + foreach (var exstr in excludelist) excludeswitches += $" -x!{exstr}"; + if (createselfextractor) { string archivetype_7z = "-t7z"; string createsfx = "-sfx"; packagefile = packageEXEfilepath; - response = Tools.ExecuteAndGetStdIo("7z.exe", $"{addfilecommand} {packagefile} {includeliststr} {recursesubdirs} {archivetype_7z} {createsfx}"); + response = Tools.ExecuteAndGetStdIo("7z.exe", $"{addfilecommand} {packagefile} {includeliststr} {recursesubdirs} {excludeswitches} {archivetype_7z} {createsfx} "); } else { string archivetype_zip = "-tzip"; packagefile = packageZIPfilepath; - response = Tools.ExecuteAndGetStdIo("7z.exe", $"{addfilecommand} {packagefile} {includeliststr} {recursesubdirs} {archivetype_zip}"); + response = Tools.ExecuteAndGetStdIo("7z.exe", $"{addfilecommand} {packagefile} {includeliststr} {recursesubdirs} {excludeswitches} {archivetype_zip}"); } ColorConsole.WriteLine($"Backup package created. Package name:{packagename}, package file: {packagefile}", ConsoleColor.Green); @@ -358,6 +365,7 @@ namespace Vrh.Log4Pro.MaintenanceConsole.BackupPackageManagerNS public string Xml_PackageFilePath; public string Xml_TempDirectoryPath; public string Xml_SourceIncludeFilenameMaskList; + public string Xml_ExcludeMaskList; public bool Xml_CreateExe; public List Xml_BackupFolderList; public List Xml_BackupSQLDataBaseList; @@ -394,6 +402,7 @@ namespace Vrh.Log4Pro.MaintenanceConsole.BackupPackageManagerNS Xml_Key = GetValue(nameof(XmlStructure.BackupPackage.Attributes.Key), backupackagexml, XmlStructure.BackupPackage.Attributes.Key.Values.DEFAULT); Xml_Description = GetValue(nameof(XmlStructure.BackupPackage.Attributes.Description), backupackagexml, Xml_PackageName); Xml_SourceIncludeFilenameMaskList = GetValue(nameof(XmlStructure.BackupPackage.Attributes.IncludeFilenameMaskList), backupackagexml, XmlStructure.BackupPackage.Attributes.IncludeFilenameMaskList.Values.DEFAULT); + Xml_ExcludeMaskList = GetValue(nameof(XmlStructure.BackupPackage.Attributes.ExcludeFilenameMaskList), backupackagexml, XmlStructure.BackupPackage.Attributes.ExcludeFilenameMaskList.Values.DEFAULT); Xml_BackupFolderList = new List(); //var conditionxmlList = GetAllXElements(foldertocleanxml, nameof(XmlStructure.FolderToClean.Conditions), nameof(XmlStructure.FolderToClean.Conditions.Condition)); @@ -424,6 +433,7 @@ namespace Vrh.Log4Pro.MaintenanceConsole.BackupPackageManagerNS Xml_TempDirectoryPath = bp.Xml_TempDirectoryPath; Xml_BackupSQLDataBaseList = bp.Xml_BackupSQLDataBaseList.Select(c => new BackupSQLDataBase(c)).ToList(); ; Xml_SourceIncludeFilenameMaskList = bp.Xml_SourceIncludeFilenameMaskList; + Xml_ExcludeMaskList = bp.Xml_ExcludeMaskList; Xml_CreateExe = bp.Xml_CreateExe; } #endregion cloner constructor @@ -451,6 +461,7 @@ namespace Vrh.Log4Pro.MaintenanceConsole.BackupPackageManagerNS public static class Description { } public static class CreateExe { public static class Values { public const bool DEFAULT = true; } } public static class IncludeFilenameMaskList { public static class Values { public const string DEFAULT = "*"; } } + public static class ExcludeFilenameMaskList { public static class Values { public const string DEFAULT = ""; } } public static class PackageFilePath{ public static class Values { public const string DEFAULT = "BackupPackage_{TIMESTAMP}_{PACKAGENAME}"; } } public static class TempDirectoryPath { public static class Values { public const string DEFAULT = ""; } } } @@ -462,6 +473,7 @@ namespace Vrh.Log4Pro.MaintenanceConsole.BackupPackageManagerNS public static class Description { } public static class BackupToFile { } public static class IncludeNameMask { public class Values { public const string DEFAULT = "*"; } } + public static class ExcludeNameMaskList { public class Values { public const string DEFAULT = ""; } } public static class IncludePathRegexp { public class Values { public const string DEFAULT = ".*"; } } } } @@ -488,6 +500,7 @@ namespace Vrh.Log4Pro.MaintenanceConsole.BackupPackageManagerNS Xml_Description = GetValue(nameof(XmlStructure.BackupPackage.BackupFolder.Attributes.Description), backupfolderxml, Xml_Path); Xml_BackupToFile = GetValue(nameof(XmlStructure.BackupPackage.BackupFolder.Attributes.BackupToFile), backupfolderxml, ""); Xml_IncludeFileNameMask = GetValue(nameof(XmlStructure.BackupPackage.BackupFolder.Attributes.IncludeNameMask), backupfolderxml, XmlStructure.BackupPackage.BackupFolder.Attributes.IncludeNameMask.Values.DEFAULT); + Xml_ExcludeFileNameMaskList = GetValue(nameof(XmlStructure.BackupPackage.BackupFolder.Attributes.ExcludeNameMaskList), backupfolderxml, XmlStructure.BackupPackage.BackupFolder.Attributes.ExcludeNameMaskList.Values.DEFAULT); Xml_IncludeFileFullPathRegex = GetValue(nameof(XmlStructure.BackupPackage.BackupFolder.Attributes.IncludePathRegexp), backupfolderxml, XmlStructure.BackupPackage.BackupFolder.Attributes.IncludePathRegexp.Values.DEFAULT); } public BackupFolder(BackupFolder bf) @@ -497,12 +510,14 @@ namespace Vrh.Log4Pro.MaintenanceConsole.BackupPackageManagerNS Xml_BackupToFile = bf.Xml_BackupToFile; FolderExists = bf.FolderExists; Xml_IncludeFileNameMask = bf.Xml_IncludeFileNameMask; + Xml_ExcludeFileNameMaskList= bf.Xml_ExcludeFileNameMaskList; Xml_IncludeFileFullPathRegex = bf.Xml_IncludeFileFullPathRegex; } public string Xml_Path; public string Xml_Description; public string Xml_BackupToFile; public string Xml_IncludeFileNameMask; + public string Xml_ExcludeFileNameMaskList; public string Xml_IncludeFileFullPathRegex; public bool FolderExists; diff --git a/Vrh.Log4Pro.MaintenanceConsole/Manager - FileCleanerManager.cs b/Vrh.Log4Pro.MaintenanceConsole/Manager - FileCleanerManager.cs index 306a807..58aabe8 100644 --- a/Vrh.Log4Pro.MaintenanceConsole/Manager - FileCleanerManager.cs +++ b/Vrh.Log4Pro.MaintenanceConsole/Manager - FileCleanerManager.cs @@ -16,6 +16,7 @@ using System.Diagnostics; using Vrh.Log4Pro.MaintenanceConsole.MenuNS; using Vrh.Log4Pro.MaintenanceConsole.ColorConsoleNS; using Vrh.Log4Pro.MaintenanceConsole.CommandLineParserNS; +using Vrh.Log4Pro.MaintenanceConsole.ToolsNS; using Vrh.XmlProcessing; using VRH.Common; @@ -128,7 +129,8 @@ namespace Vrh.Log4Pro.MaintenanceConsole.FileCleanerManagerNS 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:"); + ColorConsole.Write(ws.Xml_IncludeMask, ConsoleColor.Yellow, prefix: ", Include mask:"); + ColorConsole.WriteLine(ws.Xml_ExcludeMaskList, ConsoleColor.Yellow, prefix: ", Exclude mask:"); return " "; } else if (lineix == 3) @@ -175,8 +177,8 @@ namespace Vrh.Log4Pro.MaintenanceConsole.FileCleanerManagerNS 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.SizeFolderTotal = FileCleanerManagerCore.DirSize(di,"*","","",ftc.Xml_Recurse); + ftc.SizeSelectedBeforeClean = FileCleanerManagerCore.DirSize(di, ftc.Xml_IncludeMask,ftc.Xml_ExcludeMaskList, ftc.Xml_IncludeFullpathRegexp, ftc.Xml_Recurse); ftc.SizeSelectedCleaned = FileCleanerManagerCore.CleanFolderFiles(di,ftc,delete:false); } return ftc; @@ -199,17 +201,25 @@ namespace Vrh.Log4Pro.MaintenanceConsole.FileCleanerManagerNS #endregion IsDirectoryEmpty #region public GetDirSize - public static long DirSize(DirectoryInfo d, string filenamemask, string filefullpathregex, bool recurse) + public static long DirSize(DirectoryInfo d, string includefilenamemask,string excludefilenamemaskcsvlist, string filefullpathregex, bool recurse) { long size = 0; // Add file sizes. - FileInfo[] fis = d.GetFiles(filenamemask, SearchOption.TopDirectoryOnly); - if (fis != null) { foreach (FileInfo fi in fis) { if (Regex.Match(fi.FullName, filefullpathregex).Success) { size += fi.Length; } } } + FileInfo[] fis = d.GetFiles(includefilenamemask, SearchOption.TopDirectoryOnly); + if (fis != null) + { + foreach (FileInfo fi in fis) + { + bool toinclude1 = Regex.Match(fi.FullName, filefullpathregex, RegexOptions.IgnoreCase).Success; + bool toinclude2 = Regex.Match(fi.Name, ZipTools.FileNameMaskListToRegex(excludefilenamemaskcsvlist), RegexOptions.IgnoreCase).Success; + if (toinclude1 && toinclude2) { size += fi.Length; } + } + } // Add subdirectory sizes. if (recurse) { DirectoryInfo[] dis = d.GetDirectories(); - if (dis != null) { foreach (DirectoryInfo di in dis) { size += DirSize(di, filenamemask, filefullpathregex, recurse); } } + if (dis != null) { foreach (DirectoryInfo di in dis) { size += DirSize(di, includefilenamemask, excludefilenamemaskcsvlist, filefullpathregex, recurse); } } } return size; } @@ -291,6 +301,7 @@ namespace Vrh.Log4Pro.MaintenanceConsole.FileCleanerManagerNS var fl = fi.Length; try { + if (Regex.Match(fi.Name, ZipTools.FileNameMaskListToRegex(ftc.Xml_ExcludeMaskList)).Success) continue; if (delete) { File.Delete(fi.FullName); } cleanedsize += fl; } @@ -361,6 +372,7 @@ namespace Vrh.Log4Pro.MaintenanceConsole.FileCleanerManagerNS public bool Xml_Recurse; public bool Xml_RemoveEmptyFolder; public string Xml_IncludeMask; + public string Xml_ExcludeMaskList; public string Xml_IncludeFullpathRegexp; public bool Xml_OrConditionList = true; public List Xml_ConditionList; @@ -394,6 +406,7 @@ namespace Vrh.Log4Pro.MaintenanceConsole.FileCleanerManagerNS 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_ExcludeMaskList = GetValue(nameof(XmlStructure.FolderToClean.Attributes.ExcludeMaskList), foldertocleanxml, XmlStructure.FolderToClean.Attributes.ExcludeMaskList.Values.DEFAULT); Xml_IncludeFullpathRegexp = GetValue(GetXElement(foldertocleanxml,nameof(XmlStructure.FolderToClean.IncludeFullpathRegexp)), XmlStructure.FolderToClean.IncludeFullpathRegexp.Values.DEFAULT); Xml_IncludeFullpathRegexp = Xml_IncludeFullpathRegexp.Replace("{DTSREGEX}", commondatetimestampregex).Replace("{TSREGEX}", commontimestampregex).Replace("{DSREGEX}", commondatestampregex); @@ -417,6 +430,7 @@ namespace Vrh.Log4Pro.MaintenanceConsole.FileCleanerManagerNS Xml_Recurse = ftc.Xml_Recurse; Xml_RemoveEmptyFolder = ftc.Xml_RemoveEmptyFolder; Xml_IncludeMask = ftc.Xml_IncludeMask; + Xml_ExcludeMaskList = ftc.Xml_ExcludeMaskList; Xml_IncludeFullpathRegexp = ftc.Xml_IncludeFullpathRegexp; Xml_OrConditionList = ftc.Xml_OrConditionList; Xml_ConditionList = ftc.Xml_ConditionList.Select(c=>new Condition(c)).ToList(); ; @@ -498,6 +512,13 @@ namespace Vrh.Log4Pro.MaintenanceConsole.FileCleanerManagerNS public const string DEFAULT = "*.*"; } } + public static class ExcludeMaskList + { + public static class Values + { + public const string DEFAULT = ""; + } + } } public static class IncludeFullpathRegexp { diff --git a/Vrh.Log4Pro.MaintenanceConsole/Manager - SQLDataBaseManager.cs b/Vrh.Log4Pro.MaintenanceConsole/Manager - SQLDataBaseManager.cs index 7ccf71b..b5ad19c 100644 --- a/Vrh.Log4Pro.MaintenanceConsole/Manager - SQLDataBaseManager.cs +++ b/Vrh.Log4Pro.MaintenanceConsole/Manager - SQLDataBaseManager.cs @@ -546,7 +546,7 @@ namespace Vrh.Log4Pro.MaintenanceConsole.SQLDataBaseManagerNS string ZIPbackupFullName = Path.Combine(backupdirectorypath, ZIPbackupfilename); if (File.Exists(ZIPbackupFullName)) { File.Delete(ZIPbackupFullName); } - ZipTools.CreateEntriesFromDirectoryContent(backupdirectorypath, ZIPbackupFullName, backupfilename, "", removearchivedfiles: false, storepathinzip: false); + ZipTools.CreateEntriesFromDirectoryContent(backupdirectorypath, ZIPbackupFullName, backupfilename, "","", removearchivedfiles: false, storepathinzip: false); if (File.Exists(backupFullName)) { File.Delete(backupFullName); } returnfilename = ZIPbackupFullName; } @@ -926,7 +926,7 @@ namespace Vrh.Log4Pro.MaintenanceConsole.SQLDataBaseManagerNS ScriptOneObject(sqlserver, tempbackupdirectorypath, backupfilenamemask + backupfilenameext, sqldatabase.Views.Cast().ToList(), vars); ScriptOneObject(sqlserver, tempbackupdirectorypath, backupfilenamemask + backupfilenameext, sqldatabase.Tables.Cast().ToList(), vars); ScriptOneObject(sqlserver, tempbackupdirectorypath, backupfilenamemask + backupfilenameext, sqldatabase.Triggers.Cast().ToList(), vars); - if (createZip) { ZipTools.CreateEntriesFromDirectoryContent(tempbackupdirectorypath, zipfilefullpath, "*.sql", backupts,removearchivedfiles:true, storepathinzip: false); } + if (createZip) { ZipTools.CreateEntriesFromDirectoryContent(tempbackupdirectorypath, zipfilefullpath, "*.sql","", backupts,removearchivedfiles:true, storepathinzip: false); } var resultfilename = zipfilefullpath == null ? "-" : Path.GetFileName(zipfilefullpath); ColorConsole.WriteLine($"SQL scripts created. DB name:'{dbname}'. BAK/ZIP file name:'{resultfilename}'", ConsoleColor.DarkGreen); } @@ -1048,7 +1048,7 @@ namespace Vrh.Log4Pro.MaintenanceConsole.SQLDataBaseManagerNS if (createZip) { string fullpathregex = Regex.Escape(string.Join(";",backupfilepathlist)).Replace(';','|'); - ZipTools.CreateEntriesFromDirectoryContent(tempbackupdirectorypath, zipfilefullpath, "*.sql", fullpathregex, removearchivedfiles: true, storepathinzip: false); + ZipTools.CreateEntriesFromDirectoryContent(tempbackupdirectorypath, zipfilefullpath, "*.sql","", fullpathregex, removearchivedfiles: true, storepathinzip: false); } var resultfilename = zipfilefullpath == null ? "-" : Path.GetFileName(zipfilefullpath); ColorConsole.WriteLine($"SQL data scripts created. DB name:'{dbname}'. BAK/ZIP file name:'{resultfilename}'", ConsoleColor.DarkGreen); diff --git a/Vrh.Log4Pro.MaintenanceConsole/Properties/AssemblyInfo.cs b/Vrh.Log4Pro.MaintenanceConsole/Properties/AssemblyInfo.cs index 39e6d99..0bababb 100644 --- a/Vrh.Log4Pro.MaintenanceConsole/Properties/AssemblyInfo.cs +++ b/Vrh.Log4Pro.MaintenanceConsole/Properties/AssemblyInfo.cs @@ -32,5 +32,5 @@ using System.Runtime.InteropServices; // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.17.1.0")] -[assembly: AssemblyFileVersion("1.17.1.0")] +[assembly: AssemblyVersion("1.18.0.0")] +[assembly: AssemblyFileVersion("1.18.0.0")] diff --git a/Vrh.Log4Pro.MaintenanceConsole/Tools - Http.cs b/Vrh.Log4Pro.MaintenanceConsole/Tools - Http.cs new file mode 100644 index 0000000..ab90753 --- /dev/null +++ b/Vrh.Log4Pro.MaintenanceConsole/Tools - Http.cs @@ -0,0 +1,94 @@ +using System; +using System.IO; +using System.IO.Compression; +using System.Collections.Generic; +using System.Linq; +using System.Security.Principal; +using System.Text; +using System.Text.RegularExpressions; +using System.Threading.Tasks; +using System.Threading; + +using Microsoft.Web.Administration; +using System.Management; +using System.Diagnostics; + +using Vrh.XmlProcessing; +using System.Xml.Linq; +using Vrh.Log4Pro.MaintenanceConsole.ColorConsoleNS; +using VRH.Common; +using Microsoft.Win32; +using System.Reflection; +using Vrh.Log4Pro.MaintenanceConsole.CommandLineParserNS; +using System.Net.Http; +using System.Net.Http.Headers; +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace Vrh.Log4Pro.MaintenanceConsole.ToolsNS +{ + public static class HttpTools + { + public enum RequestType { GET,POST,} + public static ReturnInfoJSON GetReturninfoJSON(string url, int timeoutinseconds,RequestType mode = RequestType.GET, List dictparameterlist=null) + { + string returninfojsonstring = ""; + timeoutinseconds = timeoutinseconds <= 0 ? 100: timeoutinseconds; + try + { + return mode == RequestType.GET? _GetReturninfoJSON(url, timeoutinseconds,out returninfojsonstring) : _PostReturninfoJSON(url, timeoutinseconds, out returninfojsonstring, dictparameterlist); + } + catch (Exception ex) { return new ReturnInfoJSON() { ReturnValue = -1, ReturnMessage = ex.Message + "\n" + returninfojsonstring, }; } + } + + private static ReturnInfoJSON _GetReturninfoJSON(string url, int timeoutinseconds, out string returninfojsonstring) + { + Stream returninfojsonstream; + using (var httpclient = new HttpClient()) + { + httpclient.Timeout = new TimeSpan(0, 0, timeoutinseconds); + returninfojsonstream = Task.Run(async () => await httpclient.GetStreamAsync(url)).GetAwaiter().GetResult(); + } + + returninfojsonstring = GetStreamAsString(returninfojsonstream); + ReturnInfoJSON returninfojson = (ReturnInfoJSON)JsonConvert.DeserializeObject(returninfojsonstring,typeof(ReturnInfoJSON)); + //ReturnInfoJSON returninfojson = Task.Run(async () => await JsonSerializer.DeserializeAsync(returninfojsonstream)).GetAwaiter().GetResult(); + return returninfojson; + } + private static ReturnInfoJSON _PostReturninfoJSON(string url, int timeoutinseconds, out string returninfojsonstring, List dictparameterlist = null) + { + var jsonstring = JsonConvert.SerializeObject(dictparameterlist.Where(p => p.PassTo == Vrh.XmlProcessing.UrlElement.ParameterTypes.dict)); + HttpContent requestcontent = new StringContent(jsonstring); + + HttpResponseMessage returninfojsonhttpresponsemessage; + using (var httpclient = new HttpClient()) + { + httpclient.Timeout = new TimeSpan(0, 0, timeoutinseconds); + returninfojsonhttpresponsemessage = Task.Run(async () => await httpclient.PostAsync(url, requestcontent)).GetAwaiter().GetResult(); + } + + var returninfojsonstream = Task.Run(async () => await returninfojsonhttpresponsemessage.Content.ReadAsStreamAsync()).GetAwaiter().GetResult(); + returninfojsonstring = GetStreamAsString(returninfojsonstream); + ReturnInfoJSON returninfojson = (ReturnInfoJSON)JsonConvert.DeserializeObject(returninfojsonstring, typeof(ReturnInfoJSON)); + //var returninfojson = Task.Run(async () => await JsonSerializer.DeserializeAsync(returninfojsonstream)).GetAwaiter().GetResult(); + return returninfojson; + } + private static string GetStreamAsString(Stream stream) + { + + StreamReader reader = new StreamReader(stream); + return reader.ReadToEnd(); + + byte[] bytes = new byte[stream.Length]; + stream.Position = 0; + stream.Read(bytes, 0, (int)stream.Length); + return Encoding.ASCII.GetString(bytes); // this is your string + } + public class ReturnInfoJSON + { + public int ReturnValue { get; set; } + + public string ReturnMessage { get; set; } + } + } +} \ No newline at end of file diff --git a/Vrh.Log4Pro.MaintenanceConsole/Tools - Membership.cs b/Vrh.Log4Pro.MaintenanceConsole/Tools - Membership.cs new file mode 100644 index 0000000..099165e --- /dev/null +++ b/Vrh.Log4Pro.MaintenanceConsole/Tools - Membership.cs @@ -0,0 +1,1218 @@ +using System; +using System.Data.Linq.SqlClient; +using System.IO; +using System.IO.Compression; +using System.Collections.Generic; +using System.Linq; +using System.Security.Principal; +using System.Text; +using System.Text.RegularExpressions; +using System.Threading.Tasks; +using System.Threading; + +using Microsoft.Web.Administration; +using System.Management; +using System.Diagnostics; + +using Vrh.XmlProcessing; +using System.Xml.Linq; +using Vrh.Log4Pro.MaintenanceConsole.ColorConsoleNS; +using VRH.Common; + +using System.Data.Entity; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; + +namespace Vrh.Log4Pro.MaintenanceConsole.ToolsNS +{ + using System.Web.Security; + + public static class MembershipTools + { + public static void SetConnectionString(string sqlcs) + { + MembershipDBContext = new DAL.MembershipContext(sqlcs); + m_MembershipProvider = System.Web.Security.Membership.Provider; + m_roleProvider = System.Web.Security.Roles.Provider; + } + private static MembershipProvider m_MembershipProvider; + private static RoleProvider m_roleProvider; + private static DAL.MembershipContext MembershipDBContext; + + #region Constants + public class Constants + { + public const string SCHEMA_NAME = "UAdmin"; + + public const string ROLENAME_ADMINISTRATOR = "Administrator"; + public const string ROLENAME_ADMIN = "Admin"; + public const string USERNAME_ADMINISTRATOR = "Administrator"; + public const string PASSWORD_ADMINISTRATOR = "Admin123"; + public const string USERNAME_ADMIN = "Admin"; + public const string PASSWORD_ADMIN = "Admin123"; + public static readonly string[] SYSTEMUSERNAMELIST = new string[] { ROLENAME_ADMIN, USERNAME_ADMINISTRATOR }; + public static readonly DateTime NEVERONLINE = new DateTime(2000, 1, 1); + } + #endregion Constants + + #region Users + public static class Users + { + #region IsSecondaryUser + /// + /// true-val tér vissza, ha léteznek ehhez az elsődleges userhez másodlagos user-ek + /// + /// + /// + public static bool IsSecondaryUserOfUser(string primaryusername) + { + var sUserList = MembershipDBContext.SecondaryUsers.Where(x => x.User != null && x.User.UserName == primaryusername); + return (sUserList != null && sUserList.Any()); + } + #endregion IsSecondaryUser + #region DeleteSecondaryUsersOfUser methods + /// + /// Másodlagos felhasználó törlése a funkció nevének és a felhasználó nevének megadásával. + /// + /// Elsődleges felhasználó neve. + /// Ha nem található a törlendő másodlagos felhasználó. + public static void DeleteSecondaryUsersOfUser(string primaryusername) + { + var sUserList = MembershipDBContext.SecondaryUsers.Where(x => x.User!=null && x.User.UserName == primaryusername); + if (sUserList == null || !sUserList.Any()) + { + throw new ApplicationException($"Secondary users for primary user '{primaryusername}' not found!"); + } + else + { + foreach (var suser in sUserList) + { + var sllist = MembershipDBContext.SecondaryLogins.Where(sl => sl.SecondaryUserId == suser.Id); + if (sllist != null && sllist.Any()) { foreach (var sl in sllist) { MembershipDBContext.SecondaryLogins.Remove(sl); } } + MembershipDBContext.SecondaryUsers.Remove(suser); + } + MembershipDBContext.SaveChanges(); + } + } + #endregion DeleteSecondaryUsersOfUser methods + #region Create + /// + /// Felhasználó létrehozása a paraméterlistában felsorolt paraméterek megadásával. + /// + /// Felhasználó neve. + /// Felhasználó jelszava. + /// hozzárendeli a usert az Admin és az Administrator szerepekhez + /// hozzárendeli a usert minden létező szerephez és szerepkörhöz + /// a felhasználóhoz hozzárendelendő role nevek listája; ha a lista tartalmazza a * tagot, akkor minden role. + /// a felhasználóhoz hozzárendelendő rolegroup nevek listája; ha a lista tartalmazza a * tagot, akkor minden rolegroup. + /// A létrehozott felhasználó MembershipUser objektuma. + public static MembershipUser Create(string username, string password, bool administrator=false,bool superuser=false, string[] rolenames=null,string[]rolegroupnames=null) + { + #region ellenőrzések + if (String.IsNullOrWhiteSpace(username)) { throw new MembershipCreateUserException("Username is required!"); } + + string wrPrefix = "WebReq_"; + string adPrefix = "AD_"; + if (username.StartsWith(wrPrefix, StringComparison.OrdinalIgnoreCase) || username.StartsWith(adPrefix, StringComparison.OrdinalIgnoreCase)) + { + throw new MembershipCreateUserException($"Username format is incorrect, it can not start with {wrPrefix}, {adPrefix}"); + } + #endregion ellenőrzések + + CreateAdminRolesAndUsers(); + MembershipUser user = Membership.GetUser(username); + if (user == null) + { + user = Membership.CreateUser(username, password); + user.LastActivityDate = Constants.NEVERONLINE; + user.LastLoginDate = Constants.NEVERONLINE; + user.Comment = ""; + user.Email = ""; + user.IsApproved = true; + Membership.UpdateUser(user); + //user.ChangePasswordQuestionAndAnswer(password, "", ""); + } + if (superuser) + { + string rgnamelist = string.Join(",", MembershipDBContext.RoleGroups.Select(rg => rg.Name).ToArray()); + if (!string.IsNullOrWhiteSpace(rgnamelist)) { Assign.RoleGroupsToUsers(rgnamelist, username); } + foreach (var rn in System.Web.Security.Roles.GetAllRoles()) + { + if (!Users.IsInRole(username, rn)) { System.Web.Security.Roles.AddUserToRole(username, rn); } + } + } + else if (administrator) + { + if (!System.Web.Security.Roles.IsUserInRole(username, Constants.ROLENAME_ADMINISTRATOR)) { System.Web.Security.Roles.AddUserToRole(username, Constants.ROLENAME_ADMINISTRATOR); } + if (!System.Web.Security.Roles.IsUserInRole(username, Constants.ROLENAME_ADMIN)) { System.Web.Security.Roles.AddUserToRole(username, Constants.ROLENAME_ADMIN); } + } + + string[] selectedrolenames; + if (rolenames != null && rolenames.Any()) + { + selectedrolenames = rolenames.Contains("*") ? System.Web.Security.Roles.GetAllRoles() : rolenames; + if (selectedrolenames != null && selectedrolenames.Any()) + { + foreach (var rname in selectedrolenames) + { + if (string.IsNullOrWhiteSpace(rname)) { continue; } + if (!System.Web.Security.Roles.IsUserInRole(username, rname)) { System.Web.Security.Roles.AddUserToRole(username, rname); } + } + } + } + string[] selectedrolegroupnames; + if (rolegroupnames != null && rolegroupnames.Any()) + { + selectedrolegroupnames = rolegroupnames.Contains("*") ? RoleGroups.GetAllNames().ToArray() : rolegroupnames; + if (selectedrolegroupnames != null && selectedrolegroupnames.Any()) + { + foreach (var rgname in selectedrolegroupnames) + { + if (string.IsNullOrWhiteSpace(rgname)) { continue; } + if (!RoleGroups.IsUserInRoleGroup(username, rgname)) { Assign.RoleGroupsToUsers(rgname, username); } + } + } + } + return user; + } + #endregion Create + #region CreateAdminRolesAndUsers + public static void CreateAdminRolesAndUsers() + { + MembershipUser user; + if (!System.Web.Security.Roles.RoleExists(Constants.ROLENAME_ADMINISTRATOR)) { System.Web.Security.Roles.CreateRole(Constants.ROLENAME_ADMINISTRATOR); } + if (!System.Web.Security.Roles.RoleExists(Constants.ROLENAME_ADMIN)) { System.Web.Security.Roles.CreateRole(Constants.ROLENAME_ADMIN); } + + user = Membership.GetUser(Constants.USERNAME_ADMIN); + if (user == null) + { + user = Membership.CreateUser(Constants.USERNAME_ADMIN, Constants.PASSWORD_ADMIN); + } + if (!System.Web.Security.Roles.IsUserInRole(Constants.USERNAME_ADMIN, Constants.ROLENAME_ADMINISTRATOR)) { System.Web.Security.Roles.AddUserToRole(Constants.USERNAME_ADMIN, Constants.ROLENAME_ADMINISTRATOR); } + if (!System.Web.Security.Roles.IsUserInRole(Constants.USERNAME_ADMIN, Constants.ROLENAME_ADMIN)) { System.Web.Security.Roles.AddUserToRole(Constants.USERNAME_ADMIN, Constants.ROLENAME_ADMIN); } + + user = Membership.GetUser(Constants.USERNAME_ADMINISTRATOR); + if (user == null) + { + user = Membership.CreateUser(Constants.USERNAME_ADMINISTRATOR, Constants.PASSWORD_ADMINISTRATOR); + } + if (!System.Web.Security.Roles.IsUserInRole(Constants.USERNAME_ADMINISTRATOR, Constants.ROLENAME_ADMINISTRATOR)) { System.Web.Security.Roles.AddUserToRole(Constants.USERNAME_ADMINISTRATOR, Constants.ROLENAME_ADMINISTRATOR); } + if (!System.Web.Security.Roles.IsUserInRole(Constants.USERNAME_ADMINISTRATOR, Constants.ROLENAME_ADMIN)) { System.Web.Security.Roles.AddUserToRole(Constants.USERNAME_ADMINISTRATOR, Constants.ROLENAME_ADMIN); } + } + #endregion CreateAdminRolesAndUsers + #region IsInRole public method + /// + /// Annak jelzése, hogy a -ben megadott nevű felhasználó + /// rendelkezik-e a -ben megadott nevű szereppel. + /// + /// A felhasználó neve. + /// A szerep neve. + /// Igaz, ha a felhasználó rendelekezik a megadott szereppel. + public static bool IsInRole(string userName, string roleName) + { + return m_roleProvider.IsUserInRole(userName, roleName); + } + #endregion IsInRole public method + #region Get + public static MembershipUser Get(string userName) + { + return m_MembershipProvider.GetUser(userName, false); + } + #endregion Get + #region GetNameList + /// + /// A maszknak megfelelő felhasználónevek listáját adja vissza. + /// + /// SQL LIKE-ba illeszhető maszk + /// + public static List GetNameList(string usernamemask) + { + if (usernamemask == null) { usernamemask = "%"; } + usernamemask = usernamemask.Replace("%", ".*").Replace("?", "."); + return MembershipDBContext.Users + .Select(u=>u.UserName) + .ToList() + .Where(un => Regex.Match(un, usernamemask).Success) + .ToList(); + } + #endregion GetNameList + #region GetList + /// + /// Az összes felhasználót tartalmazó listát ad vissza. + /// + /// Ha hamis, akkor az ideiglenes felhasználók nincsenek a listában. + /// + public static List GetList(string usernamemask,bool includetempuser = false) + { + var result = new List(); + if (!includetempuser) + { // az ideiglenes felhasználók nélkül + var qry = MembershipDBContext.Users // primary + .Where(u => SqlMethods.Like(u.UserName, usernamemask)) + .GroupJoin(MembershipDBContext.UserSupplements, //foreign + pk => pk.UserId, // primary key + fk => fk.UserId, // foreign key + (pka, fkb) => new { u = pka, us = fkb }) + .SelectMany(sm => sm.us.DefaultIfEmpty(), (sm, d) => new { User = sm.u, UserSupplement = d }) + .Where(x => x.UserSupplement == null || x.UserSupplement.IsTemporary == false) + .Select(s => s.User); + if (qry != null && qry.Any()) + { + foreach (var dbuser in qry) + { + MembershipUser user = m_MembershipProvider.GetUser(dbuser.UserId, false); + if (user != null) + { + result.Add(user); + } + } + } + } + else + { // itt mehet mind, nem kell szűrögetni + foreach (MembershipUser user in m_MembershipProvider.GetAllUsers(0, int.MaxValue, out int totalRecords)) + { + result.Add(user); + } + } + return result; + } + #endregion GetList + #region CheckPassword + public static bool CheckPassword(string username, string userpassword) + { + var user = Membership.GetUser(username); + return user.GetPassword()==userpassword; + } + #endregion CheckPassword + #region Remove + /// + /// Törli a megadott nevű user-t és minden kapcsolatát + /// + /// + /// + /// + /// + public static void Remove(string username) + { + if (string.IsNullOrWhiteSpace(username)) { throw new Exception("Username can not be null or empty or whitespace!"); } + if (Get(username) == null) { throw new ApplicationException($"User {username} does not exist!"); } + if (Constants.SYSTEMUSERNAMELIST.Contains(username)) { throw new MembershipCreateUserException($"System user {username} are not allowed to delete!"); } + Assign.RemoveOfUser(username); + if (Users.IsSecondaryUserOfUser(username)) { Users.DeleteSecondaryUsersOfUser(username); } + m_MembershipProvider.DeleteUser(username, true); + } + #endregion Remove + } + #endregion Users + #region RoleGroups + public static class RoleGroups + { + #region Get methods + /// + /// Szerepkör lekérése az egyedi azonosítója alapján. + /// + /// A keresett funkció azonosítója. + /// A kért szerepkör, egyébként null. + public static DAL.RoleGroup Get(int id) + { + return MembershipDBContext.RoleGroups.FirstOrDefault(x => x.Id == id); + } + /// + /// Szerepkör lekérése az egyedi neve alapján. + /// + /// A keresett szerepkör egyedi neve. + /// A kért szerepkör, egyébként null. + public static DAL.RoleGroup Get(string name) + { + return MembershipDBContext.RoleGroups.FirstOrDefault(x => x.Name == name); + } + /// + /// Szerepkör lekérése az egyedi neve alapján. + /// + /// A keresett szerepkör egyedi neve. + /// A kért szerepkör, egyébként null. + public static List GetAllNames() + { + return MembershipDBContext.RoleGroups.Select(rg=>rg.Name).ToList(); + } + public static bool IsUserInRoleGroup(string username,string rolegroupname) + { + return MembershipDBContext.RoleGroupUsers.Select(rguass => rguass.User.UserName == username && rguass.RoleGroup.Name == rolegroupname).ToList().Any(); + } + #endregion Get methods + + #region Create method + /// + /// Szerepkör létrehozása. + /// + /// A létrehozandó szerepkör. + /// + /// Ha üres vagy null a szerepkör neve. + /// Ha már létezik a megadott név. + /// + public static void Create(DAL.RoleGroup roleGroup) + { + if (String.IsNullOrWhiteSpace(roleGroup.Name)) { throw new ApplicationException("RoleGroup név megadása kötelező!"); } + + if (MembershipDBContext.RoleGroups.Any(x => x.Name == roleGroup.Name)) { throw new ApplicationException($"RoleGroup {roleGroup.Name} already exist!"); } + + MembershipDBContext.RoleGroups.Add(roleGroup); + MembershipDBContext.SaveChanges(); + } + /// + /// Szerepkör létrehozása. + /// + /// A létrehozandó szerepkör. + /// + /// Ha üres vagy null a szerepkör neve. + /// Ha már létezik a megadott név. + /// + public static void Create(string name) + { + if (String.IsNullOrWhiteSpace(name)) { throw new ApplicationException("RoleGroup név megadása kötelező!"); } + if (MembershipDBContext.RoleGroups.Any(x => x.Name == name)) { throw new ApplicationException($"RoleGroup {name} already exist!"); } + MembershipDBContext.RoleGroups.Add(new DAL.RoleGroup { Name = name, }); + MembershipDBContext.SaveChanges(); + } + #endregion Create method + + #region Remove methods + /// + /// Szerepkör törlése az egyedi azonosítója megadásával. + /// A szerepkörhöz tartozó összerendelések is megszűnnek! + /// + /// Törlendő szerep egyedi azonosítója. + /// Ha nem található a törlendő szerepkör. + public static void Remove(int id) + { + var row = MembershipDBContext.RoleGroups.Find(id); + if (row == null) { throw new ApplicationException("RoleGroup does not exist!!"); } + else { MembershipDBContext.RoleGroups.Remove(row); MembershipDBContext.SaveChanges(); } + } + /// + /// Szerepkör törlése az egyedi név megadásával. + /// A szerepkörhöz tartozó összerendelések is megszűnnek! + /// + /// Törlendő szerepkör egyedi neve. + /// Ha nem található a törlendő szerepkör. + public static void Remove(string name) + { + var row = MembershipDBContext.RoleGroups.FirstOrDefault(x => x.Name == name); + if (row == null) { Remove(-1); } + else { Remove(row.Id); } + } + #endregion Remove methods + } + #endregion RoleGroups + #region Roles + public static class Roles + { + #region Get methods + /// + /// Szerep lekérése az egyedi azonosítója alapján. + /// + /// A keresett funkció azonosítója. + /// A kért szerepkör, egyébként null. + public static DAL.Role Get(Guid id) + { + return MembershipDBContext.Roles.FirstOrDefault(x => x.RoleId == id); + } + /// + /// Szerep lekérése az egyedi neve alapján. + /// + /// A keresett szerep egyedi neve. + /// A kért szerep, egyébként null. + public static DAL.Role Get(string name) + { + return MembershipDBContext.Roles.FirstOrDefault(x => x.RoleName== name); + } + /// + /// Szerepek neveinek lekérése. + /// + /// A szerepek neveinek listája. + public static List GetAllNames() + { + return MembershipDBContext.Roles.Select(r => r.RoleName).ToList(); + } + /// + /// A megadott nevű szerep benne van-e a megadott szerepkörben tartozik-e. + /// + /// + /// + /// true, ha igen + public static bool IsRoleInRoleGroup(string rolename, string rolegroupname) + { + return MembershipDBContext.RoleGroupRoles.Select(rtorg => rtorg.Role.RoleName == rolename && rtorg.RoleGroup.Name == rolegroupname).ToList().Any(); + } + #endregion Get methods + + #region Create method + /// + /// Szerep létrehozása. + /// + /// A létrehozandó szerep neve. + /// + /// Ha üres vagy null a szerep neve. + /// Ha már létezik a megadott név. + /// + public static void Create(string rolename, string appname=null) + { + if (String.IsNullOrWhiteSpace(rolename)) { throw new ApplicationException("Role név megadása kötelező!"); } + if (appname==null) { appname = MembershipDBContext.Applications.FirstOrDefault(a => a.ApplicationName == "/")?.ApplicationName; } + if (appname == null) { appname = MembershipDBContext.Applications.First()?.ApplicationName; } + if (appname==null) { throw new ApplicationException("Application nem létezik!"); } + var app = MembershipDBContext.Applications.FirstOrDefault(a => a.ApplicationName == appname); + + if (MembershipDBContext.Roles.Any(x => x.RoleName == rolename)) { throw new ApplicationException($"Role {rolename} already exist!"); } + + System.Web.Security.Roles.CreateRole(rolename); + var rolecreated = MembershipDBContext.Roles.First(x => x.RoleName == rolename); + if (rolecreated==null) { throw new ApplicationException($"Creating role failed. Role name:{rolename}!"); } + //MembershipDBContext.Roles.Add(new DAL.Role() { RoleName = rolename, ApplicationId=app.ApplicationId,Description=null, }); + rolecreated.ApplicationId = app.ApplicationId; + MembershipDBContext.SaveChanges(); + } + #endregion Create method + + #region Remove methods + /// + /// Szerep törlése az egyedi azonosítója megadásával. + /// A szerephez tartozó összerendelések is megszűnnek! + /// + /// Törlendő szerep egyedi azonosítója. + /// Ha nem található a törlendő szerep. + public static void Remove(int id) + { + var row = MembershipDBContext.Roles.Find(id); + if (row == null) { throw new ApplicationException("Role does not exist!!"); } + else { MembershipDBContext.Roles.Remove(row); MembershipDBContext.SaveChanges(); } + } + /// + /// Szerep törlése az egyedi neve megadásával. + /// A szerephez tartozó összerendelések is megszűnnek! + /// + /// Törlendő szerep egyedi neve. + /// Ha nem található a törlendő szerep. + public static void Remove(string name) + { + var row = MembershipDBContext.Roles.FirstOrDefault(x => x.RoleName == name); + if (row == null) { throw new ApplicationException("Role does not exist!!"); } + else + { + System.Web.Security.Roles.DeleteRole(name); + MembershipDBContext.Roles.Remove(row); + MembershipDBContext.SaveChanges(); + } + } + #endregion Remove methods + } + #endregion Roles + #region Assign + public static class Assign + { + #region RemoveOfUser + public static void RemoveOfUser(string username) + { + if (string.IsNullOrWhiteSpace(username)) { throw new Exception("Username can not be empty!"); } + var user = MembershipDBContext.Users.FirstOrDefault(u => u.UserName == username); + if (user==null) { throw new Exception($"User '{username}' does not exist!"); } + var rguasslist = MembershipDBContext.RoleGroupUsers.Where(rg => rg.UserId == user.UserId); + if (rguasslist == null || !rguasslist.Any()) { return; } + foreach (var rguass in rguasslist) { MembershipDBContext.RoleGroupUsers.Remove(rguass); } + } + #endregion RemoveOfUser + #region RolesToUser public method + /// + /// Role-RoleGroup-User összerendelések + /// + /// az összerendelés módját határozza meg + /// ezeket kell összerendelni... + /// ...ezekkel + /// + public static VRH.Common.ReturnInfoJSON RolesToUser(string rolenamecommalist, string usernamecommalist) + { + ReturnInfoJSON result = new ReturnInfoJSON() { ReturnMessage = "Assignment was successful!" }; + try + { + if (m_roleProvider != null) { throw new Exception("RoleService is not enabled!"); } + var rolenamelist = rolenamecommalist != null ? new List(rolenamecommalist.Split(',')) : new List(); + var usernamelist = usernamecommalist != null ? new List(usernamecommalist.Split(',')) : new List(); + foreach (var rolename in rolenamelist) + { + CheckRoleExists(rolename); + foreach (var username in usernamelist) + { + CheckUsersExists(username); + if (!Users.IsInRole(username, rolename)) { System.Web.Security.Roles.AddUserToRole(username, rolename); } + } + } + } + catch (Exception ex) + { + result.ReturnValue = -1; + result.ReturnMessage = ex.Message; + } + return result; + } + #endregion RolesToUser public method + #region RolesToRoleGroups public method + public static VRH.Common.ReturnInfoJSON RolesToRoleGroups(string rolenamecommalist, string rolegroupnamecommalist) + { + DAL.RoleGroup urg; + ReturnInfoJSON result = new ReturnInfoJSON() { ReturnMessage = "Assignment was successful!" }; + try + { + if (m_roleProvider != null) { throw new Exception("RoleService is not enabled!"); } + var rolenamelist = rolenamecommalist != null ? new List(rolenamecommalist.Split(',')) : new List(); + var rolegroupnamelist = rolegroupnamecommalist != null ? new List(rolegroupnamecommalist.Split(',')) : new List(); + foreach (var rolename in rolenamelist) + { + CheckRoleExists(rolename); + foreach (var rolegroupname in rolegroupnamelist) + { + CheckRoleGroupExists(rolegroupname); + DAL.Role role = MembershipDBContext.Roles.FirstOrDefault(x => x.RoleName == rolename); + urg = MembershipDBContext.RoleGroups.FirstOrDefault(x => x.Name == rolegroupname); + if (role != null && urg != null) + { + if (!urg.Roles.Any(x => x.Role.RoleName == rolename)) + { + urg.Roles.Add(new DAL.RoleGroupRole { Role = role }); + MembershipDBContext.SaveChanges(); + UpdateUsersForUserRoleGroup(urg.Id); + } + } + } + } + } + catch (Exception ex) + { + result.ReturnValue = -1; + result.ReturnMessage = ex.Message; + } + return result; + } + #endregion RolesToRoleGroups public method + #region RoleGroupsToUsers public method + public static VRH.Common.ReturnInfoJSON RoleGroupsToUsers(string rolegroupnamecommalist, string usernamecommalist) + { + DAL.RoleGroup urg; + ReturnInfoJSON result = new ReturnInfoJSON() { ReturnMessage = "Assignment was successful!" }; + try + { + if (m_roleProvider != null) { throw new Exception("RoleService is not enabled!"); } + var rolegroupnamelist = rolegroupnamecommalist != null ? new List(rolegroupnamecommalist.Split(',')) : new List(); + var usernamelist = usernamecommalist != null ? new List(usernamecommalist.Split(',')) : new List(); + foreach (var rolegroupname in rolegroupnamelist) + { + CheckRoleGroupExists(rolegroupname); + foreach (var username in usernamelist) + { + CheckUsersExists(username); + Guid userId = Guid.Empty; + if (Guid.TryParse(Users.Get(username).ProviderUserKey.ToString(), out userId)) + { + urg = MembershipDBContext.RoleGroups.FirstOrDefault(x => x.Name == rolegroupname); + DAL.User u = MembershipDBContext.Users.FirstOrDefault(x => x.UserId == userId); + if (u != null && urg != null) + { + if (!urg.Users.Any(x => x.UserId == userId)) + { + urg.Users.Add(new DAL.RoleGroupUser { User = u }); + MembershipDBContext.SaveChanges(); + UpdateRolesForUser(u.UserId); + } + } + } + } + } + } + catch (Exception ex) + { + result.ReturnValue = -1; + result.ReturnMessage = ex.Message; + } + return result; + } + #endregion RoleGroupsToUsers public method + #region private CheckRoleGroupExists,CheckRoleExists,CheckUsersExists + /// + /// Ellenőrzi, van-e ilyen role group + /// + /// ellenőrizendő role group + private static void CheckRoleGroupExists(string roleGroup) + { + if (!MembershipDBContext.RoleGroups.Any(x => x.Name == roleGroup)) { throw new Exception($"RoleGroup {roleGroup} does not exist!"); } + } + /// + /// Ellenőrzi, van-e ilyen role + /// + /// az ellenőrizendő role + private static void CheckRoleExists(string role) + { + if (!System.Web.Security.Roles.GetAllRoles().ToList().ConvertAll(r => r.ToUpper()).Contains(role.ToUpper())) + { + throw new Exception($"Role {role} does not exist!"); + } + } + /// + /// Ellenőrzi van-e ilyen usernevű user + /// + /// Ellenőrizendő user userneve + private static void CheckUsersExists(string userName) + { + bool exists = false; + foreach (MembershipUser user in System.Web.Security.Membership.GetAllUsers()) + { + if (user.UserName.ToUpper() == userName.ToUpper()) { exists = true; break; } + } + if (!exists) { throw new Exception($"User {userName} does not exist!"); } + } + #endregion private CheckRoleGroupExists,CheckRoleExists,CheckUsersExists + + #region private UpdateRolesForUser + /// + /// Frissíti a megadott felhasználó szerepeit a felhasználó szerepkörei alapján + /// + /// felhasználó UserID-ja + private static void UpdateRolesForUser(Guid userId) + { + MembershipUser user = System.Web.Security.Membership.GetUser(userId, false); + if (user != null) + { + // eltávolítjuk az összes szerepkörét a felhasználónak, majd a felhasználóhoz tartozó UserRoleGroup-okban lévő Roles-okat adjuk hozzá a felhasználóhoz + if (System.Web.Security.Roles.GetRolesForUser(user.UserName).Any()) + { + System.Web.Security.Roles.RemoveUserFromRoles(user.UserName, System.Web.Security.Roles.GetRolesForUser(user.UserName)); + } + foreach (DAL.RoleGroup urg in MembershipDBContext.RoleGroups.Where(x => x.Users.Any(y => y.UserId == userId))) + { + foreach (string roleName in urg.Roles.Select(x => x.Role.RoleName)) + { + if (!System.Web.Security.Roles.IsUserInRole(user.UserName, roleName)) + { + System.Web.Security.Roles.AddUserToRole(user.UserName, roleName); + } + } + } + } + } + #endregion private UpdateRolesForUser + #region private UpdateUsersForUserRoleGroup + /// + /// Frissíti a megadott szerepkörhöz tartozó felhasználók szerepeit a szerepkörök alapján + /// + /// UserRoleGroup Id-ja + private static void UpdateUsersForUserRoleGroup(int userRoleGroupId) + { + DAL.RoleGroup urg = MembershipDBContext.RoleGroups.SingleOrDefault(x => x.Id == userRoleGroupId); + if (urg != null) + { + foreach (Guid userId in urg.Users.Select(x => x.UserId)) + { + UpdateRolesForUser(userId); + } + } + } + #endregion private UpdateUsersForUserRoleGroup + } + #endregion Assign + #region DAL + public static class DAL + { + #region tables + #region table-User + /// + /// DefaultMembershipProvider által létrehozott User tábla. + /// Ha változik az aktuális verzió, és emiatt a tábla szerkezete, akkor ezt módosítani kell. + /// + [Table("Users", Schema = "dbo")] + public partial class User + { + /// + /// Felhasználó egyedi azonosítója. + /// + [Key, DatabaseGenerated(DatabaseGeneratedOption.None)] + public Guid UserId { get; set; } + + /// + /// Melyik alkalmazás felhasználója. + /// + public Guid ApplicationId { get; set; } + + /// + /// Felhasználó neve. + /// + [Required, MaxLength(50)] + public string UserName { get; set; } + + /// + /// Felhasználó névtelenül bejelentjezhet-e. + /// + public bool IsAnonymous { get; set; } + + /// + /// Felhasználó utolsó aktivitésénak időpontja. + /// + public DateTime LastActivityDate { get; set; } + + #region Virtual Collections + + /// + /// A felhasználó szerepkörei. + /// + public virtual ICollection UserRoleGroupUsers { get; set; } + + #endregion Virtual Collections + + } + #endregion table-User + #region table-RoleGroupUser + /// + /// Szerepkörök és felhasználók összerendelése. + /// + [Table(nameof(MembershipContext.RoleGroupUsers), Schema = Constants.SCHEMA_NAME)] + public partial class RoleGroupUser + { + /// + /// Szerepkör egyedi azonosítója. + /// + [Key, Column(Order = 0), DatabaseGenerated(DatabaseGeneratedOption.None)] + public int RoleGroupId { get; set; } + + /// + /// Felhasználó egyedi azonosítója. + /// + [Key, Column(Order = 1), DatabaseGenerated(DatabaseGeneratedOption.None)] + public Guid UserId { get; set; } + + #region Virtual foreignkeys + + [ForeignKey(nameof(RoleGroupId))] + public virtual RoleGroup RoleGroup { get; set; } + + [ForeignKey(nameof(UserId))] + public virtual User User { get; set; } + + #endregion Virtual foreignkeys + } + #endregion table-RoleGroupUser + #region table-RoleGroupRole + /// + /// Szerepkörök és szerepek összerendelése. + /// + [Table(nameof(MembershipContext.RoleGroupRoles), Schema = Constants.SCHEMA_NAME)] + public partial class RoleGroupRole + { + /// + /// Szerepkör egyedi azonosítója. + /// + [Key, Column(Order = 0), DatabaseGenerated(DatabaseGeneratedOption.None)] + public int RoleGroupId { get; set; } + + /// + /// Szerep egyedi azonosítója. + /// + [Key, Column(Order = 1), DatabaseGenerated(DatabaseGeneratedOption.None)] + public Guid RoleId { get; set; } + + #region Virtual foreignkeys + + [ForeignKey(nameof(RoleGroupId))] + public virtual RoleGroup RoleGroup { get; set; } + + [ForeignKey(nameof(RoleId))] + public virtual Role Role { get; set; } + + #endregion Virtual foreignkeys + } + #endregion table-RoleGroupRole + #region table-RoleGroup + /// + /// Szerepkörök táblázata. + /// + [Table(nameof(MembershipContext.RoleGroups), Schema = Constants.SCHEMA_NAME)] + public partial class RoleGroup + { + #region Properties + + /// + /// Szerepkör egyedi azonosítója. + /// + [Key] + public int Id { get; set; } + + /// + /// Szerepkör egyedi megnevezése. + /// + [Required, MaxLength(256), Index(IsUnique = true)] + public string Name { get; set; } + + #endregion Properties + + #region Virtual Collections + + /// + /// A szerepkörhöz ezek a szerepek tartoznak. + /// + public virtual ICollection Roles { get; set; } + + /// + /// A szerepkörhöz ezek a felhasználók tartoznak. + /// + public virtual ICollection Users { get; set; } + + #endregion Virtual Collections + + #region Constructor + public RoleGroup() + { + Roles = new HashSet(); + Users = new HashSet(); + } + #endregion Constructor + } + #endregion table-RoleGroup + #region table-Role + /// + /// DefaultMembershipProvider által létrehozott User tábla. + /// + [Table("Roles", Schema = "dbo")] + public partial class Role + { + /// + /// Szerep egyedi azonosítója. + /// + [Key, DatabaseGenerated(DatabaseGeneratedOption.None)] + public Guid RoleId { get; set; } + + /// + /// Melyik alkalmazás szerepe. + /// + public Guid ApplicationId { get; set; } + + /// + /// Szerep neve. + /// + [Required, MaxLength(256)] + public string RoleName { get; set; } + + /// + /// Alkalmazás rövid leírása. + /// + [MaxLength(256)] + public string Description { get; set; } + } + #endregion table-Role + #region table-Application + /// + /// DefaultMembershipProvider által létrehozott User tábla. + /// + [Table("Applications", Schema = "dbo")] + public partial class Application + { + /// + /// Alkalmazás egyedi azonosítója. + /// + [Key, DatabaseGenerated(DatabaseGeneratedOption.None)] + public Guid ApplicationId { get; set; } + + /// + /// Szerep neve. + /// + [Required, MaxLength(256)] + public string ApplicationName { get; set; } + + /// + /// Alkalmazás rövid leírása. + /// + [MaxLength(256)] + public string Description { get; set; } + } + #endregion table-Application + #region table-SecondaryFunction + /// + /// Lehetséges funkciókat tartalmazó táblázat, mely funkciókhoz + /// tartozhat a másodlagos felhasználó. + /// + [Table(nameof(MembershipContext.SecondaryFunctions), Schema = Constants.SCHEMA_NAME)] + public partial class SecondaryFunction + { + #region Properties + + /// + /// A funkció egyedi azonosítója. + /// + [Key] + public int Id { get; set; } + + /// + /// A funkció egyedi megnevezése. + /// + [Required, MaxLength(30), Index(IsUnique = true)] + public string Name { get; set; } + + #endregion Properties + + #region Virtual Collections + + /// + /// A funkcióhoz ezek a másodlagos felhasználók tartoznak tartoznak. + /// + public virtual ICollection SecondaryUsers { get; set; } + + #endregion Virtual Collections + + #region Constructor + public SecondaryFunction() + { + SecondaryUsers = new HashSet(); + } + #endregion Constructor + } + #endregion table-SecondaryFunction + #region table-SecondaryUser + /// + /// Másodlagos felhasználók adatait tartalmazó táblázat. + /// + [Table(nameof(MembershipContext.SecondaryUsers), Schema = Constants.SCHEMA_NAME)] + public partial class SecondaryUser + { + private const string INDEX_FUNCTION_NAME = "IX_SecondaryUser_SecondaryFunctionId_Name"; + + #region Properties + + /// + /// Másodlagos felhasználó belső egyedi azonosítója. + /// + [Key, Index(IsClustered = false)] + public int Id { get; set; } + + /// + /// Az elsődleges felhasználó egyedi azonosítója a dbo.Users táblából. + /// Ő hozzá tartozik a másodlagos felhasználó. + /// + public Guid UserId { get; set; } + + /// + /// Melyik funkcióhoz tartozik a másodlagos felhasználó. + /// + [Index(INDEX_FUNCTION_NAME, 1, IsUnique = true, IsClustered = true)] + public int SecondaryFunctionId { get; set; } + + /// + /// Másodlagos felhasználó neve. + /// + [Required, MaxLength(255)] + [Index(INDEX_FUNCTION_NAME, 2, IsUnique = true, IsClustered = true)] + public string Name { get; set; } + + /// + /// Másodlagos felhasználó jelszava. + /// + [MaxLength(255)] + public string Password { get; set; } + + /// + /// Másodlagos felhasználó érvényes-e jelenleg. + /// + public bool Active { get; set; } = true; + + #endregion Properties + + #region Virtual foreignkeys + + /// + /// A másodlagos felhasználó ehhez az elsődleges felhasználóhoz tartozik. + /// + [ForeignKey(nameof(UserId))] + public virtual User User { get; set; } + + /// + /// A másodlagos felhasználó ehhez a funkcióhoz tartozik. + /// + [ForeignKey(nameof(SecondaryFunctionId))] + public virtual SecondaryFunction SecondaryFunction { get; set; } + + #endregion Virtual foreignkeys + + #region Constructor + public SecondaryUser() + { + } + #endregion Constructor + + public override string ToString() + { + return String.Concat("{", + nameof(Id), "=", this.Id.ToString(), "; ", + nameof(UserId), "=", this.UserId, "; ", + nameof(SecondaryFunctionId), "=", this.SecondaryFunctionId.ToString(), "; ", + nameof(Name), "=", this.Name, "; ", + nameof(Password), "=", this.Password, "; ", + nameof(Active), "=", this.Active.ToString(), + "}" + ); + } + } + #endregion table-SecondaryUser + #region table-SecondaryLogin + /// + /// Másodlagos felhasználók bejelentkezéseit nyilvántartó táblázat. + /// Egy másodlagos felhasználónak egy bejelentkezése tartozhat egy célhoz. + /// Vagyis a UserID+TargetId együtt egyedi kulcsot alkot. + /// + [Table(nameof(MembershipContext.SecondaryLogins), Schema = Constants.SCHEMA_NAME)] + public partial class SecondaryLogin + { + private const string INDEX_USER_TARGET = "IX_SecondaryLogin_UserId_TargetKey"; + + #region Properties + + /// + /// A bejelentkezés belső egyedi azonosítója. + /// + [Key] + public int Id { get; set; } + + /// + /// Másodlagos felhasználó azonosítója, akinek a nevében történt a bejelentkezés. + /// + [Index(INDEX_USER_TARGET, 1, IsUnique = true)] + public int SecondaryUserId { get; set; } + + /// + /// A bejelentkezéshez tartozó azonosító. Értelmezése: + /// Mi célból történt a bejelentkezés? + /// + [MaxLength(20), Index(INDEX_USER_TARGET, 2, IsUnique = true)] + public string TargetKey { get; set; } + + /// + /// Bejelentkezés időpontja. + /// + public DateTime LoginTime { get; set; } + + /// + /// A legutóbbi aktivitás időpontja. + /// + public DateTime LastActivityTime { get; set; } + + #endregion Properties + + #region Virtual foreignkeys + + /// + /// A másodlagos felhasználóra mutató tulajdonság. + /// + [ForeignKey(nameof(SecondaryUserId))] + public virtual SecondaryUser SecondaryUser { get; set; } + + #endregion Virtual foreignkeys + + public override string ToString() + { + return String.Concat("{", + nameof(Id), "=", this.Id.ToString(), "; ", + nameof(SecondaryUserId), "=", this.SecondaryUserId.ToString(), "; ", + nameof(DAL.SecondaryUser.Name), "=", this.SecondaryUser.Name, "; ", + nameof(TargetKey), "=", this.TargetKey ?? "null", "; ", + nameof(LoginTime), "=", this.LoginTime.ToString("G"), "; ", + nameof(LastActivityTime), "=", this.LastActivityTime.ToString("G"), + "}" + ); + } + + } + #endregion table-SecondaryLogin + #region table-UserSupplement + /// + /// A DefaultMembershipProvider 'User' táblájában nem szabad változtatásokat eszközölni + /// a jövőbeni esetleges Microsoft fejlesztések miatt. + /// Ez a tábla arra való, hogy a felhasználóra vonatkozó egyéb kiegészítő adatokat + /// legyen hol tárolni. + /// + /// + /// Ha nincsenek a felhasználónak kiegészítő adatai akkor nem lesz itt rekordja. + /// + [Table(nameof(MembershipContext.UserSupplements), Schema = Constants.SCHEMA_NAME)] + public partial class UserSupplement + { + #region Properties + + /// + /// A felhasználó egyedi azonosítója a 'User' táblából. + /// Itt is csak 1 db azonosító lehet. + /// + [Key, DatabaseGenerated(DatabaseGeneratedOption.None)] + public Guid UserId { get; set; } + + /// + /// Annak jelzése, hogy a felhasználó ideiglenesen létrehozott felhasználó. + /// Ha igaz, akkor ideiglenes, egyébként hamis. Ha nem létezik a felhasználónak + /// itt rekordja, akkor nem ideiglenes felhasználó. + /// Alapértelmezett érték: true. + /// + public bool IsTemporary { get; set; } = true; + + #endregion Properties + + #region Virtual foreignkeys + + [ForeignKey(nameof(UserId))] + public virtual User User { get; set; } + + #endregion Virtual foreignkeys + } + #endregion table-UserSupplement + #endregion tables + + #region MembershipContext + public class MembershipContext : DbContext + { + #region Constructors + // Your context has been configured to use a 'VrhWebMembership' connection string from your application's + // configuration file (App.config or Web.config). + public MembershipContext(string sqlcs) : base(sqlcs) + { + } + #endregion Constructors + + #region DbSets + + #region !!! A migrációból kivett táblák. Ezeket a DefaultMembershipProvider kezeli és hozza létre. !!! + public virtual DbSet Applications { get; set; } + public virtual DbSet Roles { get; set; } + public virtual DbSet Users { get; set; } + #endregion !!! A migrációból kivett két tábla. Ezeket a DefaultMembershipProvider kezeli és hozza létre. !!! + + // Saját táblák, melyek a Global.SCHEMA_NAME állandó szerinti sémában vannak. + public virtual DbSet RoleGroups { get; set; } + public virtual DbSet RoleGroupRoles { get; set; } + public virtual DbSet RoleGroupUsers { get; set; } + public virtual DbSet SecondaryFunctions { get; set; } + public virtual DbSet SecondaryLogins { get; set; } + public virtual DbSet SecondaryUsers { get; set; } + public virtual DbSet UserSupplements { get; set; } + #endregion DbSets + + #region OnModelCreating + protected override void OnModelCreating(DbModelBuilder modelBuilder) + { + //modelBuilder.HasDefaultSchema("GoodBill"); + + //WA20160124: Sajnos az EF a kötelező idegen kulcsnál alapértelmezésként cascadeDelete értékét true-ra állítja, + // ami sok esetben nem megfelelő (nem is értem, miért true a default :(( ) + // Ahol ez előfordul, ott a ForeignKey-eket itt kell definiálni. + // HasRequired = many oldal virtual property + // WithMany = ha a one oldalon lett definiálva ICollection a many-ra, akkor azt kell ide írni, egyébként üres + // HasForeignKey = many oldalon a foreign key mező + } + #endregion OnModelCreating + } + #endregion MembershipContext + } + #endregion DAL + } +} \ No newline at end of file diff --git a/Vrh.Log4Pro.MaintenanceConsole/Tools - TcpIp.cs b/Vrh.Log4Pro.MaintenanceConsole/Tools - TcpIp.cs new file mode 100644 index 0000000..cf0a2de --- /dev/null +++ b/Vrh.Log4Pro.MaintenanceConsole/Tools - TcpIp.cs @@ -0,0 +1,1034 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using System.Linq; +using System.Net; +using System.Net.NetworkInformation; +using System.Net.Sockets; +using System.Text; +using System.Threading.Tasks; +using System.Timers; +using System.Xml.Linq; + +namespace Vrh.Log4Pro.MaintenanceConsole.ToolsNS +{ + /// + /// A pinger objektum ping ciklusokat indít (egy ping ciklusban több ping kérés van/lehet), és ezek eredményét + /// tárolja tömörített formátumban elsősorban abból a célból, hogy a tárolt adatok alapján trend diagramot lehessen + /// készíteni a kapcsolat minőségének kimutatására. + /// + public class Pinger : IDisposable + { + /// + /// Egy Pinger objektum létrehozása xml-ből + /// + /// a ping célállomása + /// a pinger konfigurációs paramétereit tartalmazó xml struktúra + public Pinger(string hostNameOrAddress, XElement pingerconfig) : this(hostNameOrAddress, new PingerConfig(pingerconfig)) { } + + /// + /// Egy Pinger objektum létrehozása PrinterConfig osztályból + /// + /// a ping célállomása + /// a konfigurációt tartalmazó pinger objektum + private Pinger(string hostNameOrAddress, PingerConfig pc) + { + this.HostNameOrAddress = hostNameOrAddress; + this.History = new PingHistory(hostNameOrAddress, pc); + this.PingTimeout = pc.pingtimeout; + this.PingCycleFrequency = pc.pingcyclefrequency; + this.PingCycleNumberOfPackages = pc.pingcyclenumofpackages; + this.PingerActiveLength = pc.pingeractivlength; + this.Configuration = pc; + if (pc.RoundTripTimeLimits!=null) + { + Pinger.RoundTripTimeLimits = pc.RoundTripTimeLimits; + Pinger.MaxRoundTripTimeoutCategory = pc.RoundTripTimeLimits.Last(); + Pinger.RoundTripTimeyCategoryLimits = pc.RoundTripTimeyCategoryLimits; + } + } + /// + /// A maximális ping timeout kategória értéke + /// + public static int MaxRoundTripTimeoutCategory = 5000; + + /// + /// A FINOM válaszidő kategóriákat tartalmazza; egy válasz az i. válaszidő kategóriába tartozik, ha a pontos válaszidő nagyobb, vagy egyenlő, + /// mint az i. elem értéke, de kisebb, mint az i+1. elem értéke.A sor első elemének értéke mindig 0!!!! + /// Ha a sor értékei: 0:0,1:100,2:200,3:300,4:400,5:500, a pontos válaszidő 350, akkor ez a 2. kategóriába tartozik, ha pontos válaszidő. + /// + public static List RoundTripTimeLimits = new List { 0, 25, 50, 75, 100, 150, 200, 250, 300, 400, 500, 750, 1000, 1250, 1500, 1750, 2000, 2500, 3000, 3500, 4000, 4500, Pinger.MaxRoundTripTimeoutCategory, }; + + /// + /// A DURVA válaszidő kategóriákat tartalmazza; egy válasz az i. válaszidő kategóriába tartozik, ha a pontos válaszidő nagyobb, vagy egyenlő, + /// mint az i. elem értéke, de kisebb, mint az i+1. elem értéke.A sor első elemének értéke mindig 0!!!! + /// Ha a sor értékei: 0:0,1:100,2:200,3:300,4:400,5:500, a pontos válaszidő 350, akkor ez a 2. kategóriába tartozik, ha pontos válaszidő. + /// + public static List RoundTripTimeyCategoryLimits = new List { 0, 50, 250, 750, }; + + /// + /// A pinger indítása/újraindítása; elindítja a ping ciklus időzítőt, és elkezdi/folytatja a ping státusz adatok letárolását + /// + /// pinger konfig xml struktúra, amely + /// (jellemzően újraindítás esetén) a Pinger részleges átkonfigurálását teszi lehetővé + public void Start(XElement pingerconfig = null) + { + lock (pingcyclelocker) + { + CycleTimerStop(); + Reconfigure(pingerconfig); + CycleTimerStart(); + + if (this.PingerActiveLength > 0) + { + AutoStopTimerStop(); + AutoStopTimerStart(); + } + } + } + + /// + /// A pinger leállítása; kikapcsolja a ping ciklus időzítőt, és leállítja a ping státusz adatok letárolását + /// + public void Stop() + { + CycleTimerStop(); + } + + /// + /// A Pinge objektum átkonfigurálás a a megadott xml struktúra alapján + /// + /// + private void Reconfigure(XElement pingerconfig = null) + { + lock (pingcyclelocker) + { + if (pingerconfig != null) + { + var pc = new PingerConfig(pingerconfig); + this.PingTimeout = pc.pingtimeout; + this.PingCycleFrequency = pc.pingcyclefrequency; + this.PingCycleNumberOfPackages = pc.pingcyclenumofpackages; + this.PingerActiveLength = pc.pingeractivlength; + this.History.SetHistoryLength(pc.pingerhistorylength); + if (pc.RoundTripTimeLimits != null) + { + Pinger.RoundTripTimeLimits = pc.RoundTripTimeLimits; + Pinger.MaxRoundTripTimeoutCategory = pc.RoundTripTimeLimits.Last(); + Pinger.RoundTripTimeyCategoryLimits = pc.RoundTripTimeyCategoryLimits; + } + } + } + } + + /// + /// A pinger autostop lejártakor végrehajtandó metódus + /// + /// + /// + private void AutoStop(Object source, ElapsedEventArgs e) { CycleTimerStop(); } + + private void CycleTimerStop() + { + lock (pingcyclelocker) { if (this.CycleTimer != null) { this.CycleTimer.Enabled = false; } this.Operating = false; } + } + private void CycleTimerStart() + { + lock (pingcyclelocker) + { + if (this.CycleTimer == null) { this.CycleTimer = new System.Timers.Timer(); this.CycleTimer.Elapsed += StartPingCycle; this.CycleTimer.AutoReset = true; } + this.CycleTimer.Interval = this.PingCycleFrequency; + this.CycleTimer.Enabled = true; + this.Operating = true; + } + } + private void AutoStopTimerStop() + { + lock (pingcyclelocker) + { + if (this.AutoStopTimer != null) { this.AutoStopTimer.Enabled = false; } + } + } + private void AutoStopTimerStart() + { + lock (pingcyclelocker) + { + if (this.AutoStopTimer == null) { this.AutoStopTimer = new System.Timers.Timer(); this.AutoStopTimer.Elapsed += AutoStop; this.AutoStopTimer.AutoReset = false; } + this.AutoStopTimer.Interval = this.PingerActiveLength; + this.AutoStopTimer.Enabled = true; + } + } + /// + /// Dispose + /// + public void Dispose() + { + Stop(); + if (this.CycleTimer != null) { this.CycleTimer.Dispose(); this.CycleTimer = null; } + if (this.AutoStopTimer != null) { this.AutoStopTimer.Dispose(); this.AutoStopTimer = null; } + this.History.Dispose(); + } + + /// + /// Visszadja a history listát + /// + /// + public Pinger.PingHistory GetHistory() + { + lock (pingcyclelocker) { this.History.PingerState = this.CycleTimer != null && this.CycleTimer.Enabled ? PingerStatus.Operating : PingerStatus.Still; return this.History; } + } + + #region public fields + /// + /// A ping célállomása + /// + public string HostNameOrAddress; + /// + /// true: a pingcycle timer működik, a pingelés folyamataos + /// false: a pingcycle timer NEM működik, a pingelés áll + /// + public bool Operating; + /// + /// Egy ciklusban kiadott ping kérések száma. + /// + public PingerConfig Configuration; + #endregion public fields + + #region private metódusok + /// + /// A ping ciklus időzítés lejártakor elindított metódus, ami végrehajt egy ping ciklust és eredményét bedolgozza a PingStateQueue sorba + /// + /// + /// + private void StartPingCycle(Object source, ElapsedEventArgs e) + { + lock (pingcyclelocker) + { + this.CycleTimer.Enabled = false; // kikapcsoljuk a timer-t a ciklus végrehajtása alatt + var newpc = new PingCycle(this.HostNameOrAddress, this.PingCycleNumberOfPackages, this.PingTimeout).Execute(); + this.History.Merge(newpc); + this.CycleTimer.Interval = this.PingCycleFrequency;// ha esetleg közben újrakonfigurálták.... + this.CycleTimer.Enabled = true; // a ciklus végrehajtása után ismét elindítjuk az időzítőt + } + } + #endregion private metódusok + + #region private fields + /// + /// Az egyes ping kérések maximális timeout-ja (millisecundum) + /// + private int PingTimeout; + /// + /// A ping ciklus befejeződése után ennyi idővel indítja a következőt (másodpercben) + /// + private int PingCycleFrequency; + /// + /// A ping vizsgálat teljes időtartama; Ennyi idő eltelte után nem indít több több ping ciklust. + /// Érték percben. Ha az érték 0, akkor végtelen hosszú időn keresztül indít ping ciklusokat. + /// + private int PingerActiveLength; + /// + /// Egy ciklusban kiadott ping kérések száma. + /// + private int PingCycleNumberOfPackages; + /// + /// A ping ciklusok keveredését megakadályozó locker objektum + /// + private object pingcyclelocker = new object(); + /// + /// A Pinger működési periódusának hossza (az autostop timer kikapcsolási ideje) (perc) + /// + private System.Timers.Timer AutoStopTimer; + /// + /// A Ping ciklus timere + /// + private System.Timers.Timer CycleTimer; + /// + /// Ping history + /// + private PingHistory History; + #endregion private fields + + #region PingerConfig class + /// + /// PingerConfig osztály + /// + public class PingerConfig + { + /// + /// példány létrehozása xml struktúra alapján + /// + /// + public PingerConfig(XElement pingerconfig) + { + if (pingerconfig != null) + { + var _pingtimeout = GetPositiveIntFromXml(PINGTIMEOUT, pingerconfig); + var _pingcyclefrequency = GetPositiveIntFromXml(PINGCYCLEFREQUENCY, pingerconfig); + var _pingcyclenumofpackages = GetPositiveIntFromXml(PINGCYCLENUMOFPACKAGES, pingerconfig); + var _pingerlifetime = GetPositiveIntFromXml(PINGERACTIVELENGTHTOSTOPPERIOD, pingerconfig); + var _pingerhistorylength = GetPositiveIntFromXml(PINGERHISTORYLENGTH, pingerconfig); + var _optimizehistorylength = pingerconfig.Element(OPTIMIZEHISTORYLENGTH)?.Value; ; + var _roundtriptimelimits = pingerconfig.Element(ROUNDTRIPTIMELIMITS)?.Value; + var _roundtriptimecategorylimits = pingerconfig.Element(ROUNDTRIPTIMECATEGORYLIMITS)?.Value; + SetValues(_pingtimeout, _pingcyclefrequency, _pingcyclenumofpackages, _pingerlifetime, _pingerhistorylength, _roundtriptimelimits, _roundtriptimecategorylimits,_optimizehistorylength); + } + else { SetValues(); } + } + + /// + /// Példány létrehozása paraméterek alapján; a konstruktor célja a mértékegységek és a default értékek kezelése + /// + /// millisecond + /// seconds + /// pcs + /// minutes + /// minutes + public PingerConfig(int pingtimeout = 0, int pingcyclefrequency = 0, int pingcyclenumofpackages = 0, int pingeractivelength = 0, int pingerhistorylength = 0,string rttlimits=null, string rttcatlimits=null,string optimizehlength=null) + { + SetValues(pingtimeout, pingcyclefrequency, pingcyclenumofpackages, pingeractivelength, pingerhistorylength, rttlimits , rttcatlimits, optimizehlength); + } + + /// + /// Beállítja a field-ek értékét a megfelelő mértékegységben a paraméterek, illetve az alapértelmezések szerint + /// + /// millisecond + /// seconds + /// pcs + /// minutes + /// minutes + private void SetValues(int pingtimeout = 0, int pingcyclefrequency = 0, int pingcyclenumofpackages = 0, int pingeractivelength = 0, int pingerhistorylength = 0, string rttlimits = null, string rttcatlimits = null,string optimizehlength=null) + { + this.pingcyclenumofpackages = pingcyclenumofpackages <= 0 ? PingerConfig.DEFAULT_PINGCYCLENUMOFPACKAGES : pingcyclenumofpackages; + this.pingeractivlength = (pingeractivelength <= 0 ? PingerConfig.DEFAULT_PINGERACTIVELENGTH : pingeractivelength) * 60 * 1000; + this.pingerhistorylength = (pingerhistorylength <= 0 ? PingerConfig.DEFAULT_PINGERHISTORYLENGTH : pingerhistorylength) * 60 * 1000; + bool optimizehlengthbool=true; + if (optimizehlength != null) { optimizehlengthbool = bool.TryParse(optimizehlength.ToLower(), out optimizehlengthbool) ? optimizehlengthbool : true; } + this.optimizehistorylength = optimizehlengthbool; + + try + { + // ha a megadott sor nem ok, akkor nem változtat a default-on + List rttl = rttlimits.Split(new char[] { ' ', ',', ';', '/', }, StringSplitOptions.RemoveEmptyEntries).ToList().Select(x => int.Parse(x)).ToList(); + if (rttl.Count <4) { throw new Exception(); } + if (rttl.ElementAt(0) != 0) { throw new Exception(); } + int lastelementvalue = -1; + for(var i=0;i rttcl = rttcatlimits.Split(new char[] { ' ', ',', ';', '/', }, StringSplitOptions.RemoveEmptyEntries).ToList().Select(x => int.Parse(x)).ToList(); + if (rttcl.Count != 4) { throw new Exception(); } + if (rttcl.ElementAt(0) != 0) { throw new Exception(); } + lastelementvalue = -1; + for (var i = 0; i < rttcl.Count; i++) { if (rttcl.ElementAt(i) <= lastelementvalue) { throw new Exception(); } lastelementvalue = rttcl.ElementAt(i); } + + this.RoundTripTimeLimits = rttl; + this.RoundTripTimeyCategoryLimits = rttcl; + } + catch + { + this.RoundTripTimeLimits = Pinger.RoundTripTimeLimits; + this.RoundTripTimeyCategoryLimits = Pinger.RoundTripTimeyCategoryLimits; + } + this.pingtimeout = pingtimeout <= 0 ? rttlimits.Last() : pingtimeout; + this.pingcyclefrequency = pingcyclefrequency * 1000; + if (this.pingcyclefrequency < this.pingtimeout) { this.pingcyclefrequency = this.pingtimeout; } + } + + /// + /// Egy int értéket kiemel a megadott xml struktúrából, ha nincs ott a keresett érték, + /// vagy nem integer, vagy nem pozitív, akkor az alapértelmezést adja vissza + /// + /// az xml struktúrában a keresett elem neve + /// az xml struktúra + /// az alapértelmezett érték + /// + private static int GetPositiveIntFromXml(string xname, XElement pingerconfig, int defaultvalue=0) + { + string valstr = pingerconfig?.Element(XName.Get(xname))?.Value; + int val = defaultvalue; + if (valstr != null && int.TryParse(valstr, out int val1) && val1 > 0) { val = val1; } + return val; + } + + public List RoundTripTimeLimits=null; + public List RoundTripTimeyCategoryLimits=null; + public int pingtimeout; + public int pingcyclefrequency; + public int pingcyclenumofpackages; + public int pingeractivlength; + public int pingerhistorylength; + public bool optimizehistorylength; + + const string PINGTIMEOUT = "PingTimeout"; + const string PINGCYCLEFREQUENCY = "PingCycleFrequency"; + const string PINGCYCLENUMOFPACKAGES = "PingCycleNumOfPackages"; + const string PINGERACTIVELENGTHTOSTOPPERIOD = "PingerActiveLength"; + const string PINGERHISTORYLENGTH = "PingerHistoryLength"; + const string OPTIMIZEHISTORYLENGTH = "OptimizeHistoryLength"; + const string ROUNDTRIPTIMELIMITS = "RoundTripTimeLimits"; + const string ROUNDTRIPTIMECATEGORYLIMITS = "RoundTripCategoryLimits"; + public const int DEFAULT_PINGTIMEOUT = 0; + public const int DEFAULT_PINGCYCLENUMOFPACKAGES = 4; + public const int DEFAULT_PINGERACTIVELENGTH = 60; + public const int DEFAULT_PINGERHISTORYLENGTH = 60; + } + #endregion PingerConfig class + + #region PingHistory class + /// + /// Ping history struktúra + /// + public class PingHistory : IDisposable + { + /// + /// Ping állapot-sor. Minden eleme egy kezdő-időponttól fogva a következő elem kezdőidopontjáig fennálló állapotot ír le. + /// Ha az új státusz állapot-ban a RoundtripTimeCategory vagy StatusCategory értéke a sorban levő legutolsó elemben levő értékekhez képes + /// KÜLÖNBÖZIK, akkor Új elem kerül be a sorba; + /// AZONOS, akkor a legutolsó elemben a PackagesSent és PackagesLost értékekhez hozzáadódik az új elemben levő megfelelő érték, de új elem nem kerül hozzáadásra + /// + public List PingStateQueue; + /// + /// A PingStateQueue utolsó eleme + /// + private PingCycle LastPingCycle; + + /// + /// A tárolt history hossza percben + /// + public int Length; + + /// + /// A ping ciklusok gyakorisága + /// + public int PingCycleFrequency; + + /// + /// Az érvényes configuráció + /// + public PingerConfig PingerConfig; + + public string HostNameOrAddress; + public PingerStatus PingerState = PingerStatus.Still; + public DateTime StartTime; + + private object historylocker = new object(); + + public PingHistory(string hostnameoraddress, PingerConfig pingerconfig) + { + this.HostNameOrAddress = hostnameoraddress; + this.PingStateQueue = new List(); + this.LastPingCycle = null; + this.Length = pingerconfig.pingerhistorylength; + this.PingCycleFrequency = pingerconfig.pingcyclefrequency; + this.PingerConfig = pingerconfig; + } + public PingHistory(PingHistory ph) + { + this.HostNameOrAddress = ph.HostNameOrAddress; + this.PingStateQueue = ph.PingStateQueue.Select(x=>new PingCycle(x)).ToList(); + this.LastPingCycle = ph.LastPingCycle; + this.Length = ph.Length; + this.PingCycleFrequency = ph.PingCycleFrequency; + this.PingerConfig = ph.PingerConfig; + } + + public void Dispose() + { + this.PingStateQueue = null; + this.LastPingCycle = null; + } + /// + /// A PrintCycle beillesztése a sor végére, vagy "hozzáadása" az utolsó elemhez + /// + /// + public void Merge(PingCycle newpc) + { + lock (historylocker) + { + if (!this.PingerConfig.optimizehistorylength || (this.LastPingCycle?.isDifferent(newpc) ?? true)) { this.PingStateQueue.Add(newpc); this.LastPingCycle = newpc; } + else + { + var totalrtt = ((this.LastPingCycle.RoundtripTimeAverage * this.LastPingCycle.NumberOfCycles) + newpc.RoundtripTimeAverage); + this.LastPingCycle.NumberOfCycles++; + this.LastPingCycle.RoundtripTimeAverage = totalrtt / this.LastPingCycle.NumberOfCycles; + this.LastPingCycle.PackagesSent += newpc.PackagesSent; + this.LastPingCycle.PackagesLost += newpc.PackagesLost; + this.LastPingCycle.PackagesSentCategory = this.LastPingCycle.GetLostPackageCategory(); + this.LastPingCycle.LastTimestamp = newpc.StartTimestamp; + if (newpc.RoundtripTimeMax != -1 && this.LastPingCycle.RoundtripTimeMax != -1) + { + if (this.LastPingCycle.RoundtripTimeMax < newpc.RoundtripTimeMax) { this.LastPingCycle.RoundtripTimeMax = newpc.RoundtripTimeMax; } + if (this.LastPingCycle.RoundtripTimeMin > newpc.RoundtripTimeMin) { this.LastPingCycle.RoundtripTimeMin = newpc.RoundtripTimeMin; } + } + } + + var borderts = newpc.StartTimestamp.AddMilliseconds(-1 * this.Length); + this.PingStateQueue.RemoveAll(x => x.LastTimestamp <= borderts); + var firstelement = this.PingStateQueue.FirstOrDefault(); + if (firstelement != null && firstelement.StartTimestamp < borderts) + { + var partiallength = (firstelement.LastTimestamp - borderts).TotalMilliseconds; + var fulllength = (firstelement.LastTimestamp - firstelement.StartTimestamp).TotalMilliseconds; + firstelement.PackagesSent = (int)((double)firstelement.PackagesSent * partiallength / fulllength); + firstelement.PackagesLost = (int)((double)firstelement.PackagesLost * partiallength / fulllength); + firstelement.NumberOfCycles = (int)((double)firstelement.NumberOfCycles * partiallength / fulllength); + if (firstelement.NumberOfCycles == 0 || firstelement.PackagesSent == 0) { this.PingStateQueue.Remove(firstelement); firstelement = this.PingStateQueue.FirstOrDefault(); } + + firstelement.PackagesSentCategory = firstelement.GetLostPackageCategory(); + firstelement.StartTimestamp = borderts; + } + StartTime = firstelement?.StartTimestamp ?? DateTime.MaxValue; + } + } + + /// + /// Beállítja a history hosszát + /// + /// + public void SetHistoryLength(int pingerhistoryperiod) + { + lock (historylocker) { this.Length = pingerhistoryperiod; } + } + } + #endregion PingHistory class + + #region PingCycle class + /// + /// A ping history-ban szereplő elemek típusa + /// + public class PingCycle + { + /// + /// Ping ciklus objektum létrehozása + /// + /// a pingek célja + /// ennyi ping-et kell végrehajtani + /// ennyi az egyes ping-ek timeout-ja + public PingCycle(string hostnameoraddress, int numofpings, int pingtimeout) + { + this.HostNameOrAddress = hostnameoraddress; + this.PackagesSent = numofpings; + this.PingTimeout = pingtimeout; + this.PackagesLost = 0; + this.PackagesSentCategory = LostPackageCategory.Excellent; + this.NumberOfCycles = 1; + this.StatusCategory = IPStatusCategory.NotExecuted; + this.RoundtripTimeAverage = 0; + this.RoundtripTimeMin = -1; + this.RoundtripTimeMax = -1; + } + public PingCycle(PingCycle pc) + { + this.HostNameOrAddress = pc.HostNameOrAddress; + this.PackagesSent = pc.PackagesSent; + this.PingTimeout = pc.PingTimeout; + this.PackagesLost = pc.PackagesLost; + this.PackagesSentCategory = pc.PackagesSentCategory; + this.NumberOfCycles = pc.NumberOfCycles; + this.StatusCategory = pc.StatusCategory; + this.RoundtripTime = pc.RoundtripTime; + this.RoundtripTimeAverage = pc.RoundtripTimeAverage; + this.RoundtripTimeMax = pc.RoundtripTimeMax; + this.RoundtripTimeMin= pc.RoundtripTimeMin; + this.RoundtripTimeCategory = pc.RoundtripTimeCategory; + } + + #region public fields,enums + /// + /// A Ping állapot ezen időpillanattól kezdődően állt/áll fenn + /// + public DateTime StartTimestamp; + /// + /// A Ping állapot ezen időpillanattól kezdődően állt/áll fenn + /// + public DateTime LastTimestamp; + /// + /// Az állapot ilyen válaszidőt jelent (valójában ez is egy kategória, de egy konkrét idő érték jellemzi) + /// + public int RoundtripTime; + + /// + /// A ping ciklusban végrehajtott ping-ek maximális válaszideje + /// + public int RoundtripTimeMax=-1; + /// + /// A ping ciklusban végrehajtott ping-ek minimális válaszideje + /// + public int RoundtripTimeMin=-1; + + /// + /// A pontos válaszidők átlaga + /// + public int RoundtripTimeAverage; + + /// + /// Az állapot ilyen válaszidő kategóriát jelent + /// + public RoundTripTimeCategory RoundtripTimeCategory; + /// + /// Az állapot ilyen IPStatus kategóriát jelent + /// + public IPStatusCategory StatusCategory; + /// + /// Ebben a státus állapotban ennyi csomag került kiküldésre + /// + public int PackagesSent; + /// + /// Ebben a státus állapotban ennyi csomag veszett el nem Success + /// + public int PackagesLost; + /// + /// Ebben a státus állapotban az elveszett csomagokra utaló státusz + /// + public LostPackageCategory PackagesSentCategory; + /// + /// A ping ciklusok száma ebben az egységben + /// + public int NumberOfCycles; + + /// + /// Válasz státusz kategóriák; minél nagyobb az érték, annál kevesebbet tudunk a hiba okáról. + /// + public enum IPStatusCategory { Success = 0, TimedOut = 10, PortUnreachable = 20, HostUnreachable = 30, NetworkUnreachable = 40, Failed = 50, NotExecuted = 100, } + public enum LostPackageCategory { Excellent = 0, Good = 1, Acceptable = 2, Bad = 3, } + public enum RoundTripTimeCategory { Q1 = 0, Q2 = 1, Q3 = 2, Q4 = 3, } + #endregion public fields,enums + + #region isDifferent + /// + /// Eldönti, hogy a két objektum azonosnak tekinthető-e, vagy sem + /// + /// + /// + public bool isDifferent(PingCycle pc) + { + return this.StatusCategory != pc.StatusCategory + || this.RoundtripTime != pc.RoundtripTime; + } + #endregion isDifferent + + #region Execute + /// + /// Egy ping ciklus végrehajtása; + /// + /// + /// StatusCategory: értéke NotExecuted értéktől különbözni fog. + /// StartTimestamp: értéke a hívás időpillanata lesz. + /// PackagesLost: a nem Success-sel visszatérő ping-ek száma + /// RoundtripTimeCategory: a válaszidő kategória értéke + /// + public PingCycle Execute() + { + this.StartTimestamp = DateTime.Now; + this.LastTimestamp = this.StartTimestamp; + PingReply pr; + for (var i = 0; i < this.PackagesSent; i++) + { + pr = null; + try { pr = PingTool.Ping(this.HostNameOrAddress, (int)PingTimeout); }//egy ping kérés feladása + catch { } + AddResponse(pr, i + 1);//a ping válasz "bedolgozása" a pingciklus-állapotba + } + + this.PackagesSentCategory = GetLostPackageCategory(); + this.RoundtripTime = Pinger.RoundTripTimeLimits.LastOrDefault(x => x <= this.RoundtripTimeAverage); + var RoundTripTimeyCategoryValue = Pinger.RoundTripTimeyCategoryLimits.LastOrDefault(x => x < this.RoundtripTimeAverage); + var RoundTripTimeyCategoryIndex = Pinger.RoundTripTimeyCategoryLimits.FindIndex(x => x == RoundTripTimeyCategoryValue); + this.RoundtripTimeCategory = RoundTripTimeyCategoryIndex == 0 ? RoundTripTimeCategory.Q1 + : RoundTripTimeyCategoryIndex == 1 ? RoundTripTimeCategory.Q2 + : RoundTripTimeyCategoryIndex == 2 ? RoundTripTimeCategory.Q3 + : RoundTripTimeCategory.Q4; + return this; + } + #endregion Execute + + #region private elemek + /// + /// a ping célcíme + /// + private string HostNameOrAddress; + /// + /// Az egyes ping kérések timeout-ja + /// + private int PingTimeout; + /// + /// A ping válasz bedolgozása a pingciklus státuszba + /// + /// a ping válasza + /// a ping kérés indexe; 1,2,.... + private void AddResponse(PingReply pr, int i) + { + var ipsCat = GetIPStatusCategory(pr); + if (ipsCat==IPStatusCategory.Success) + { + int prroundtriptime = pr.RoundtripTime >= int.MaxValue ? int.MaxValue : (int)pr.RoundtripTime; + this.RoundtripTimeMin = prroundtriptime < this.RoundtripTimeMin || this.RoundtripTimeMin ==-1 ? prroundtriptime : this.RoundtripTimeMin; + this.RoundtripTimeMax = prroundtriptime > this.RoundtripTimeMax || this.RoundtripTimeMax == -1 ? prroundtriptime : this.RoundtripTimeMax; + this.RoundtripTimeAverage = ((i - 1) * this.RoundtripTimeAverage + prroundtriptime) / i;// az átlagos válaszidőt tárolja + } + else { this.PackagesLost++; } + if (ipsCat < this.StatusCategory) { this.StatusCategory = ipsCat; }// a legjobb státuszt tárolja + } + + /// + /// Visszaadja az elveszett és összes csomagok száma alapján a lostpackagecategory értéket + /// + /// az elveszett csomagok száma + /// az összes csomagok száma + /// + public LostPackageCategory GetLostPackageCategory() + { + double packagelostratio = (double)this.PackagesLost / (double)this.PackagesSent; + return packagelostratio == 0 ? PingCycle.LostPackageCategory.Excellent + : packagelostratio < 0.1 ? PingCycle.LostPackageCategory.Good + : packagelostratio < 0.3 ? PingCycle.LostPackageCategory.Acceptable + : PingCycle.LostPackageCategory.Bad; + } + /// + /// Visszaadja, hogy a PingReply adat alapján a válasz melyik státusz kategóriába tartozik + /// + /// + /// + private static IPStatusCategory GetIPStatusCategory(PingReply pr) + { + //if (new Random().Next(0, 9) < 3) { return IPStatusCategory.Failed; } + if (pr == null) { return IPStatusCategory.Failed; } + switch (pr.Status) + { + case IPStatus.Success: return IPStatusCategory.Success;//Success = 0,The ICMP echo request succeeded; an ICMP echo reply was received. When you get this status code, the other System.Net.NetworkInformation.PingReply properties contain valid data. + + case IPStatus.DestinationNetworkUnreachable: //DestinationNetworkUnreachable = 11002,The ICMP echo request failed because the network that contains the destination computer is not reachable. + return IPStatusCategory.NetworkUnreachable; + + case IPStatus.BadRoute: //BadRoute = 11012,The ICMP echo request failed because there is no valid route between the source and destination computers. + case IPStatus.DestinationUnreachable: //DestinationUnreachable = 11040,The ICMP echo request failed because the destination computer that is specified in an ICMP echo message is not reachable; the exact cause of problem is unknown. + case IPStatus.DestinationHostUnreachable: //DestinationHostUnreachable = 11003,The ICMP echo request failed because the destination computer is not reachable. + return IPStatusCategory.HostUnreachable; + + case IPStatus.TtlReassemblyTimeExceeded://TtlReassemblyTimeExceeded = 11014,The ICMP echo request failed because the packet was divided into fragments for transmission and all of the fragments were not received within the time allottedfor reassembly. RFC 2460 (available at www.ietf.org) specifies 60 seconds as the time limit within which all packet fragments must be received. + case IPStatus.TtlExpired://TtlExpired = 11013,The ICMP echo request failed because its Time to Live (TTL) value reached zero, causing the forwarding node (router or gateway) to discard the packet. + case IPStatus.TimeExceeded: //TimeExceeded = 11041,The ICMP echo request failed because its Time to Live (TTL) value reached zero, causing the forwarding node (router or gateway) to discard the packet. + case IPStatus.TimedOut: //TimedOut = 11010,The ICMP echo Reply was not received within the allotted time. The default time allowed for replies is 5 seconds. You can change this value using theOverload:System.Net.NetworkInformation.Ping.Send or Overload:System.Net.NetworkInformation.Ping.SendAsync methods that take a timeout parameter. + return IPStatusCategory.TimedOut; + + //DestinationProhibited = 11004,The ICMPv6 echo request failed because contact with the destination computer is administratively prohibited. This value applies only to IPv6. + case IPStatus.DestinationProtocolUnreachable://DestinationProtocolUnreachable = 11004, The ICMP echo request failed because the destination computer that is specified in an ICMP echo message is not reachable, because it does not support the packet'sprotocol. This value applies only to IPv4. This value is described in IETF RFC 1812 as Communication Administratively Prohibited. + case IPStatus.DestinationPortUnreachable: //DestinationPortUnreachable = 11005,Summary: The ICMP echo request failed because the port on the destination computer is not available. + case IPStatus.Unknown://Unknown = -1,The ICMP echo request failed for an unknown reason. + case IPStatus.NoResources: //NoResources = 11006,Summary: The ICMP echo request failed because of insufficient network resources. + case IPStatus.BadOption: //BadOption = 11007,The ICMP echo request failed because it contains an invalid option. + case IPStatus.HardwareError: //HardwareError = 11008,The ICMP echo request failed because of a hardware error. + case IPStatus.PacketTooBig: //PacketTooBig = 11009,The ICMP echo request failed because the packet containing the request is larger than the maximum transmission unit (MTU) of a node (router or gateway) located between the source and destination. The MTU defines the maximum size of a transmittable packet. + case IPStatus.ParameterProblem: //ParameterProblem = 11015,The ICMP echo request failed because a node (router or gateway) encountered problems while processing the packet header. This is the status if, for example, the header contains invalid field data or an unrecognized option. + case IPStatus.SourceQuench: //SourceQuench = 11016,The ICMP echo request failed because the packet was discarded. This occurs when the source computer's output queue has insufficient storage space, or when packetsarrive at the destination too quickly to be processed. + case IPStatus.BadDestination: //BadDestination = 11018,The ICMP echo request failed because the destination IP address cannot receive ICMP echo requests or should never appear in the destination address field ofany IP datagram. For example, calling Overload:System.Net.NetworkInformation.Ping.Send and specifying IP address "000.0.0.0" returns this status. + case IPStatus.BadHeader: //BadHeader = 11042,The ICMP echo request failed because the header is invalid. + case IPStatus.UnrecognizedNextHeader://UnrecognizedNextHeader = 11043,The ICMP echo request failed because the Next Header field does not contain a recognized value. The Next Header field indicates the extension header type (ifpresent) or the protocol above the IP layer, for example, TCP or UDP. + case IPStatus.IcmpError: //IcmpError = 11044,The ICMP echo request failed because of an ICMP protocol error. + case IPStatus.DestinationScopeMismatch://DestinationScopeMismatch = 11045, The ICMP echo request failed because the source address and destination address that are specified in an ICMP echo message are not in the same scope. This istypically caused by a router forwarding a packet using an interface that is outside the scope of the source address. Address scopes (link-local, site-local, andglobal scope) determine where on the network an address is valid. } + return IPStatusCategory.Failed; + } + return IPStatusCategory.Failed; + } + #endregion private elemek + } + #endregion PingCycle class + + public enum PingerStatus { NotExisting = 2, Still = 1, Operating = 0, } + } + + /// + /// TCP Ping eszközök + /// + public static class PingTool + { + /// + /// Elérhető e az állomás? + /// + /// Ip, vagy host név + /// timeout + /// + public static bool IsHostAccessible(string hostNameOrAddress, int timeOut = 1000) + { + PingReply reply = Ping(hostNameOrAddress, timeOut); + return reply.Status == IPStatus.Success; + } + + /// + /// Visszadja az állomás ping idejét (millisecundum) + /// + /// Ip, vagy host név + /// timeout + /// + public static long GetPingTime(string hostNameOrAddress, int timeOut = 1000) + { + PingReply reply = Ping(hostNameOrAddress, timeOut); + return reply.RoundtripTime; + } + + /// + /// Visszadja az állomás ping szerinti státuszát (IPStatus) + /// + /// Ip, vagy host név + /// timeout + /// + + /// + public static IPStatus GetPingStatus(string hostNameOrAddress, int timeOut = 1000) + { + PingReply reply = Ping(hostNameOrAddress, timeOut); + return reply.Status; + } + + /// + /// Ping + /// + /// Ip, vagy host név + /// timeout + /// PingReply + public static PingReply Ping(string hostNameOrAddress, int timeOut = 1000) + { + Ping ping = new Ping(); + return ping.Send(hostNameOrAddress, timeOut); + } + + /// + /// Ping specifikált adatokkal + /// + /// Ip, vagy host név + /// timeout + /// ping adatok + /// PingReply + public static PingReply Ping(string hostNameOrAddress, int timeOut, byte[] buffer) + { + if (buffer.Length > 65500) + { + throw new ArgumentException("Ping data too big! Maximum 65500 bytes allowed!"); + } + Ping ping = new Ping(); + return ping.Send(hostNameOrAddress, timeOut, buffer); + } + + /// + /// Ping specifikált adatokkal és beállításokkal (PingOptions) + /// + /// Ip, vagy host név + /// timeout + /// ping adatok + /// ping beállítások + /// PingReply + public static PingReply Ping(string hostNameOrAddress, int timeOut, byte[] buffer, PingOptions options) + { + if (buffer.Length > 65500) + { + throw new ArgumentException("Ping data too big! Maximum 65500 bytes allowed!"); + } + Ping ping = new Ping(); + return ping.Send(hostNameOrAddress, timeOut, buffer, options); + } + } + /// + /// IPv4 kezeléssel kapcsolatos eszközök + /// + public static class IPv4Tool + { + /// + /// Visszad egy IPAddress osztályt, amit a megadott byte értékekből épít fel + /// + /// + /// + public static IPAddress BuildIPAddress(params byte[] ip) + { + if (ip.Length != 4) + { + throw new ArgumentException("Invalid IP! Specific 4 byte value for valid IP address!"); + } + return new IPAddress(ip); + } + + public static IPAddress BuildIPAddress(string ipOrHostname) + { + IPAddress ip; + + if (IPAddress.TryParse(ipOrHostname, out ip)) + { + // IP + return ip; + } + else + { + // Hostname + try + { + IPHostEntry hostEntry; + hostEntry = Dns.GetHostEntry(ipOrHostname); + foreach (var address in hostEntry.AddressList) + { + if (address.AddressFamily == AddressFamily.InterNetwork) + { + return address; + } + } + throw new ArgumentException(String.Format("Bad input argument! (Argument is not Ip or DNS resorvable host name.)", ipOrHostname)); + } + catch (Exception ex) + { + throw new ArgumentException(String.Format("Bad input argument! (Argument is not Ip or DNS resorvable host name.)", ipOrHostname), ex); + } + } + } + } + + /// + /// MAC address lekérdezése IP alapján + /// + public static class MACTool + { + /// + /// Gets the MAC address () associated with the specified IP. + /// + /// The remote IP address. + /// The remote machine's MAC address. + public static PhysicalAddress GetMacAddress(IPAddress ipAddress) + { + const int MacAddressLength = 6; + int length = MacAddressLength; + var macBytes = new byte[MacAddressLength]; + SendARP(BitConverter.ToInt32(ipAddress.GetAddressBytes(), 0), 0, macBytes, ref length); + return new PhysicalAddress(macBytes); + } + + public static PhysicalAddress GetMacAddress(string ipAddressOrHostName) + { + return MACTool.GetMacAddress(IPv4Tool.BuildIPAddress(ipAddressOrHostName)); + } + + public static PhysicalAddress GetMacAddress(params byte[] ipAddress) + { + return MACTool.GetMacAddress(IPv4Tool.BuildIPAddress(ipAddress)); + } + + public static string ToString(this PhysicalAddress mac, char byteSeparator) + { + return HexString.ByteArrayToHexViaLookup32(mac.GetAddressBytes(), byteSeparator); + } + + /// + /// Netbiostól kér a mac címet, csak netbiost megvalósító eszközökre működik!!! + /// Elég lassú... + /// + /// + /// + public static string GetMacAddressFromNetBios(string ipAddress) + { + string macAddress = string.Empty; + + if (!PingTool.IsHostAccessible(ipAddress)) + { + return String.Empty; + } + try + { + ProcessStartInfo processStartInfo = new ProcessStartInfo(); + Process process = new Process(); + if (Environment.Is64BitOperatingSystem) + { + string filePath = Environment.GetFolderPath(Environment.SpecialFolder.Windows) + "\\sysnative"; + processStartInfo.FileName = Path.Combine(filePath, "nbtstat"); + } + else + { + processStartInfo.FileName = "nbtstat"; + } + processStartInfo.RedirectStandardInput = false; + processStartInfo.RedirectStandardOutput = true; + processStartInfo.Arguments = "-a " + ipAddress; + processStartInfo.UseShellExecute = false; + process = Process.Start(processStartInfo); + string line = null; + do + { + line = macAddress = process.StandardOutput.ReadLine(); + if (line != null) + { + if (macAddress.Trim().ToLower().IndexOf("mac address", 0) > -1) + { + macAddress = line; + break; + } + } + } while (line != null); + process.WaitForExit(); + if (macAddress.IndexOf('=') > -1) + { + macAddress = macAddress.Substring(macAddress.IndexOf('=') + 1); + } + macAddress = macAddress.Trim(); + } + catch (Exception e) + { + // Something unexpected happened? Inform the user + // The possibilities are: + // 1.That the machine is not on the network currently + // 2. The IP address/hostname supplied are not on the same network + // 3. The host was not found on the same subnet or could not be + // resolved + } + return macAddress; + } + + /// + /// ARP query kiküldése + /// + /// + /// + /// + /// + /// + // http://www.codeproject.com/KB/IP/host_info_within_network.aspx + [System.Runtime.InteropServices.DllImport("iphlpapi.dll", ExactSpelling = true)] + static extern int SendARP(int DestIP, int SrcIP, byte[] pMacAddr, ref int PhyAddrLen); + } + + + public static class HexString + { + private static readonly uint[] _lookup32 = CreateLookup32(); + + private static uint[] CreateLookup32() + { + var result = new uint[256]; + for (int i = 0; i < 256; i++) + { + string s = i.ToString("X2"); + result[i] = ((uint)s[0]) + ((uint)s[1] << 16); + } + return result; + } + + public static string ByteArrayToHexViaLookup32(byte[] bytes, char separator) + { + var lookup32 = _lookup32; + byte multipier = 2; + int length = bytes.Length * 2; + if (separator != '\0') + { + length = bytes.Length * 3 - 1; + multipier = 3; + } + var result = new char[length]; + for (int i = 0; i < bytes.Length; i++) + { + var val = lookup32[bytes[i]]; + result[multipier * i] = (char)val; + result[multipier * i + 1] = (char)(val >> 16); + if (separator != '\0' && i != bytes.Length - 1) + { + result[multipier * i + 2] = separator; + } + } + return new string(result); + } + } +} \ No newline at end of file diff --git a/Vrh.Log4Pro.MaintenanceConsole/Tools.cs b/Vrh.Log4Pro.MaintenanceConsole/Tools.cs new file mode 100644 index 0000000..f52a71d --- /dev/null +++ b/Vrh.Log4Pro.MaintenanceConsole/Tools.cs @@ -0,0 +1,509 @@ +using System; +using System.IO; +using System.IO.Compression; +using System.Collections.Generic; +using System.Linq; +using System.Security.Principal; +using System.Text; +using System.Text.RegularExpressions; +using System.Threading.Tasks; +using System.Threading; + +using Microsoft.Web.Administration; +using System.Management; +using System.Diagnostics; + +using Vrh.XmlProcessing; +using System.Xml.Linq; +using Vrh.Log4Pro.MaintenanceConsole.ColorConsoleNS; +using VRH.Common; +using Microsoft.Win32; +using System.Reflection; +using Vrh.Log4Pro.MaintenanceConsole.CommandLineParserNS; + +namespace Vrh.Log4Pro.MaintenanceConsole.ToolsNS +{ + public static class OtherTools + { + public static bool IsRunAsAdmin() + { + WindowsIdentity id = WindowsIdentity.GetCurrent(); + WindowsPrincipal pr = new WindowsPrincipal(id); + return pr.IsInRole(WindowsBuiltInRole.Administrator); + } + public static void StartAsAdmin() + { + if (!OtherTools.IsRunAsAdmin()) + { + ProcessStartInfo proc = new ProcessStartInfo(); + + proc.UseShellExecute = true; + proc.WorkingDirectory = Environment.CurrentDirectory; + proc.FileName = Assembly.GetEntryAssembly().CodeBase; + proc.Verb = "runas"; + try + { + Process.Start(proc); + System.Environment.Exit(1); + } + catch (Exception ex) + { + Console.WriteLine("This program must be run as an administrator! \n\n" + ex.ToString()); + } + } + } + + public static void StartAsSystem(bool interactivemode=false) + { + if (interactivemode) + { + var ans = ColorConsole.ReadLine("NT AUTHORITY\\SYSTEM", prefix: "Start as ",f:ConsoleColor.Yellow, suffix: "?", bracket: "[]",validitylist:new List { "yes","no"},exitvalue:"EX",defaultvalue:"no"); + if (ans?.ToLower() != "yes") { return; } + } + string runasusername = System.Security.Principal.WindowsIdentity.GetCurrent().Name; + if (runasusername=="NT AUTHORITY\\SYSTEM") { return; } + + Process p = new System.Diagnostics.Process(); + p.StartInfo.FileName = @"C:\Log4ProIS\MAINTENANCECONSOLE\PsTools\psexec.exe"; + p.StartInfo.UseShellExecute = false; + + p.StartInfo.Arguments = @"-sid C:\Log4ProIS\MAINTENANCECONSOLE\Vrh.Log4Pro.MaintenanceConsole.exe " + CLP.CMD_STARTASSYSTEM + " YES"; + p.Start(); + System.Environment.Exit(1); + } + } + public static class ZipTools + { + public static string FileNameMaskListToRegex(string excludefilenamemaskcsvlist) + { + string pattern = ""; + string regexor = ""; + foreach (var exclmask in excludefilenamemaskcsvlist.Split(new char[] { ',', ';' }, StringSplitOptions.RemoveEmptyEntries)) + { + pattern += regexor + "(^" + Regex.Escape(exclmask.Replace(".", "__DOT__").Replace("*", "__STAR__").Replace("?", "__QM__")) + .Replace("__DOT__", "[.]").Replace("__STAR__", ".*").Replace("__QM__", ".") + "$)"; + regexor = "|"; + } + return "(" + pattern + ")"; + } + public static void Extract1stFileFromZIP(string targetfilefullpath, string ZIPfilefullpath) + { + if (File.Exists(targetfilefullpath)) { File.Delete(targetfilefullpath); } + using (ZipArchive archive = ZipFile.Open(ZIPfilefullpath, ZipArchiveMode.Read)) + { + foreach (var zipentry in archive.Entries) + { + zipentry.ExtractToFile(targetfilefullpath); + return; + } + } + } + public static void ExtractAllFileFromZIP(string targetdirectorypath, string ZIPfilefullpath) + { + if (!Directory.Exists(targetdirectorypath)) { Directory.CreateDirectory(targetdirectorypath); } + using (ZipArchive archive = ZipFile.Open(ZIPfilefullpath, ZipArchiveMode.Read)) + { + foreach (var zipentry in archive.Entries) + { + zipentry.ExtractToFile(Path.Combine(targetdirectorypath, zipentry.FullName)); + } + } + } + + public static void CreateEntriesFromDirectoryContent(string sourcefolderpath, string ZIPfilefullpath, string includefilenamemask, string excludefilenamemasklist, string includefullpathregex, bool removearchivedfiles = false,bool storepathinzip = true) + { + if (File.Exists(ZIPfilefullpath)) { File.Delete(ZIPfilefullpath); } + DirectoryInfo di = new DirectoryInfo(sourcefolderpath); + var inclrgx = new Regex(includefullpathregex??""); + var exclrgx = new Regex(FileNameMaskListToRegex(excludefilenamemasklist) ?? ""); + var archivedfiles = new List(); + using (ZipArchive archive = ZipFile.Open(ZIPfilefullpath, ZipArchiveMode.Create)) + { + ColorConsole.WriteLine($"ZIP-ping directory '{sourcefolderpath}'...", ConsoleColor.Yellow); + FileInfo[] fis = di.GetFiles(includefilenamemask, SearchOption.AllDirectories); + int maxfilefullpathlength = 0; + int cpt = ColorConsole.CursorTop; + int cpl = ColorConsole.CursorLeft; + foreach (var fi in fis) + { + var entryname = storepathinzip ? fi.FullName.Substring((Path.GetPathRoot(fi.FullName)?.Length) ?? 0) : fi.Name; + if (inclrgx.Match(fi.FullName).Success && !exclrgx.Match(fi.Name).Success) + { + try + { + archive.CreateEntryFromFile(fi.FullName, entryname, CompressionLevel.Optimal); + ColorConsole.Write(fi.FullName, ConsoleColor.Yellow); + if (maxfilefullpathlength > fi.FullName.Length) + { + ColorConsole.Write(new string(' ', maxfilefullpathlength - fi.FullName.Length)); + } + else { maxfilefullpathlength = fi.FullName.Length; } + ColorConsole.SetCursorPosition(cpl, cpt); + archivedfiles.Add(fi.FullName); + } + catch (Exception ex) + { + ColorConsole.WriteLine($"Error when accessing/zipping file '{fi.FullName}'!", ConsoleColor.Red); + ColorConsole.WriteLine(ex.Message, ConsoleColor.Red,prefix: "Exception message: ", bracket:"[]"); + } + } + cpt = ColorConsole.CursorTop; + cpl = ColorConsole.CursorLeft; + } + ColorConsole.Write(new string(' ', maxfilefullpathlength)); + ColorConsole.SetCursorPosition(cpl, cpt); + } + if (removearchivedfiles) + { + archivedfiles.ForEach(x => File.Delete(x)); + string[] dirs = System.IO.Directory.GetDirectories(sourcefolderpath); + string[] files = System.IO.Directory.GetFiles(sourcefolderpath); + if (dirs.Length + files.Length == 0) { Directory.Delete(sourcefolderpath); } + } + } + } + public static class Tools + { + public static T GetPropertyValue(object obj, string propName) { return (T)obj.GetType().GetProperty(propName).GetValue(obj, null); } + + public static Dictionary Merge(IEnumerable> dictionaries) + { + return dictionaries.SelectMany(x => x) + .GroupBy(d => d.Key) + .ToDictionary(x => x.Key, y => y.First().Value); + } + + public static bool IsElevated + { + get + { + return new WindowsPrincipal(WindowsIdentity.GetCurrent()).IsInRole(WindowsBuiltInRole.Administrator); + } + } + public static string ExecuteAndGetStdIo(string exepath, string args) + { + StringBuilder outputBuilder = new StringBuilder(); + StringBuilder erroroutputBuilder = new StringBuilder(); + ProcessStartInfo startInfo = new ProcessStartInfo() { }; + using (Process exeProcess = new Process()) + { + startInfo.CreateNoWindow = true; + startInfo.WindowStyle = ProcessWindowStyle.Hidden; + startInfo.RedirectStandardOutput = true; + startInfo.RedirectStandardError= true; + startInfo.RedirectStandardInput = true; + startInfo.UseShellExecute = false; + startInfo.FileName = exepath; + startInfo.Verb= "runas"; + startInfo.Arguments = args; + + exeProcess.StartInfo = startInfo; + // enable raising events because Process does not raise events by default + exeProcess.EnableRaisingEvents = true; + exeProcess.OutputDataReceived += new DataReceivedEventHandler + ( + delegate (object sender, DataReceivedEventArgs e) + { + // append the new data to the data already read-in + outputBuilder.Append(e.Data + "\r\n"); + } + ); + exeProcess.ErrorDataReceived += new DataReceivedEventHandler + ( + delegate (object sender, DataReceivedEventArgs e) + { + // append the new data to the data already read-in + erroroutputBuilder.Append(e.Data + "\r\n"); + } + ); + // start the process + // then begin asynchronously reading the output + // then wait for the process to exit + // then cancel asynchronously reading the output + exeProcess.Start(); + exeProcess.BeginOutputReadLine(); + exeProcess.WaitForExit(); + exeProcess.CancelOutputRead(); + return outputBuilder.ToString(); + } + } + + public static string GetTemporaryFoldername(string directorypath) + { + return Path.Combine(directorypath, DateTime.Now.ToString($"TMP_yyyyMMddHHmmssfffffff")); + } + public static string GetTemporaryfilename(string directorypath, string extension) + { + if (extension == null) { extension = ".tmp"; } + return Path.Combine(directorypath, DateTime.Now.ToString($"TMP_yyyyMMddHHmmssfffffff.{extension}")); + } + public static void ShutDown(ShutDownMode oparation) + { + string filename = string.Empty; + string arguments = string.Empty; + switch (oparation) + { + case ShutDownMode.ShutDown: + filename = "shutdown.exe"; + arguments = "-s"; + break; + case ShutDownMode.Restart: + filename = "shutdown.exe"; + arguments = "-r"; + break; + case ShutDownMode.Logoff: + filename = "shutdown.exe"; + arguments = "-l"; + break; + case ShutDownMode.Lock: + filename = "Rundll32.exe"; + arguments = "User32.dll, LockWorkStation"; + break; + case ShutDownMode.Hibernation: + filename = @"%windir%\system32\rundll32.exe"; + arguments = "PowrProf.dll, SetSuspendState"; + break; + case ShutDownMode.Sleep: + filename = "Rundll32.exe"; + arguments = "powrprof.dll, SetSuspendState 0,1,0"; + break; + } + ProcessStartInfo startinfo = new ProcessStartInfo(filename, arguments); + Process.Start(startinfo); + } + public enum ShutDownMode { Sleep, Hibernation,Lock,Logoff,Restart,ShutDown,} + private static string HKLM_GetString(string path, string key) + { + try + { + Microsoft.Win32.RegistryKey rk = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(path); + if (rk == null) return ""; + return (string)rk.GetValue(key); + } + catch { return null; } + } + + public static string GetOSFriendlyNameA() + { + string ProductName = HKLM_GetString(@"SOFTWARE\Microsoft\Windows NT\CurrentVersion", "ProductName"); + string CSDVersion = HKLM_GetString(@"SOFTWARE\Microsoft\Windows NT\CurrentVersion", "CSDVersion"); + if (!string.IsNullOrWhiteSpace(ProductName)) + { + return (ProductName.StartsWith("Microsoft") ? "" : "Microsoft ") + ProductName + (CSDVersion != "" ? " " + CSDVersion : ""); + } + return null; + } + + public static string GetOSFriendlyNameB() + { + string result = string.Empty; + ManagementObjectSearcher searcher = new ManagementObjectSearcher("SELECT Caption FROM Win32_OperatingSystem"); + foreach (ManagementObject os in searcher.Get()) { result = os["Caption"].ToString(); break; } + return string.IsNullOrWhiteSpace(result)? null : result; + } + public static string GetOSFriendlyNameC() + { + return new Microsoft.VisualBasic.Devices.ComputerInfo().OSFullName; + } + public static string GetOSType() + { + string os = null; + IEnumerable list64 = System.IO.Directory.GetDirectories(Environment.GetEnvironmentVariable("SystemRoot")).Where(s => s.Equals(@"C:\Windows\SysWOW64")); + IEnumerable list32 = System.IO.Directory.GetDirectories(Environment.GetEnvironmentVariable("SystemRoot")).Where(s => s.Equals(@"C:\Windows\System32")); + if (list32.Count() > 0) { if (list64.Count() > 0) { os = "64bit"; } else { os = "32bit"; } } + return os; + } + public static bool ResolveArguments(string parameterkvpstring, string stringwithparameters, out string resolvedtext, bool interactive = true) + { + var argumentparametersdictionary = parameterkvpstring.Split(new char[] { ';', ',' }, StringSplitOptions.RemoveEmptyEntries) + .Select(kvp => CreateKVP(kvp)) + .Where(kvp => kvp.Key != null) + .ToDictionary(kvp => kvp.Key, kvp => kvp.Value); + Dictionary resolveddictionary = new Dictionary(); + resolvedtext = stringwithparameters; + foreach (var kvp in argumentparametersdictionary) + { + if (kvp.Value.StartsWith("?") && interactive) + { + string prompt = $"Enter value for {kvp.Key}:"; + string kvpdefaultvalue = null; + if (kvp.Value.Length > 1) + { + prompt = kvp.Value.Substring(1).Split(new char[] { '?' }, StringSplitOptions.RemoveEmptyEntries)[0]; + if (kvp.Value.Substring(1).IndexOf('?') != -1) kvpdefaultvalue = kvp.Value.Substring(1).Split(new char[] { '?' }, StringSplitOptions.RemoveEmptyEntries)[1]; + } + string value = ColorConsole.ReadLine(prompt, ConsoleColor.Yellow, defaultvalue: kvpdefaultvalue); + if (value.ToLower() == "ex") { return false; } + resolveddictionary.Add(kvp.Key, value); + } + else if (kvp.Value.StartsWith("?") && !interactive) resolveddictionary.Add(kvp.Key, $"{{{kvp.Key}}}"); + else { resolveddictionary.Add(kvp.Key, kvp.Value); } + } + resolvedtext = VRH.Common.StringConstructor.ResolveConstructorR(resolveddictionary, stringwithparameters, "{}@@"); + return true; + } + private static KeyValuePair CreateKVP(string kvpstring) + { + string kvpk = null; + string kvpv = null; + try + { + kvpk = kvpstring.Split(new char[] { '=' }, StringSplitOptions.RemoveEmptyEntries)[0]; if (string.IsNullOrWhiteSpace(kvpk)) { kvpk = null; } + kvpv = kvpstring.Split(new char[] { '=' }, StringSplitOptions.RemoveEmptyEntries)[1]; + KeyValuePair r = new KeyValuePair(kvpk, kvpv); + return r; + } + catch { return new KeyValuePair(kvpk, null); } + } + } + + class ComputerInfo + { + public string PageHeader; + public string ComputerName; + public string DNSHostName; + public string UserName; + public string DomainUserName; + public List IpAddressList; + public string ProcessorArchitecture; + public string OSType; + public string NumOfPhysicalProcessors; + public string NumOfLogicalProcessors; + public string NumOfCores; + public string OSPlatform; + public string OSServicePack; + public string OSVersionString; + public List OSFriendlyNames; + public static void DisplayThis() { new ComputerInfo().Display(); } + public ComputerInfo() + { + var ci = this; + const string XMLCONNECTIONSTRING = "config=MAINTENANCECONSOLE;"; + //const string XMLCONNECTIONSTRING_DEFAULT = "file=Config.Xml;"; + var config = new MaintenanceConsoleXmlProcessor(XMLCONNECTIONSTRING, "", "hu-HU"); + + ci.PageHeader = config.Xml_Header; + ci.ComputerName = System.Environment.MachineName; + ci.DNSHostName = System.Net.Dns.GetHostName(); + ci.UserName = Environment.UserName; + ci.DomainUserName = System.Security.Principal.WindowsIdentity.GetCurrent().Name; + ci.IpAddressList = System.Net.Dns.GetHostEntry(ci.DNSHostName).AddressList.Where(ip => ip.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork).ToList(); + ci.ProcessorArchitecture = System.Environment.GetEnvironmentVariable("PROCESSOR_ARCHITECTURE"); + ci.OSType = Tools.GetOSType(); + foreach (var item in new System.Management.ManagementObjectSearcher("Select * from Win32_ComputerSystem").Get()) + { + ci.NumOfPhysicalProcessors = item["NumberOfProcessors"].ToString(); + ci.NumOfLogicalProcessors = item["NumberOfLogicalProcessors"].ToString(); + break; + } + + var numofcores = 0; + foreach (var item in new System.Management.ManagementObjectSearcher("Select * from Win32_Processor").Get()) { numofcores += int.Parse(item["NumberOfCores"].ToString()); } + ci.NumOfCores = numofcores.ToString(); + ci.OSPlatform = System.Environment.OSVersion.Platform.ToString(); + ci.OSServicePack = System.Environment.OSVersion.ServicePack; + ci.OSVersionString = System.Environment.OSVersion.VersionString; + + string fn; + ci.OSFriendlyNames = new List(); + fn = Tools.GetOSFriendlyNameA(); if (!string.IsNullOrWhiteSpace(fn) && !ci.OSFriendlyNames.Contains(fn)) ci.OSFriendlyNames.Add(fn); + fn = Tools.GetOSFriendlyNameB(); if (!string.IsNullOrWhiteSpace(fn) && !ci.OSFriendlyNames.Contains(fn)) ci.OSFriendlyNames.Add(fn); + fn = Tools.GetOSFriendlyNameC(); if (!string.IsNullOrWhiteSpace(fn) && !ci.OSFriendlyNames.Contains(fn)) ci.OSFriendlyNames.Add(fn); + } + public void Display() + { + const string XMLCONNECTIONSTRING = "config=MAINTENANCECONSOLE;"; + //const string XMLCONNECTIONSTRING_DEFAULT = "file=Config.Xml;"; + var config = new MaintenanceConsoleXmlProcessor(XMLCONNECTIONSTRING, "", "hu-HU"); + + ColorConsole.WriteLine(PageHeader, ConsoleColor.Yellow, bracket: "[]"); + + //computername + ColorConsole.WriteLine(""); + ColorConsole.Write("Computer name: "); + ColorConsole.Write(ComputerName, ConsoleColor.Yellow, bracket: "[]", prefix: "", suffix: ","); + ColorConsole.Write(DNSHostName, ConsoleColor.Yellow, bracket: "[]", prefix: "DNS hostname:"); + ColorConsole.WriteLine(""); + + //username + ColorConsole.Write("Username:"); + ColorConsole.Write(UserName, ConsoleColor.Yellow, bracket: "[]", prefix: "RunAs:", suffix: ","); + ColorConsole.Write(DomainUserName, ConsoleColor.Yellow, bracket: "[]", prefix: "LoggedIn:"); + ColorConsole.WriteLine(""); + + //ip address + ColorConsole.Write("IP addresses: "); + if (IpAddressList.Any()) { foreach (var ip in IpAddressList) { ColorConsole.Write(ip.ToString(), ConsoleColor.Yellow, bracket: "[]", prefix: $"{ip.AddressFamily}:", suffix: ","); } } + else { ColorConsole.Write("N/A", ConsoleColor.Yellow, bracket: "[]"); } + + ColorConsole.WriteLine(""); + + // processor architecture + ColorConsole.Write("Processors: "); + ColorConsole.Write(System.Environment.GetEnvironmentVariable("PROCESSOR_ARCHITECTURE"), ConsoleColor.Yellow, bracket: "[]", prefix: "Architecture: "); + ColorConsole.Write(OSType ?? "N/A", ConsoleColor.Yellow, bracket: "[]", suffix: ", "); + ColorConsole.Write(NumOfPhysicalProcessors, ConsoleColor.Yellow, bracket: "[]", prefix: "Physical:", suffix: ", "); + ColorConsole.Write(NumOfLogicalProcessors, ConsoleColor.Yellow, bracket: "[]", prefix: "Logical:", suffix: ", "); + ColorConsole.Write(NumOfCores, ConsoleColor.Yellow, bracket: "[]", prefix: "Cores:"); + ColorConsole.WriteLine(""); + + + // os version + ColorConsole.Write("Operating system: "); + ColorConsole.Write(OSPlatform.ToString(), ConsoleColor.Yellow, bracket: "[]", prefix: "Platform:", suffix: ","); + ColorConsole.Write(OSServicePack, ConsoleColor.Yellow, bracket: "[]", prefix: "Service pack:", suffix: ","); + ColorConsole.Write(OSVersionString, ConsoleColor.Yellow, bracket: "[]", prefix: "Version string:"); + ColorConsole.WriteLine(""); + + ColorConsole.Write("", ConsoleColor.Yellow, prefix: "OS Friendly name versions:"); + if (OSFriendlyNames.Any()) { foreach (var fn in OSFriendlyNames) { ColorConsole.Write(fn, ConsoleColor.Yellow, bracket: "[]"); } } + else { ColorConsole.Write("N/A", ConsoleColor.Yellow, bracket: "[]"); } + + ColorConsole.WriteLine(""); + ColorConsole.WriteLine(""); + ColorConsole.WriteLine(""); + } + } + + + #region StringExtension class + public static class StringExtension + { + /// + /// Behelyezzesíti a megadott stringben előforduló Environment.SpecialFolder enum neveket + /// az Environment.GetFolderPath által visszadott tényleges értékükre + /// + /// + /// + /// + public static string SubstituteSpecialFolderName(this string s, Environment.SpecialFolder n) { return s.Replace("@" + n.ToString() + "@", Environment.GetFolderPath(n)); } + } + #endregion StringExtension class + + #region ExceptionExtension class + public static class ExceptionExtension + { + /// + /// Az exception és belső exceptionjeinek összefűzése + /// + /// + /// + public static string MessageNested(this Exception ex) + { + string rexmsg = ""; + string indent = ""; + const string indentof1level = " "; + Exception excl = ex; + while (true) + { + rexmsg += indent + excl.Message; + excl = excl.InnerException; + indent += (indent==""?"\n":"")+indentof1level; + if (excl == null) { break; } + } + return rexmsg.Replace("\n\n","\n"); + } + } + + #endregion ExceptionExtension class +} diff --git a/Vrh.Log4Pro.MaintenanceConsole/Vrh.Log4Pro.MaintenanceConsole.csproj b/Vrh.Log4Pro.MaintenanceConsole/Vrh.Log4Pro.MaintenanceConsole.csproj index 8032fb6..e3196ca 100644 --- a/Vrh.Log4Pro.MaintenanceConsole/Vrh.Log4Pro.MaintenanceConsole.csproj +++ b/Vrh.Log4Pro.MaintenanceConsole/Vrh.Log4Pro.MaintenanceConsole.csproj @@ -359,13 +359,13 @@ - - + + - - + + -- libgit2 0.21.2