[.NET][C#] Manager with singleton for manipulate the Windows Hosts File using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.IO; using System.Text.RegularExpressions; namespace Framework { public class ManagerHostFile { #region singleton private static ManagerHostFile instance = null; private static readonly object padlock = new object(); ManagerHostFile() { } public static ManagerHostFile Instance { get { lock (padlock) { if (instance == null) { instance = new ManagerHostFile(); } hostList = ParseHostsFile(ref noHosts); return instance; } } } #endregion singleton private IList hostList = new IList(); #region General Methods private string GetHostsPath() { // Gets dynamic hosts path from system folder string systemPath = Environment.GetFolderPath(Environment.SpecialFolder.System); string hostsPath = Path.Combine(systemPath, @"drivers\etc"); return hostsPath; } private string GetHostsFilename() { // Creates full host filename string hostsFileName = Path.Combine(GetHostsPath(), "hosts"); return hostsFileName; } private bool StartWithNumber(string str) { // Check if string starts with an ip number Regex regex = new Regex(@"^\d{1}"); return regex.IsMatch(str); } private bool StartWithNumberCommented(string str) { // Check if strings starts with a commented ip number Regex regex = new Regex(@"^#{1}\d{1}"); return regex.IsMatch(str); } #endregion private struct stHost { public string HostDescription; public string HostComment; public string IP; public bool Selected; } /// /// Parse Windows Host File /// private IList ParseHostsFile(ref bool noHosts) { noHosts = true; IList lineList = new List(); IList hostList = new List(); try { // Reads all lines from hosts file FileInfo fileInfo = new FileInfo(GetHostsFilename()); StreamReader sr = fileInfo.OpenText(); while (sr.EndOfStream == false) { string line = sr.ReadLine(); line = line.Trim(); //if (string.IsNullOrEmpty(line) == false) { lineList.Add(line.Replace("\t", " ").Replace("\r", " ").Replace("\n", " ")); } } sr.Close(); // Creates a host list for (int f = 0; f < lineList.Count; f++) { // If we found an host entry with a comment in the line before, ex: // // # DIT - x.acme.com [host comment] // #38.25.63.10 acme [host ip] [host address] // if (lineList[f].StartsWith("# ") && (f + 1) < lineList.Count && (StartWithNumberCommented(lineList[f + 1]) || StartWithNumber(lineList[f + 1]))) { // Get host comment string hostComment = lineList[f].Replace("# ", ""); // Retrieve host details line string hostDetailsLine = lineList[f + 1]; // Get host IP string hostIp = hostDetailsLine.Replace("#", ""); if (hostIp.IndexOf(" ") > -1) { hostIp = hostIp.Substring(0, hostIp.IndexOf(" ")); } // Get host address string hostAddress = string.Empty; if ((hostDetailsLine.IndexOf(" ") > -1) && hostDetailsLine.IndexOf(" ") < hostDetailsLine.Length) { hostAddress = hostDetailsLine.Substring(hostDetailsLine.IndexOf(" ")).Trim(); } // Creates the host description with comment, addresss and IP string hostDescription = hostComment + " [" + hostAddress + " at " + hostIp + "]"; // Check if host is not commented out bool selected = StartWithNumber(hostDetailsLine); // Search for repeated IP entries bool hostAlreadyExists = false; foreach (stHost hostItemSearch in hostList) { if (hostItemSearch.IP == hostIp) { hostAlreadyExists = true; } } // Make sure we don´t add repeated IP entries // And also only entries with host IP and host address if (hostAlreadyExists == false && string.IsNullOrEmpty(hostIp) == false && string.IsNullOrEmpty(hostAddress) == false) { // Create and add new host object to the list stHost hostItem = new stHost(); hostItem.HostDescription = hostDescription; hostItem.HostComment = hostComment; hostItem.IP = hostIp; hostItem.Selected = selected; hostList.Add(hostItem); // If we found a single selected host, no hosts menu option can´t be enabled if (selected) { noHosts = false; } } } else if ((StartWithNumberCommented(lineList[f]) || StartWithNumber(lineList[f])) && (f - 1) >= 0 && lineList[f - 1].StartsWith("# ") == false) { // Parse strings in both formats: // // #102.54.94.97 rhino.acme.com # Rhino server [host ip] [host address] [host comment] // // #10.4.2.4 www.test1234567.com [host ip] [host address] // // Retrieve host ip string hostIp = lineList[f].Replace("#", ""); if (hostIp.IndexOf(" ") > -1) { hostIp = hostIp.Substring(0, hostIp.IndexOf(" ")); } // Gets host address and comment string hostFullText = string.Empty; if (lineList[f].IndexOf(" ") > -1) { hostFullText = lineList[f].Substring(lineList[f].IndexOf(" ") + 1).TrimStart(); } // Gets only host address string hostAddress = hostFullText; if (hostFullText.IndexOf(" ") > -1) { hostAddress = hostFullText.Substring(0, hostFullText.IndexOf(" ")).Trim(); } // Gets only host comment string hostComment = string.Empty; if (hostFullText.IndexOf("#") > -1 && ((hostFullText.IndexOf("#") + 1) < hostFullText.Length)) { hostComment = hostFullText.Substring(hostFullText.IndexOf("#") + 1).Trim(); } // Creates the host description with comment, addresss and IP string hostDescription = hostComment + " [" + hostAddress + " at " + hostIp + "]"; // Check if host is not commented out bool selected = StartWithNumber(lineList[f]); // Search for repeated IP entries bool hostAlreadyExists = false; foreach (stHost hostItemSearch in hostList) { if (hostItemSearch.IP == hostIp) { hostAlreadyExists = true; } } // Make sure we don´t add repeated IP entries // And also only entries with host IP and host address if (hostAlreadyExists == false && string.IsNullOrEmpty(hostIp) == false && string.IsNullOrEmpty(hostAddress) == false) { // Create and add new host object to the list stHost hostItem = new stHost(); hostItem.HostDescription = hostDescription; hostItem.HostComment = hostComment; hostItem.IP = hostIp; hostItem.Selected = selected; hostList.Add(hostItem); // If we found a single selected host, no hosts menu option can´t be enabled if (selected) { noHosts = false; } } } } } catch (Exception ex) { throw ex; } return hostList; } /// /// Update HostFile /// /// public void UpdateHosts(string ipHost) { try { StringBuilder sbHostsNew = new StringBuilder(); // Read hosts file FileInfo fileInfo = new FileInfo(GetHostsFilename()); StreamReader sr = fileInfo.OpenText(); while (sr.EndOfStream == false) { string line = sr.ReadLine(); // Check if we found selected host commented out if (string.IsNullOrEmpty(ipHost) == false && line.Contains(ipHost) && line.StartsWith("#" + ipHost)) { // Uncomment selected host line = line.Substring(1); } else if (((string.IsNullOrEmpty(ipHost) == false) && (line.Contains(ipHost) == false)) || string.IsNullOrEmpty(ipHost) == true) { // Comment out other entries except already uncommend host entry if (StartWithNumber(line)) { line = "#" + line; } } sbHostsNew.Append(line + "\r\n"); } sr.Close(); // Saves new host file and prevent file watcher from raising event TextWriter tw = new StreamWriter(GetHostsFilename()); tw.Write(sbHostsNew.ToString()); tw.Flush(); tw.Close(); } catch (Exception ex) { throw ex; } } } }