Commit 62445795987c19f083f95f46eec0adafe79ef5a3

Authored by Schwirg László
1 parent 26858817

FTPManager előkészítése

Vrh.Log4Pro.MaintenanceConsole/ConsoleFunction - Tools.cs
... ... @@ -304,6 +304,115 @@ namespace Vrh.Log4Pro.MaintenanceConsole.ToolsNS
304 304 }
305 305 }
306 306  
  307 + class ComputerInfo
  308 + {
  309 + public string PageHeader;
  310 + public string ComputerName;
  311 + public string DNSHostName;
  312 + public string UserName;
  313 + public string DomainUserName;
  314 + public List<System.Net.IPAddress> IpAddressList;
  315 + public string ProcessorArchitecture;
  316 + public string OSType;
  317 + public string NumOfPhysicalProcessors;
  318 + public string NumOfLogicalProcessors;
  319 + public string NumOfCores;
  320 + public string OSPlatform;
  321 + public string OSServicePack;
  322 + public string OSVersionString;
  323 + public List<string> OSFriendlyNames;
  324 + public static void DisplayThis() { new ComputerInfo().Display(); }
  325 + public ComputerInfo()
  326 + {
  327 + var ci = this;
  328 + const string XMLCONNECTIONSTRING = "config=MAINTENANCECONSOLE;";
  329 + //const string XMLCONNECTIONSTRING_DEFAULT = "file=Config.Xml;";
  330 + var config = new MaintenanceConsoleXmlProcessor(XMLCONNECTIONSTRING, "", "hu-HU");
  331 +
  332 + ci.PageHeader = config.Xml_Header;
  333 + ci.ComputerName = System.Environment.MachineName;
  334 + ci.DNSHostName = System.Net.Dns.GetHostName();
  335 + ci.UserName = Environment.UserName;
  336 + ci.DomainUserName = System.Security.Principal.WindowsIdentity.GetCurrent().Name;
  337 + ci.IpAddressList = System.Net.Dns.GetHostEntry(ci.DNSHostName).AddressList.Where(ip => ip.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork).ToList();
  338 + ci.ProcessorArchitecture = System.Environment.GetEnvironmentVariable("PROCESSOR_ARCHITECTURE");
  339 + ci.OSType = Tools.GetOSType();
  340 + foreach (var item in new System.Management.ManagementObjectSearcher("Select * from Win32_ComputerSystem").Get())
  341 + {
  342 + ci.NumOfPhysicalProcessors = item["NumberOfProcessors"].ToString();
  343 + ci.NumOfLogicalProcessors = item["NumberOfLogicalProcessors"].ToString();
  344 + break;
  345 + }
  346 +
  347 + var numofcores = 0;
  348 + foreach (var item in new System.Management.ManagementObjectSearcher("Select * from Win32_Processor").Get()) { numofcores += int.Parse(item["NumberOfCores"].ToString()); }
  349 + ci.NumOfCores = numofcores.ToString();
  350 + ci.OSPlatform = System.Environment.OSVersion.Platform.ToString();
  351 + ci.OSServicePack = System.Environment.OSVersion.ServicePack;
  352 + ci.OSVersionString = System.Environment.OSVersion.VersionString;
  353 +
  354 + string fn;
  355 + ci.OSFriendlyNames = new List<string>();
  356 + fn = Tools.GetOSFriendlyNameA(); if (!string.IsNullOrWhiteSpace(fn) && !ci.OSFriendlyNames.Contains(fn)) ci.OSFriendlyNames.Add(fn);
  357 + fn = Tools.GetOSFriendlyNameB(); if (!string.IsNullOrWhiteSpace(fn) && !ci.OSFriendlyNames.Contains(fn)) ci.OSFriendlyNames.Add(fn);
  358 + fn = Tools.GetOSFriendlyNameC(); if (!string.IsNullOrWhiteSpace(fn) && !ci.OSFriendlyNames.Contains(fn)) ci.OSFriendlyNames.Add(fn);
  359 + }
  360 + public void Display()
  361 + {
  362 + const string XMLCONNECTIONSTRING = "config=MAINTENANCECONSOLE;";
  363 + //const string XMLCONNECTIONSTRING_DEFAULT = "file=Config.Xml;";
  364 + var config = new MaintenanceConsoleXmlProcessor(XMLCONNECTIONSTRING, "", "hu-HU");
  365 +
  366 + ColorConsole.WriteLine(PageHeader, ConsoleColor.Yellow, bracket: "[]");
  367 +
  368 + //computername
  369 + ColorConsole.WriteLine("");
  370 + ColorConsole.Write("Computer name: ");
  371 + ColorConsole.Write(ComputerName, ConsoleColor.Yellow, bracket: "[]", prefix: "", suffix: ",");
  372 + ColorConsole.Write(DNSHostName, ConsoleColor.Yellow, bracket: "[]", prefix: "DNS hostname:");
  373 + ColorConsole.WriteLine("");
  374 +
  375 + //username
  376 + ColorConsole.Write("Username:");
  377 + ColorConsole.Write(UserName, ConsoleColor.Yellow, bracket: "[]", prefix: "RunAs:", suffix: ",");
  378 + ColorConsole.Write(DomainUserName, ConsoleColor.Yellow, bracket: "[]", prefix: "LoggedIn:");
  379 + ColorConsole.WriteLine("");
  380 +
  381 + //ip address
  382 + ColorConsole.Write("IP addresses: ");
  383 + if (IpAddressList.Any()) { foreach (var ip in IpAddressList) { ColorConsole.Write(ip.ToString(), ConsoleColor.Yellow, bracket: "[]", prefix: $"{ip.AddressFamily}:", suffix: ","); } }
  384 + else { ColorConsole.Write("N/A", ConsoleColor.Yellow, bracket: "[]"); }
  385 +
  386 + ColorConsole.WriteLine("");
  387 +
  388 + // processor architecture
  389 + ColorConsole.Write("Processors: ");
  390 + ColorConsole.Write(System.Environment.GetEnvironmentVariable("PROCESSOR_ARCHITECTURE"), ConsoleColor.Yellow, bracket: "[]", prefix: "Architecture: ");
  391 + ColorConsole.Write(OSType ?? "N/A", ConsoleColor.Yellow, bracket: "[]", suffix: ", ");
  392 + ColorConsole.Write(NumOfPhysicalProcessors, ConsoleColor.Yellow, bracket: "[]", prefix: "Physical:", suffix: ", ");
  393 + ColorConsole.Write(NumOfLogicalProcessors, ConsoleColor.Yellow, bracket: "[]", prefix: "Logical:", suffix: ", ");
  394 + ColorConsole.Write(NumOfCores, ConsoleColor.Yellow, bracket: "[]", prefix: "Cores:");
  395 + ColorConsole.WriteLine("");
  396 +
  397 +
  398 + // os version
  399 + ColorConsole.Write("Operating system: ");
  400 + ColorConsole.Write(OSPlatform.ToString(), ConsoleColor.Yellow, bracket: "[]", prefix: "Platform:", suffix: ",");
  401 + ColorConsole.Write(OSServicePack, ConsoleColor.Yellow, bracket: "[]", prefix: "Service pack:", suffix: ",");
  402 + ColorConsole.Write(OSVersionString, ConsoleColor.Yellow, bracket: "[]", prefix: "Version string:");
  403 + ColorConsole.WriteLine("");
  404 +
  405 + ColorConsole.Write("", ConsoleColor.Yellow, prefix: "OS Friendly name versions:");
  406 + if (OSFriendlyNames.Any()) { foreach (var fn in OSFriendlyNames) { ColorConsole.Write(fn, ConsoleColor.Yellow, bracket: "[]"); } }
  407 + else { ColorConsole.Write("N/A", ConsoleColor.Yellow, bracket: "[]"); }
  408 +
  409 + ColorConsole.WriteLine("");
  410 + ColorConsole.WriteLine("");
  411 + ColorConsole.WriteLine("");
  412 + }
  413 + }
  414 +
  415 +
307 416 #region StringExtension class
308 417 public static class StringExtension
309 418 {
... ...
Vrh.Log4Pro.MaintenanceConsole/Manager - FTPManager.cs 0 → 100644
... ... @@ -0,0 +1,357 @@
  1 +using System;
  2 +using System.Collections.Generic;
  3 +using System.Linq;
  4 +using System.Text;
  5 +using System.Threading.Tasks;
  6 +using System.Net;
  7 +using System.Text.RegularExpressions;
  8 +using System.IO;
  9 +
  10 +namespace Vrh.Log4Pro.MaintenanceConsole
  11 +{
  12 + static class FTPManagerCore
  13 + {
  14 + public class FTPFileList
  15 + {
  16 + #region constructor
  17 + /// <summary>
  18 + /// Létrehoz egy FTP kapcsolódáshoz szükséges obektumot
  19 + /// </summary>
  20 + /// <param name="servername">az ftp server neve</param>
  21 + /// <param name="username">a felhasználó neve</param>
  22 + /// <param name="password">a felhasználó jelszava</param>
  23 + public FTPFileList(string servername, string username, string password)
  24 + {
  25 + this.servername = servername;
  26 + this.username = username;
  27 + this.password = password;
  28 + }
  29 + #endregion constructor
  30 +
  31 + #region fields
  32 + public string servername;
  33 + public string ftprootdirectory;
  34 + public string localrootdirectory;
  35 + public string username;
  36 + private string password;
  37 + private string directorydisplaymask;
  38 + private string filedisplaymask;
  39 + public List<FTPDirectoryItemData> ftpfilelist;
  40 + public List<FTPDirectoryItemData> localfilelist;
  41 + #endregion fields
  42 +
  43 + #region SetRootDirectories
  44 + /// <summary>
  45 + /// Beállítja az ftp szerveren a root könyvtárat, valamint a lokális szerveren a root könyvtárat;
  46 + /// a könyvtárútvonalakat a lokális gépen és az ftp szerveren is ezekhez képest kell megadni
  47 + /// </summary>
  48 + /// <param name="ftprootdirectory"></param>
  49 + /// <param name="localrootdirectory"></param>
  50 + public void SetRootDirectories(string ftprootdirectory=null,string localrootdirectory=null)
  51 + {
  52 + this.ftprootdirectory = ftprootdirectory ?? "";
  53 + this.localrootdirectory = localrootdirectory ?? "";
  54 + }
  55 + #endregion SetRootDirectories
  56 +
  57 + #region BuildForUpload
  58 + /// <summary>
  59 + /// Elkészíti a megadott paraméterek alapján a feltöltéshez szükséges file listát (a lokális gépen levő file-ok listája)
  60 + /// </summary>
  61 + /// <param name="directorypath">a lokális könyvtár útvonal, aminek a tartalmát kell a listába betölteni
  62 + /// (a megadott lokális root könyvtárhoz képest van megadva a path)</param>
  63 + /// <param name="recurse">alkönyvtárakba is bemegy</param>
  64 + /// <param name="filterregex">regex a file-ok szűrésére</param>
  65 + /// <param name="filterregexappliedtopath">true=a regex-et a teljes elérési útra kell alkalmazni, false=csak a file nevére</param>
  66 + /// <param name="filterregextoexclude">true=a regex-nek megfelelő file-okat nem kell betenni,false=be kell tenni</param>
  67 + public void BuildForUpload(string directorypath, bool recurse, string filterregex = "", bool filterregexappliedtopath = false, bool filterregextoexclude = false)
  68 + {
  69 + localfilelist = LocalFileListFactory(this.localrootdirectory,directorypath, recurse, filterregex, filterregexappliedtopath, filterregextoexclude);
  70 + }
  71 + #endregion BuildForUpload
  72 +
  73 + #region BuildForDownload
  74 + /// <summary>
  75 + /// Elkészíti a file listát a letöltéshez (az ftp szerveren található file-ok listája)
  76 + /// </summary>
  77 + /// <param name="directorypath">ennek a könyvtárnak a tartalmát kell listázni
  78 + /// (a megadott ftp root könyvtárhoz képest van megadva a path)</param>
  79 + /// <param name="recurse">alkönyvtárakba is be kell menni</param>
  80 + /// <param name="filterregex">regex a file-ok szűrésére</param>
  81 + /// <param name="filterregexappliedtopath">true=a regex-et a teljes elérési útra kell alkalmazni, false=csak a file nevére</param>
  82 + /// <param name="filterregextoexclude">true=a regex-nek megfelelő file-okat nem kell betenni,false=be kell tenni</param>
  83 + public void BuildForDownload(string directorypath, bool recurse, string filterregex = "", bool filterregexappliedtopath = false, bool filterregextoexclude = false)
  84 + {
  85 + ftpfilelist = FTPFileListFactory(servername, this.ftprootdirectory,directorypath, username, password , recurse, filterregex, filterregexappliedtopath, filterregextoexclude);
  86 + }
  87 + #endregion BuildForDownload
  88 +
  89 + #region Download
  90 + /// <summary>
  91 + /// Az ftp file lista letöltése az ftp szerverrőől a lokális gépre.
  92 + /// A megadott könyvtárba kerül be az ftp file lista az ftp root könyvtár alatti könyvtár struktúra megörzésével.
  93 + /// </summary>
  94 + /// <param name="localdirectory">ebbe a könyvtárba kell letölteni (a lokális root könyvtárhoz képest megadott útvonal)</param>
  95 + public void Download(string localdirectory)
  96 + {
  97 + foreach (var f in this.ftpfilelist)
  98 + {
  99 + var targetdirectory = Path.Combine(this.localrootdirectory, localdirectory, f.directory);
  100 + var sourcedirectory = Path.Combine(f.rootdirectory, f.directory);
  101 + FTPManagerCore.FTPTools.FileDownload(targetdirectory, f.name, this.servername, sourcedirectory, f.name, this.username, this.password);
  102 + }
  103 + }
  104 + #endregion Download
  105 +
  106 + #region Upload
  107 + /// <summary>
  108 + /// A lokális file lista feltöltése az ftp szerverre a lokális gépről.
  109 + /// A megadott könyvtárba kerül be az lokális file lista a lokális root könyvtár alatti könyvtár struktúra megörzésével.
  110 + /// </summary>
  111 + /// <param name="ftpdirectory">ebbe a könyvtárba kell feltölteni (az ftproot könyvtárhoz képest megadott útvonal)</param>
  112 + public void Upload(string ftpdirectory)
  113 + {
  114 + foreach (var f in this.localfilelist)
  115 + {
  116 + var targetdirectory = Path.Combine(this.ftprootdirectory, ftpdirectory, f.directory);
  117 + var sourcedirectory = Path.Combine(f.rootdirectory, f.directory);
  118 + FTPManagerCore.FTPTools.FileUpload(f.directory, f.name, this.servername, targetdirectory, f.name, this.username, this.password);
  119 + }
  120 + }
  121 + #endregion Upload
  122 +
  123 + #region other public methods
  124 + public void DisplayFTP()
  125 + {
  126 + if (this.ftpfilelist == null) { return; }
  127 + foreach (var did in this.ftpfilelist)
  128 + {
  129 + Console.WriteLine(did.ToString(this.directorydisplaymask, this.filedisplaymask));
  130 + }
  131 + }
  132 + public void DisplayLocal()
  133 + {
  134 + if (this.localfilelist == null) { return; }
  135 + foreach (var did in this.localfilelist)
  136 + {
  137 + Console.WriteLine(did.ToString(this.directorydisplaymask, this.filedisplaymask));
  138 + }
  139 + }
  140 + #endregion other public methods
  141 +
  142 + #region private methods
  143 + private static List<FTPDirectoryItemData> FTPFileListFactory(string servername,string rootdirectory, string directorypath, string username, string password
  144 + , bool recurse, string filterregex = "", bool filterregexappliedtopath = false, bool filterregexptoexclude = false)
  145 + {
  146 + var fulldirectorypath = Path.Combine(rootdirectory, directorypath);
  147 + var uristr = $"ftp://{servername}/{fulldirectorypath}/";
  148 + var uri = new Uri(uristr, UriKind.Absolute);
  149 + var ftprequest = WebRequest.Create(uri);
  150 + ftprequest.Credentials = new NetworkCredential(username, password);
  151 + ftprequest.Method = WebRequestMethods.Ftp.ListDirectoryDetails;
  152 + string[] dirlisting;
  153 + try
  154 + {
  155 + var ftpresponse = ftprequest.GetResponse();
  156 + var ftpresponsestream = ftpresponse.GetResponseStream();
  157 + var streamreader = new System.IO.StreamReader(ftpresponsestream);
  158 + dirlisting = streamreader.ReadToEnd().Split(new string[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries);
  159 + streamreader.Close();
  160 + ftpresponse.Close();
  161 + }
  162 + catch { return null; }
  163 +
  164 + var dl = new List<FTPDirectoryItemData>();
  165 + var didlist = dirlisting.Select(l => FTPDirectoryItemData.FTPListFactory(l, rootdirectory, directorypath)).Where(id => !id.isdirectory);
  166 + foreach (var did in didlist)
  167 + {
  168 + string includecheckstr = filterregexappliedtopath ? did.fullpath : did.name;
  169 + if (Regex.Match(includecheckstr, filterregex).Success != filterregexptoexclude) { dl.Add(did); }
  170 + }
  171 + if (recurse)
  172 + {
  173 + didlist = dirlisting.Select(l => FTPDirectoryItemData.FTPListFactory(l, rootdirectory, directorypath)).Where(id => id.isdirectory);
  174 + foreach (var did in didlist)
  175 + {
  176 + var subdirectorypath = (string.IsNullOrWhiteSpace(directorypath) ? "" : "\\") + did.name;
  177 + var subdir = FTPFileListFactory(servername, rootdirectory, subdirectorypath, username, password
  178 + , recurse, filterregex, filterregexappliedtopath, filterregexptoexclude);
  179 + if (subdir != null) { dl = dl.Concat(subdir).ToList(); }
  180 + }
  181 + }
  182 + return dl;
  183 + }
  184 +
  185 + private static List<FTPDirectoryItemData> LocalFileListFactory(string localrootdirectory, string directorypath, bool recurse
  186 + , string filterregex = "", bool filterregexappliedtopath = false, bool filterregextoexclude = false)
  187 + {
  188 + var dl = new List<FTPDirectoryItemData>();
  189 + string fulldirectorypath = Path.Combine(localrootdirectory, directorypath);
  190 + var fnl = Directory.GetFiles(fulldirectorypath).Where(dn => filterregextoexclude == !Regex.Match(filterregexappliedtopath ? dn : Path.GetFileName(dn), filterregex).Success);
  191 + fnl = fnl.Select(fp => Path.GetFileName(fp)).ToList();
  192 + var dnl = Directory.GetDirectories(fulldirectorypath).ToList();
  193 + dnl = dnl.Select(dp => new DirectoryInfo(dp).Name).ToList();
  194 +
  195 + foreach (var fn in fnl)
  196 + {
  197 + var did = FTPDirectoryItemData.LocalListFactory(fn, localrootdirectory, directorypath);
  198 + if (did != null) { dl.Add(did); }
  199 + }
  200 + foreach (var dn in dnl)
  201 + {
  202 + var didlist = LocalFileListFactory(localrootdirectory, Path.Combine(directorypath, dn), recurse, filterregex, filterregexappliedtopath, filterregextoexclude);
  203 + if (didlist != null) { dl = dl.Concat(didlist).ToList(); }
  204 + }
  205 + return dl;
  206 + }
  207 + private void SetDisplayMasks(string directorydisplaymask = null, string filedisplaymask = null)
  208 + {
  209 + this.directorydisplaymask = directorydisplaymask;
  210 + this.filedisplaymask = filedisplaymask;
  211 + }
  212 + #endregion private methods
  213 + }
  214 + public class FTPDirectoryItemData
  215 + {
  216 + public static FTPDirectoryItemData LocalListFactory(string filename, string rootdirectoryname, string directoryname)
  217 + {
  218 + if (string.IsNullOrWhiteSpace(filename)) { return null; }
  219 + var did = new FTPDirectoryItemData();
  220 + did.listingline = null;
  221 + did.rootdirectory = rootdirectoryname;
  222 + did.directory = directoryname;
  223 + did.name = filename;
  224 + did.isdirectory = false;
  225 + did.date = File.GetCreationTime(did.fullpath);
  226 + did.size = new System.IO.FileInfo(did.fullpath).Length;
  227 + return did;
  228 + }
  229 + public static FTPDirectoryItemData FTPListFactory(string ftplistingline, string rootdirectory, string directoryname)
  230 + {
  231 + if (string.IsNullOrWhiteSpace(ftplistingline)) { return null; }
  232 + var did = new FTPDirectoryItemData();
  233 + did.listingline = ftplistingline;
  234 + var words = ftplistingline.Split(new char[] { ' ', '+', }, StringSplitOptions.RemoveEmptyEntries);
  235 + did.isdirectory = words[0].StartsWith("d");
  236 + did.name = string.Join(" ", words.Where((x, ix) => ix >= 8));
  237 + if (string.IsNullOrWhiteSpace(did.name)) { return null; }
  238 + did.rootdirectory = rootdirectory;
  239 + did.directory = directoryname;
  240 + if (!long.TryParse(words[4], out did.size)) { did.size = 0; }
  241 + if (!DateTime.TryParse($"{words[5]}.{words[6]}.{words[7]}", out did.date)) { did.date = DateTime.MinValue; };
  242 + return did;
  243 + }
  244 + public string ToString(string dirlinemask = null, string filelinemask = null )
  245 + {
  246 + const string defaultlinemask = "{TYPE} {NAME} {ROOTDIRECTORY} {DIRECTORY} {FULLPATH} {SIZE} {DATE} {LISTLINE}";
  247 + if (dirlinemask == null) { dirlinemask = defaultlinemask; }
  248 + if (filelinemask == null) { filelinemask = defaultlinemask; }
  249 + string linemask = this.isdirectory ? dirlinemask : filelinemask;
  250 + return linemask
  251 + .Replace("{NAME}", this.name)
  252 + .Replace("{TYPE}", this.isdirectory?"DIR":"FILE")
  253 + .Replace("{ROOTDIRECTORY}", this.rootdirectory)
  254 + .Replace("{DIRECTORY}", this.directory)
  255 + .Replace("{FULLPATH}", this.fullpath)
  256 + .Replace("{SIZE}", this.size.ToString())
  257 + .Replace("{DATE}", this.date.ToString("yyyy.MM.dd"))
  258 + .Replace("{LISTLINE}", this.listingline);
  259 + }
  260 + public string listingline;
  261 + public string name;
  262 + public string directory;
  263 + public string rootdirectory;
  264 + public string fullpath { get {return Path.Combine(this.rootdirectory, this.directory, this.name); } }
  265 + public long size;
  266 + public DateTime date;
  267 + public bool isdirectory;
  268 + }
  269 +
  270 + private static class FTPTools
  271 + {
  272 + public static bool FileUpload(string localdirectory, string localfilename, string servername, string directory, string filename, string username, string password)
  273 + {
  274 + try
  275 + {
  276 + if (!string.IsNullOrWhiteSpace(directory)) { filename = Path.Combine(directory, filename); }
  277 + if (!string.IsNullOrWhiteSpace(localdirectory)) { localfilename = Path.Combine(localdirectory, localfilename); }
  278 +
  279 + var uristr = "ftp://" + username + ":" + password + "@" + servername + "/" + filename;
  280 + var webclient = new System.Net.WebClient();
  281 + var uri = new Uri(uristr);
  282 + DirectoryCreate(directory, servername, username, password, false);
  283 + webclient.UploadFile(uri, localfilename);
  284 + return true;
  285 + }
  286 + catch { return false; }
  287 + }
  288 + public static bool FileDownload(string localdirectory, string localfilename, string servername, string directory, string filename, string username, string password)
  289 + {
  290 + try
  291 + {
  292 + if (string.IsNullOrWhiteSpace(directory)) { directory = ""; }
  293 + if (string.IsNullOrWhiteSpace(localdirectory)) { localdirectory = ""; }
  294 + filename = Path.Combine(directory, filename);
  295 + localfilename = Path.Combine(localdirectory, localfilename);
  296 + var uristr = "ftp://" + username + ":" + password + "@" + servername + "/" + filename;
  297 + var webclient = new System.Net.WebClient();
  298 + var uri = new Uri(uristr);
  299 + if (!Directory.Exists(localdirectory)) { Directory.CreateDirectory(localdirectory); }
  300 + webclient.DownloadFile(uri, localfilename);
  301 + return true;
  302 + }
  303 + catch { return false; }
  304 + }
  305 +
  306 + public static string DirectoryCreate(string directoryname, string servername, string username, string password, bool errorifexists = false)
  307 + {
  308 + var directoryparts = directoryname.Replace("/", "\\").Split(new char[] { '\\' }, StringSplitOptions.RemoveEmptyEntries);
  309 + string dn = "";
  310 + for (int ix = 0; ix < directoryparts.Length; ix++)
  311 + {
  312 + dn = Path.Combine(dn, directoryparts[ix]);
  313 + OneDirectoryCreate(dn, servername, username, password, errorifexists = false);
  314 + }
  315 + return null;
  316 + }
  317 + public static string OneDirectoryCreate(string directoryname, string servername, string username, string password, bool errorifexists = false)
  318 + {
  319 + var uristr = $"ftp://{servername}/{directoryname}/";
  320 + var uri = new Uri(uristr, UriKind.Absolute);
  321 + try
  322 + {
  323 + WebRequest ftprequest = WebRequest.Create(uri);
  324 + WebResponse ftpresponse = null;
  325 + ftprequest.Credentials = new NetworkCredential(username, password);
  326 + ftprequest.Method = WebRequestMethods.Ftp.MakeDirectory;
  327 + ftpresponse = ftprequest.GetResponse();
  328 + ftpresponse?.Close();
  329 + return $"//{servername}/{directoryname}/";
  330 + }
  331 + catch (Exception ex)
  332 + {
  333 + if (errorifexists) { return null; }
  334 + else
  335 + {
  336 + try
  337 + {
  338 + //if there was an error returned, check if folder already existed on server
  339 + WebRequest ftprequest = WebRequest.Create(uri);
  340 + WebResponse ftpresponse = null;
  341 + ftprequest.Credentials = new NetworkCredential(username, password);
  342 + ftprequest.Method = WebRequestMethods.Ftp.PrintWorkingDirectory;
  343 + ftpresponse = ftprequest.GetResponse();
  344 + ftpresponse?.Close();
  345 + return $"//{servername}/{directoryname}/";
  346 + }
  347 + catch (Exception exx)
  348 + {
  349 + //if the folder didn't exist, then it's probably a file perms issue, incorrect credentials, dodgy server name etc
  350 + return null;
  351 + }
  352 + }
  353 + }
  354 + }
  355 + }
  356 + }
  357 +}
... ...
Vrh.Log4Pro.MaintenanceConsole/Manager - MSMQManager.cs
... ... @@ -4,6 +4,7 @@ using System.Linq;
4 4 using System.Messaging;
5 5 using System.Text;
6 6 using System.Threading.Tasks;
  7 +using System.Net;
7 8  
8 9 using Vrh.Log4Pro.MaintenanceConsole.MenuNS;
9 10 using Vrh.Log4Pro.MaintenanceConsole.ColorConsoleNS;
... ... @@ -527,9 +528,55 @@ namespace Vrh.Log4Pro.MaintenanceConsole.MSMQManagerNS
527 528 addressprefix = string.IsNullOrWhiteSpace(addressprefix) ? "" : addressprefix;
528 529 return $"{addressprefix}{msmqservernamepart}{msmqname}";
529 530 }
  531 + public static bool ParseFullQueuePath(string qn, out string servername, out string formatname, out string queuename, out bool privatequeue, out string addresstype, out string successpattern)
  532 + {
  533 + servername = "";
  534 + successpattern = "";
  535 + formatname = "";
  536 + queuename = "";
  537 + privatequeue = false;
  538 + addresstype = null;
  539 + var patterns = new List<string>();
  540 + patterns.Add(@"^FormatName:(?'FORMATNAME'DIRECT=(?'ADDRESSTYPE'TCP|OS)):(?'SERVERNAME'.*?)\\(?'QUEUENAME'(?'PRIVATE'private\$\\).*)$");
  541 + patterns.Add(@"^FormatName:(?'FORMATNAME'DIRECT=(?'ADDRESSTYPE'TCP|OS)):(?'SERVERNAME'.*?)\\(?'QUEUENAME'.*)$");
  542 + patterns.Add(@"^(?'SERVERNAME'.*?)\\(?'QUEUENAME'(?'PRIVATE'private\$\\).*)$");
  543 + patterns.Add(@"^(?'QUEUENAME'(?'PRIVATE'private\$\\).*)$");
  544 + patterns.Add(@"^(?'SERVERNAME'.*?)\\(?'QUEUENAME'.*)$");
  545 + patterns.Add(@"^(?'QUEUENAME'.*)$");
  546 +
  547 + var pattern = string.Join("|", patterns);
  548 + foreach (var p in patterns)
  549 + {
  550 + var rm = Regex.Match(qn, p);
  551 + if (rm.Success)
  552 + {
  553 + Group rg;
  554 + rg = rm.Groups["SERVERNAME"]; if (rg.Success) { servername = rg.Value; }
  555 + rg = rm.Groups["ADDRESSTYPE"]; if (rg.Success) { addresstype = rg.Value; }
  556 + rg = rm.Groups["QUEUENAME"]; if (rg.Success) { queuename = rg.Value; }
  557 + rg = rm.Groups["PRIVATE"]; if (rg.Success) { privatequeue = true; }
  558 + rg = rm.Groups["FORMATNAME"]; if (rg.Success) { formatname = rg.Value; };
  559 + successpattern = p;
  560 + bool isip = IPAddress.TryParse(servername, out IPAddress ip);
  561 + if (servername == "" || servername == "." || servername.ToLower() == "localhost") { servername = System.Environment.MachineName; }
  562 + if (formatname == "")
  563 + {
  564 + if (isip) { formatname = @"FormatName:DIRECT=TCP"; addresstype = @"TCP"; }
  565 + else { formatname = @"FormatName:DIRECT=OS"; addresstype = @"OS"; }
  566 + }
  567 + if ((isip && addresstype=="OS") || (!isip && addresstype == "TCP")) { return false; }
  568 + return true;
  569 + }
  570 + }
  571 + return false;
  572 + }
530 573 public static bool CheckIfQueueExists(string servername,string queuefullname)
531 574 {
532 575 if (string.IsNullOrWhiteSpace(servername) || servername == "." || servername.ToLower() == "localhost") { servername = System.Environment.MachineName; }
  576 + if (servername == "*")
  577 + {
  578 + }
  579 +
533 580 var queuearray = System.Messaging.MessageQueue.GetPrivateQueuesByMachine(servername);
534 581 foreach (var q in queuearray)
535 582 {
... ...
Vrh.Log4Pro.MaintenanceConsole/Program.cs
... ... @@ -37,42 +37,14 @@ namespace Vrh.Log4Pro.MaintenanceConsole
37 37 {
38 38 static void Main(string[] args)
39 39 {
  40 + Tests.T3();
  41 + return;
  42 +
40 43 var startassystemstr = CommandLine.GetCommandLineArgument(args, CLP.CMD_STARTASSYSTEM);
41 44 var startassystem = startassystemstr!=null && startassystemstr.ToLower() == "yes";
42 45  
43 46 OtherTools.StartAsAdmin();
44 47 OtherTools.StartAsSystem(silent:startassystem);
45   - //while (true)
46   - //{
47   - // Console.Clear();
48   - // Console.Write("Enter string:"); var cp1 = Console.ReadLine();
49   - // Console.WriteLine();
50   - // Console.ForegroundColor = ConsoleColor.Red;
51   - // Console.Write(cp1); foreach (char c in cp1) { Console.Write(c); Console.Write(" => "); var i = (int)c; Console.Write(i); Console.Write(" => "); Console.Write((char)i); Console.WriteLine(); }
52   - // Console.ForegroundColor = ConsoleColor.DarkGreen;
53   - // Console.Write(cp1); foreach (char c in cp1) { Console.Write(c); Console.Write(" => "); var i = (int)c; Console.Write(i); Console.Write(" => "); Console.Write((char)i); Console.WriteLine(); }
54   - // Console.ForegroundColor = ConsoleColor.Green;
55   - // Console.Write(cp1); foreach (char c in cp1) { Console.Write(c); Console.Write(" => "); var i = (int)c; Console.Write(i); Console.Write(" => "); Console.Write((char)i); Console.WriteLine(); }
56   - // Console.ForegroundColor = ConsoleColor.DarkYellow;
57   - // Console.Write(cp1); foreach (char c in cp1) { Console.Write(c); Console.Write(" => "); var i = (int)c; Console.Write(i); Console.Write(" => "); Console.Write((char)i); Console.WriteLine(); }
58   - // Console.ForegroundColor = ConsoleColor.Yellow;
59   - // Console.Write(cp1); foreach (char c in cp1) { Console.Write(c); Console.Write(" => "); var i = (int)c; Console.Write(i); Console.Write(" => "); Console.Write((char)i); Console.WriteLine(); }
60   - // Console.ReadKey();
61   - // Console.Clear();
62   - // Console.Write("Enter Code page:"); var cp = Console.ReadLine();
63   - // try
64   - // {
65   - // Console.OutputEncoding = System.Text.Encoding.GetEncoding(int.Parse(cp));
66   - // for (int i = 0; i < 256; i++)
67   - // {
68   - // Console.Write((i).ToString().PadLeft(3) + "=> [" + (char)(i) + "] ");
69   - // if (i % 6 == 5) { Console.WriteLine(); }
70   - // //Console.Write((char)(i*j));
71   - // }
72   - // }
73   - // catch { Console.WriteLine("Code page is not supported!"); }
74   - // Console.ReadKey();
75   - //}
76 48  
77 49 var forcedmodulekey = CommandLine.GetCommandLineArgument(args, CLP.CMD_MODULE);
78 50 var commandmode = !string.IsNullOrEmpty(forcedmodulekey);
... ... @@ -109,81 +81,13 @@ namespace Vrh.Log4Pro.MaintenanceConsole
109 81 .AddMenuItem(new Menu.Item(CLP.Module.InstallManager.KEY, "Install Manager", InstallManager.Execute, new Menu.ExecutorParameter(args: args)))
110 82 .AddMenuItem(new Menu.ItemSeparator('-'))
111 83 .AddMenuItem(new Menu.Item(CLP.Module.MaintenanceToolManager.KEY, "Maintenance tools", MaintenanceToolManager.Execute, new Menu.ExecutorParameter(args: args)))
112   - .SetMenuHeaderDisplayer(DisplayComputerInfo)
  84 + .SetMenuHeaderDisplayer(ComputerInfo.DisplayThis)
113 85 .SetSelectionMode(Menu.SelectionMode.Single);
114 86  
115 87 mm.ExecuteMenu(forcedmodulekey);
116 88  
117 89 ColorConsole.PressAnykeyToContinue();
118 90 }
119   - static void DisplayComputerInfo()
120   - {
121   - const string XMLCONNECTIONSTRING = "config=MAINTENANCECONSOLE;";
122   - //const string XMLCONNECTIONSTRING_DEFAULT = "file=Config.Xml;";
123   - var config = new MaintenanceConsoleXmlProcessor(XMLCONNECTIONSTRING, "", "hu-HU");
124   -
125   - ColorConsole.WriteLine(config.Xml_Header,ConsoleColor.Yellow,bracket:"[]");
126   -
127   - //computername
128   - ColorConsole.WriteLine("");
129   - ColorConsole.Write("Computer name: ");
130   - ColorConsole.Write(System.Environment.MachineName, ConsoleColor.Yellow, bracket: "[]",prefix: "", suffix: ",");
131   - var hostname = System.Net.Dns.GetHostName();
132   - ColorConsole.Write(hostname, ConsoleColor.Yellow, bracket: "[]", prefix: "DNS hostname:");
133   - ColorConsole.WriteLine("");
134   -
135   - //username
136   - ColorConsole.Write("Username:");
137   - ColorConsole.Write(Environment.UserName, ConsoleColor.Yellow, bracket: "[]", prefix: "RunAs:", suffix: ",");
138   - ColorConsole.Write(System.Security.Principal.WindowsIdentity.GetCurrent().Name, ConsoleColor.Yellow, bracket: "[]", prefix: "LoggedIn:");
139   - ColorConsole.WriteLine("");
140   -
141   - //ip address
142   - ColorConsole.Write("IP addresses: ");
143   - var host = System.Net.Dns.GetHostEntry(hostname);
144   - foreach (var ip in host.AddressList)
145   - {
146   - if (ip.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
147   - {
148   - ColorConsole.Write(ip.ToString(), ConsoleColor.Yellow, bracket: "[]", prefix: $"{ip.AddressFamily}:",suffix: ",");
149   - }
150   - }
151   - ColorConsole.WriteLine("");
152   -
153   - // processor architecture
154   - ColorConsole.Write("Processors: ");
155   - ColorConsole.Write(System.Environment.GetEnvironmentVariable("PROCESSOR_ARCHITECTURE"), ConsoleColor.Yellow, bracket: "[]", prefix: "Architecture: ");
156   - ColorConsole.Write(Tools.GetOSType() ?? "N/A", ConsoleColor.Yellow, bracket: "[]", suffix: ", ");
157   - foreach (var item in new System.Management.ManagementObjectSearcher("Select * from Win32_ComputerSystem").Get())
158   - {
159   - ColorConsole.Write(item["NumberOfProcessors"].ToString(), ConsoleColor.Yellow, bracket: "[]", prefix: "Physical:",suffix:", ");
160   - ColorConsole.Write(item["NumberOfLogicalProcessors"].ToString(), ConsoleColor.Yellow, bracket: "[]", prefix: "Logical:", suffix: ", ");
161   - }
162   -
163   - int coreCount = 0;
164   - foreach (var item in new System.Management.ManagementObjectSearcher("Select * from Win32_Processor").Get())
165   - {
166   - coreCount += int.Parse(item["NumberOfCores"].ToString());
167   - }
168   - ColorConsole.Write(coreCount.ToString(), ConsoleColor.Yellow, bracket: "[]", prefix: "Cores:");
169   - ColorConsole.WriteLine("");
170   -
171   - // os version
172   - ColorConsole.Write("Operating system: ");
173   - ColorConsole.Write(System.Environment.OSVersion.Platform.ToString(), ConsoleColor.Yellow, bracket: "[]", prefix: "Platform:",suffix: ",");
174   - ColorConsole.Write(System.Environment.OSVersion.ServicePack, ConsoleColor.Yellow, bracket: "[]", prefix: "Service pack:", suffix: ",");
175   - ColorConsole.Write(System.Environment.OSVersion.VersionString, ConsoleColor.Yellow, bracket: "[]", prefix: "Version string:");
176   - ColorConsole.WriteLine("");
177   -
178   - ColorConsole.Write("", ConsoleColor.Yellow, prefix: "OS Friendly name versions:");
179   - string fnA = Tools.GetOSFriendlyNameA(); if (!string.IsNullOrWhiteSpace(fnA)) ColorConsole.Write(fnA, ConsoleColor.Yellow, bracket: "[]");
180   - string fnB = Tools.GetOSFriendlyNameB(); if (!string.IsNullOrWhiteSpace(fnB) && fnB!=fnA) ColorConsole.Write(fnB, ConsoleColor.Yellow, bracket: "[]");
181   - string fnC = Tools.GetOSFriendlyNameC(); if (!string.IsNullOrWhiteSpace(fnC) && fnC!=fnA && fnC!=fnB) ColorConsole.Write(fnC, ConsoleColor.Yellow, bracket: "[]");
182   - if (string.IsNullOrWhiteSpace(fnA) && string.IsNullOrWhiteSpace(fnB) && string.IsNullOrWhiteSpace(fnC)) ColorConsole.Write("N/A", ConsoleColor.Yellow, bracket: "[]");
183   - ColorConsole.WriteLine("");
184   - ColorConsole.WriteLine("");
185   - ColorConsole.WriteLine("");
186   - }
187 91 }
188 92  
189 93 #region MaintenanceConsoleXmlProcessor class
... ...
Vrh.Log4Pro.MaintenanceConsole/Properties/AssemblyInfo.cs
... ... @@ -32,5 +32,5 @@ using System.Runtime.InteropServices;
32 32 // You can specify all the values or you can default the Build and Revision Numbers
33 33 // by using the '*' as shown below:
34 34 // [assembly: AssemblyVersion("1.0.*")]
35   -[assembly: AssemblyVersion("1.9.2.0")]
36   -[assembly: AssemblyFileVersion("1.9.2.0")]
  35 +[assembly: AssemblyVersion("1.9.3.0")]
  36 +[assembly: AssemblyFileVersion("1.9.3.0")]
... ...
Vrh.Log4Pro.MaintenanceConsole/Tests.cs 0 → 100644
... ... @@ -0,0 +1,127 @@
  1 +using System;
  2 +using System.Collections.Generic;
  3 +using System.Linq;
  4 +using System.Text;
  5 +using System.Threading.Tasks;
  6 +using System.Threading;
  7 +
  8 +using Microsoft.Web.Administration;
  9 +using System.Management;
  10 +using System.Diagnostics;
  11 +
  12 +using Vrh.Log4Pro.MaintenanceConsole.ColorConsoleNS;
  13 +using Vrh.Log4Pro.MaintenanceConsole.MenuNS;
  14 +using Vrh.Log4Pro.MaintenanceConsole.ToolsNS;
  15 +
  16 +using Vrh.Log4Pro.MaintenanceConsole.WebApplicationManagerNS;
  17 +using Vrh.Log4Pro.MaintenanceConsole.WindowsServiceManagerNS;
  18 +using Vrh.Log4Pro.MaintenanceConsole.BackupPackageManagerNS;
  19 +using Vrh.Log4Pro.MaintenanceConsole.SQLDataBaseManagerNS;
  20 +using Vrh.Log4Pro.MaintenanceConsole.ScheduledTaskManagerNS;
  21 +using Vrh.Log4Pro.MaintenanceConsole.MSMQManagerNS;
  22 +using Vrh.Log4Pro.MaintenanceConsole.FileCleanerManagerNS;
  23 +using Vrh.Log4Pro.MaintenanceConsole.MaintenanceToolManagerNS;
  24 +using Vrh.Log4Pro.MaintenanceConsole.UserManagerNS;
  25 +using Vrh.Log4Pro.MaintenanceConsole.InstallManagerNS;
  26 +
  27 +using Vrh.Log4Pro.MaintenanceConsole.CommandLineParserNS;
  28 +
  29 +using Vrh.XmlProcessing;
  30 +using VRH.Common;
  31 +using System.Xml.Linq;
  32 +using System.Reflection;
  33 +
  34 +namespace Vrh.Log4Pro.MaintenanceConsole
  35 +{
  36 + static class Tests
  37 + {
  38 + public static void T3()
  39 + {
  40 + FTPManagerCore.FTPFileList dl;
  41 + dl = new FTPManagerCore.FTPFileList("web.vonalkod.hu", "web.vonalkod.hu", "r9e2fejxHhVh");
  42 + dl.SetRootDirectories("LEAR", "c:\\temp");
  43 +
  44 + dl.BuildForDownload("", recurse: true, filterregex: @"ETALON150\\.*\.pdf", filterregexappliedtopath: true, filterregextoexclude: false);
  45 + dl.DisplayFTP();
  46 + dl.Download("TEST");
  47 +
  48 +
  49 +
  50 + dl.BuildForUpload("", recurse: true, filterregex: ".pdf", filterregexappliedtopath: false, filterregextoexclude: false);
  51 + dl.DisplayLocal();
  52 + dl.Upload("TEST");
  53 + //Console.ReadKey();
  54 +
  55 + Console.ReadKey();
  56 + }
  57 + public static void T2()
  58 + {
  59 + var queuenames = new List<string>();
  60 + queuenames.Add(@"FormatName:DIRECT=OS:192.168.77.150\private$\LJSKSKIN");
  61 + queuenames.Add(@"FormatName:DIRECT=TCP:SERVERNAME\private$\LJSKSKIN");
  62 + queuenames.Add(@"FormatName:DIRECT=TCP:192.168.77.150\private$\LJSKSKIN");
  63 + queuenames.Add(@"FormatName:DIRECT=OS:SERVERNAME\private$\LJSKSKIN");
  64 + queuenames.Add(@"FormatName:DIRECT=OS:SERVERNAME\LJSKSKIN");
  65 + queuenames.Add(@"FormatName:DIRECT=TCP:192.168.77.150\LJSKSKIN");
  66 + queuenames.Add(@"localhost\private$\LJSKSKIN");
  67 + queuenames.Add(@".\private$\LJSKSKIN");
  68 + queuenames.Add(@"SERVERNAME\private$\LJSKSKIN");
  69 + queuenames.Add(@"localhost\LJSKSKIN");
  70 + queuenames.Add(@".\LJSKSKIN");
  71 + queuenames.Add(@"SERVERNAME\LJSKSKIN");
  72 + queuenames.Add(@"private$\LJSKSKIN");
  73 + queuenames.Add(@"LJSKSKIN");
  74 +
  75 + foreach (var qname in queuenames)
  76 + {
  77 + var success = MSMQManagerCore.ParseFullQueuePath(qname, out string sn, out string fn, out string qn, out bool pq, out string at, out string p);
  78 + if (success)
  79 + {
  80 + Console.WriteLine($"'{qname}' parsing SUCCESS!");
  81 + if (!string.IsNullOrWhiteSpace(sn)) Console.WriteLine($"SERVERNAME:{sn}");
  82 + if (!string.IsNullOrWhiteSpace(qn)) Console.WriteLine($"QUEUENAME:{qn}");
  83 + if (pq) Console.WriteLine($"PRIVATE");
  84 + if (!string.IsNullOrWhiteSpace(at)) Console.WriteLine($"ADDRESSTYPE:{at}");
  85 + if (!string.IsNullOrWhiteSpace(fn)) Console.WriteLine($"FORMATNAME:{fn}");
  86 + if (!string.IsNullOrWhiteSpace(p)) Console.WriteLine($"SUCCESSPATTERN:{p}");
  87 + Console.WriteLine();
  88 + }
  89 + else { Console.WriteLine($"'{qn}' parsing FAILED!"); }
  90 + }
  91 + }
  92 + public static void T1()
  93 + {
  94 + while (true)
  95 + {
  96 + Console.Clear();
  97 + Console.Write("Enter string:"); var cp1 = Console.ReadLine();
  98 + Console.WriteLine();
  99 + Console.ForegroundColor = ConsoleColor.Red;
  100 + Console.Write(cp1); foreach (char c in cp1) { Console.Write(c); Console.Write(" => "); var i = (int)c; Console.Write(i); Console.Write(" => "); Console.Write((char)i); Console.WriteLine(); }
  101 + Console.ForegroundColor = ConsoleColor.DarkGreen;
  102 + Console.Write(cp1); foreach (char c in cp1) { Console.Write(c); Console.Write(" => "); var i = (int)c; Console.Write(i); Console.Write(" => "); Console.Write((char)i); Console.WriteLine(); }
  103 + Console.ForegroundColor = ConsoleColor.Green;
  104 + Console.Write(cp1); foreach (char c in cp1) { Console.Write(c); Console.Write(" => "); var i = (int)c; Console.Write(i); Console.Write(" => "); Console.Write((char)i); Console.WriteLine(); }
  105 + Console.ForegroundColor = ConsoleColor.DarkYellow;
  106 + Console.Write(cp1); foreach (char c in cp1) { Console.Write(c); Console.Write(" => "); var i = (int)c; Console.Write(i); Console.Write(" => "); Console.Write((char)i); Console.WriteLine(); }
  107 + Console.ForegroundColor = ConsoleColor.Yellow;
  108 + Console.Write(cp1); foreach (char c in cp1) { Console.Write(c); Console.Write(" => "); var i = (int)c; Console.Write(i); Console.Write(" => "); Console.Write((char)i); Console.WriteLine(); }
  109 + Console.ReadKey();
  110 + Console.Clear();
  111 + Console.Write("Enter Code page:"); var cp = Console.ReadLine();
  112 + try
  113 + {
  114 + Console.OutputEncoding = System.Text.Encoding.GetEncoding(int.Parse(cp));
  115 + for (int i = 0; i < 256; i++)
  116 + {
  117 + Console.Write((i).ToString().PadLeft(3) + "=> [" + (char)(i) + "] ");
  118 + if (i % 6 == 5) { Console.WriteLine(); }
  119 + //Console.Write((char)(i*j));
  120 + }
  121 + }
  122 + catch { Console.WriteLine("Code page is not supported!"); }
  123 + Console.ReadKey();
  124 + }
  125 + }
  126 + }
  127 +}
... ...
Vrh.Log4Pro.MaintenanceConsole/Vrh.Log4Pro.MaintenanceConsole.csproj
... ... @@ -357,6 +357,7 @@
357 357 <Compile Include="ConsoleFunction - Menu.cs" />
358 358 <Compile Include="ConsoleFunction - Tools - Membership.cs" />
359 359 <Compile Include="ConsoleFunction - Tools.cs" />
  360 + <Compile Include="Manager - FTPManager.cs" />
360 361 <Compile Include="Manager - BackupPackageManager.cs" />
361 362 <Compile Include="Manager - InstallManager.cs" />
362 363 <Compile Include="Manager - MSMQManager.cs" />
... ... @@ -367,6 +368,7 @@
367 368 <Compile Include="Manager - FileCleanerManager.cs" />
368 369 <Compile Include="Manager - MaintenanceToolManager.cs" />
369 370 <Compile Include="Manager - WebApplicationManager.cs" />
  371 + <Compile Include="Tests.cs" />
370 372 <Compile Include="Program.cs" />
371 373 <Compile Include="Properties\AssemblyInfo.cs" />
372 374 </ItemGroup>
... ...