[.NET][C#] Manager with singleton for manipulate the Windows Hosts File


SUBMITTED BY: Guest

DATE: Dec. 7, 2013, 4:47 p.m.

FORMAT: Text only

SIZE: 13.3 kB

HITS: 51524

  1. [.NET][C#] Manager with singleton for manipulate the Windows Hosts File
  2. using System;
  3. using System.Collections.Generic;
  4. using System.Linq;
  5. using System.Text;
  6. using System.IO;
  7. using System.Text.RegularExpressions;
  8. namespace Framework
  9. {
  10. public class ManagerHostFile
  11. {
  12. #region singleton
  13. private static ManagerHostFile instance = null;
  14. private static readonly object padlock = new object();
  15. ManagerHostFile()
  16. {
  17. }
  18. public static ManagerHostFile Instance
  19. {
  20. get
  21. {
  22. lock (padlock)
  23. {
  24. if (instance == null)
  25. {
  26. instance = new ManagerHostFile();
  27. }
  28. hostList = ParseHostsFile(ref noHosts);
  29. return instance;
  30. }
  31. }
  32. }
  33. #endregion singleton
  34. private IList<stHost> hostList = new IList<stHost>();
  35. #region General Methods
  36. private string GetHostsPath()
  37. {
  38. // Gets dynamic hosts path from system folder
  39. string systemPath = Environment.GetFolderPath(Environment.SpecialFolder.System);
  40. string hostsPath = Path.Combine(systemPath, @"drivers\etc");
  41. return hostsPath;
  42. }
  43. private string GetHostsFilename()
  44. {
  45. // Creates full host filename
  46. string hostsFileName = Path.Combine(GetHostsPath(), "hosts");
  47. return hostsFileName;
  48. }
  49. private bool StartWithNumber(string str)
  50. {
  51. // Check if string starts with an ip number
  52. Regex regex = new Regex(@"^\d{1}");
  53. return regex.IsMatch(str);
  54. }
  55. private bool StartWithNumberCommented(string str)
  56. {
  57. // Check if strings starts with a commented ip number
  58. Regex regex = new Regex(@"^#{1}\d{1}");
  59. return regex.IsMatch(str);
  60. }
  61. #endregion
  62. private struct stHost
  63. {
  64. public string HostDescription;
  65. public string HostComment;
  66. public string IP;
  67. public bool Selected;
  68. }
  69. ///
  70. /// Parse Windows Host File
  71. ///
  72. private IList<stHost> ParseHostsFile(ref bool noHosts)
  73. {
  74. noHosts = true;
  75. IList<string> lineList = new List<string>();
  76. IList<stHost> hostList = new List<stHost>();
  77. try
  78. {
  79. // Reads all lines from hosts file
  80. FileInfo fileInfo = new FileInfo(GetHostsFilename());
  81. StreamReader sr = fileInfo.OpenText();
  82. while (sr.EndOfStream == false)
  83. {
  84. string line = sr.ReadLine();
  85. line = line.Trim();
  86. //if (string.IsNullOrEmpty(line) == false)
  87. {
  88. lineList.Add(line.Replace("\t", " ").Replace("\r", " ").Replace("\n", " "));
  89. }
  90. }
  91. sr.Close();
  92. // Creates a host list
  93. for (int f = 0; f < lineList.Count; f++)
  94. {
  95. // If we found an host entry with a comment in the line before, ex:
  96. //
  97. // # DIT - x.acme.com [host comment]
  98. // #38.25.63.10 acme [host ip] [host address]
  99. //
  100. if (lineList[f].StartsWith("# ") &&
  101. (f + 1) < lineList.Count &&
  102. (StartWithNumberCommented(lineList[f + 1]) || StartWithNumber(lineList[f + 1])))
  103. {
  104. // Get host comment
  105. string hostComment = lineList[f].Replace("# ", "");
  106. // Retrieve host details line
  107. string hostDetailsLine = lineList[f + 1];
  108. // Get host IP
  109. string hostIp = hostDetailsLine.Replace("#", "");
  110. if (hostIp.IndexOf(" ") > -1)
  111. {
  112. hostIp = hostIp.Substring(0, hostIp.IndexOf(" "));
  113. }
  114. // Get host address
  115. string hostAddress = string.Empty;
  116. if ((hostDetailsLine.IndexOf(" ") > -1) && hostDetailsLine.IndexOf(" ") < hostDetailsLine.Length)
  117. {
  118. hostAddress = hostDetailsLine.Substring(hostDetailsLine.IndexOf(" ")).Trim();
  119. }
  120. // Creates the host description with comment, addresss and IP
  121. string hostDescription = hostComment + " [" + hostAddress + " at " + hostIp + "]";
  122. // Check if host is not commented out
  123. bool selected = StartWithNumber(hostDetailsLine);
  124. // Search for repeated IP entries
  125. bool hostAlreadyExists = false;
  126. foreach (stHost hostItemSearch in hostList)
  127. {
  128. if (hostItemSearch.IP == hostIp)
  129. {
  130. hostAlreadyExists = true;
  131. }
  132. }
  133. // Make sure we don´t add repeated IP entries
  134. // And also only entries with host IP and host address
  135. if (hostAlreadyExists == false &&
  136. string.IsNullOrEmpty(hostIp) == false &&
  137. string.IsNullOrEmpty(hostAddress) == false)
  138. {
  139. // Create and add new host object to the list
  140. stHost hostItem = new stHost();
  141. hostItem.HostDescription = hostDescription;
  142. hostItem.HostComment = hostComment;
  143. hostItem.IP = hostIp;
  144. hostItem.Selected = selected;
  145. hostList.Add(hostItem);
  146. // If we found a single selected host, no hosts menu option can´t be enabled
  147. if (selected)
  148. {
  149. noHosts = false;
  150. }
  151. }
  152. }
  153. else if ((StartWithNumberCommented(lineList[f]) || StartWithNumber(lineList[f])) &&
  154. (f - 1) >= 0 &&
  155. lineList[f - 1].StartsWith("# ") == false)
  156. {
  157. // Parse strings in both formats:
  158. //
  159. // #102.54.94.97 rhino.acme.com # Rhino server [host ip] [host address] [host comment]
  160. //
  161. // #10.4.2.4 www.test1234567.com [host ip] [host address]
  162. //
  163. // Retrieve host ip
  164. string hostIp = lineList[f].Replace("#", "");
  165. if (hostIp.IndexOf(" ") > -1)
  166. {
  167. hostIp = hostIp.Substring(0, hostIp.IndexOf(" "));
  168. }
  169. // Gets host address and comment
  170. string hostFullText = string.Empty;
  171. if (lineList[f].IndexOf(" ") > -1)
  172. {
  173. hostFullText = lineList[f].Substring(lineList[f].IndexOf(" ") + 1).TrimStart();
  174. }
  175. // Gets only host address
  176. string hostAddress = hostFullText;
  177. if (hostFullText.IndexOf(" ") > -1)
  178. {
  179. hostAddress = hostFullText.Substring(0, hostFullText.IndexOf(" ")).Trim();
  180. }
  181. // Gets only host comment
  182. string hostComment = string.Empty;
  183. if (hostFullText.IndexOf("#") > -1 && ((hostFullText.IndexOf("#") + 1) < hostFullText.Length))
  184. {
  185. hostComment = hostFullText.Substring(hostFullText.IndexOf("#") + 1).Trim();
  186. }
  187. // Creates the host description with comment, addresss and IP
  188. string hostDescription = hostComment + " [" + hostAddress + " at " + hostIp + "]";
  189. // Check if host is not commented out
  190. bool selected = StartWithNumber(lineList[f]);
  191. // Search for repeated IP entries
  192. bool hostAlreadyExists = false;
  193. foreach (stHost hostItemSearch in hostList)
  194. {
  195. if (hostItemSearch.IP == hostIp)
  196. {
  197. hostAlreadyExists = true;
  198. }
  199. }
  200. // Make sure we don´t add repeated IP entries
  201. // And also only entries with host IP and host address
  202. if (hostAlreadyExists == false &&
  203. string.IsNullOrEmpty(hostIp) == false &&
  204. string.IsNullOrEmpty(hostAddress) == false)
  205. {
  206. // Create and add new host object to the list
  207. stHost hostItem = new stHost();
  208. hostItem.HostDescription = hostDescription;
  209. hostItem.HostComment = hostComment;
  210. hostItem.IP = hostIp;
  211. hostItem.Selected = selected;
  212. hostList.Add(hostItem);
  213. // If we found a single selected host, no hosts menu option can´t be enabled
  214. if (selected)
  215. {
  216. noHosts = false;
  217. }
  218. }
  219. }
  220. }
  221. }
  222. catch (Exception ex)
  223. {
  224. throw ex;
  225. }
  226. return hostList;
  227. }
  228. /// <summary>
  229. /// Update HostFile
  230. /// </summary>
  231. /// <param name="ipHost"></param>
  232. public void UpdateHosts(string ipHost)
  233. {
  234. try
  235. {
  236. StringBuilder sbHostsNew = new StringBuilder();
  237. // Read hosts file
  238. FileInfo fileInfo = new FileInfo(GetHostsFilename());
  239. StreamReader sr = fileInfo.OpenText();
  240. while (sr.EndOfStream == false)
  241. {
  242. string line = sr.ReadLine();
  243. // Check if we found selected host commented out
  244. if (string.IsNullOrEmpty(ipHost) == false &&
  245. line.Contains(ipHost) &&
  246. line.StartsWith("#" + ipHost))
  247. {
  248. // Uncomment selected host
  249. line = line.Substring(1);
  250. }
  251. else if (((string.IsNullOrEmpty(ipHost) == false) && (line.Contains(ipHost) == false)) ||
  252. string.IsNullOrEmpty(ipHost) == true)
  253. {
  254. // Comment out other entries except already uncommend host entry
  255. if (StartWithNumber(line))
  256. {
  257. line = "#" + line;
  258. }
  259. }
  260. sbHostsNew.Append(line + "\r\n");
  261. }
  262. sr.Close();
  263. // Saves new host file and prevent file watcher from raising event
  264. TextWriter tw = new StreamWriter(GetHostsFilename());
  265. tw.Write(sbHostsNew.ToString());
  266. tw.Flush();
  267. tw.Close();
  268. }
  269. catch (Exception ex)
  270. {
  271. throw ex;
  272. }
  273. }
  274. }
  275. }

comments powered by Disqus