基本信息
源码名称:Hosts文件管理工具源码下载
源码大小:0.07M
文件格式:.zip
开发语言:C#
更新时间:2013-10-14
友情提示:(无需注册或充值,赞助后即可获取资源下载链接)
嘿,亲!知识可是无价之宝呢,但咱这精心整理的资料也耗费了不少心血呀。小小地破费一下,绝对物超所值哦!如有下载和支付问题,请联系我们QQ(微信同号):78630559
本次赞助数额为: 2 元×
微信扫码支付:2 元
×
请留下您的邮箱,我们将在2小时内将文件发到您的邮箱
源码介绍
/*
* 网址:http://www.afuhao.com/article.aspx?articleId=84&articleGroupId=42
* 作者:符号
* Q Q:254186917
* 邮箱:service@afuhao.com
*
*/
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
namespace Symbol.Net {
/// <summary>
/// hosts文件管理类,%windir%\system32\drivers\etc\hosts
/// </summary>
public static class HostsManager {
#region classes
/// <summary>
/// 行
/// </summary>
public class Line {
/// <summary>
/// 备注
/// </summary>
public string Comment { get; set; }
public override string ToString() {
return Comment;
}
}
/// <summary>
/// 主机映射
/// </summary>
public class HostLine : Line {
/// <summary>
/// IP地址
/// </summary>
public string IP { get; set; }
/// <summary>
/// 域名
/// </summary>
public string Domain { get; set; }
public override string ToString() {
//用Builder的原因是,String.Format 内部也是用的它
StringBuilder sb = new StringBuilder();
//IP和域名之间有空格的
sb.Append(IP).Append(' ').Append(Domain);
//没有备注,就不要多弄出一点东西来
if (!string.IsNullOrEmpty(Comment))
sb.Append(" #").Append(Comment);
return sb.ToString();
}
}
#endregion
/// <summary>
/// 由于这是系统唯一的一个文件,所以会用到锁,目的是保证同一时刻只有一个人在修改,以免改乱了
/// </summary>
private static readonly object _syncObject = new object();
private static readonly string _path;
/// <summary>
/// 用于匹配的正则表达式,以免每次都new,省事,另外兼容IPV6
/// </summary>
private static readonly System.Text.RegularExpressions.Regex _regex =
new System.Text.RegularExpressions.Regex(@"^\s*([\:0-9a-f\.] )\s ([a-zA-Z0-9_\-\.] )\s*[#]*(.*)$");
#region HostsManager
static HostsManager() {
//用statuc readonly 是为了不让内存回收把变量的值清掉了,在Web中经常要注意这个问题,不然你会死得很惨
//得到系统目录,貌似直接用%windir%也可以,为了安全起见,这里多做点事吧
_path= GetFolderPath(36);
//定位文件
_path = Path.Combine(_path, "system32\\drivers\\etc\\hosts");
}
//下面这个函数是从系统库中得来的,它不支持Windows这个选项,对应值是36,所以我改造了它,直接用数字了,在.NET 3.5是支持的。
[System.Security.SecuritySafeCritical]
public static string GetFolderPath(int folder) {
StringBuilder lpszPath = new StringBuilder(260);
Type type = Type.GetType("Microsoft.Win32.Win32Native, mscorlib");
int num = (int)type.InvokeMember("SHGetFolderPath", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.InvokeMethod, null, null, new object[]{
IntPtr.Zero,(folder | 0), IntPtr.Zero, 0, lpszPath
});
if (num < 0) {
switch (num) {
case -2146233031:
throw new PlatformNotSupportedException();
}
}
string path = lpszPath.ToString();
return path;
}
#endregion
#region List
/// <summary>
/// 获取域名映射列表(如果有重复的映射,将不会去除重复。)
/// </summary>
/// <returns>返回域名映射列表</returns>
public static List<HostLine> List() {
lock (_syncObject) {
//先得到所有的行
List<Line> list = ListInternal();
List<HostLine> result = new List<HostLine>();
HostLine hostLine=null;
//过滤掉不是主机映射的行
foreach (Line line in list) {
hostLine = line as HostLine;
if (hostLine != null)
result.Add(hostLine);
}
list = null;
return result;
}
}
private static List<Line> ListInternal() {
List<Line> list = new List<Line>();
using (StreamReader reader = new StreamReader(_path,Encoding.Default)) {
string line = null;
System.Text.RegularExpressions.Match match = null;
bool normal = false;
while ((line = reader.ReadLine()) != null) {
normal = !string.IsNullOrEmpty(line);
//如果不是空行,看看是不是以#开头,因为这样就是整行为注释
if (normal && line.Trim().StartsWith("#"))
normal = false;
//如果正常,再检查一下是否是一行映射
if (normal)
normal = _regex.IsMatch(line);
if (normal) {
match = _regex.Match(line);
list.Add(new HostLine() {
IP = match.Groups[1].Value,
Domain = match.Groups[2].Value,
Comment = match.Groups[3].Value,
});
} else {
//这是一条普通行
list.Add(new Line() { Comment = line });
}
}
}
return list;
}
#endregion
#region Add
/// <summary>
/// 添加一个域名映射,如果存在同样的域名,自动替换旧的IP
/// </summary>
/// <param name="ip">需要绑定的IP</param>
/// <param name="domain">需要映射的域名</param>
public static void Add(string ip, string domain) {
Add(ip, domain, null);
}
/// <summary>
/// 添加一个域名映射,如果存在同样的域名,自动替换旧的IP
/// </summary>
/// <param name="ip">需要绑定的IP</param>
/// <param name="domain">需要映射的域名</param>
/// <param name="comment">备注信息</param>
public static void Add(string ip, string domain,string comment) {
if (string.IsNullOrEmpty(ip)) {
throw new ArgumentNullException("ip", "IP地址不能为空");
}
if (string.IsNullOrEmpty(domain)) {
throw new ArgumentNullException("domain", "域名不能为空");
}
lock (_syncObject) {
List<Line> list = ListInternal();
HostLine hostLine = null;
bool changed = false;
bool find = false;
foreach (Line line in list) {
hostLine = line as HostLine;
//如果不是行就跳过了
if (hostLine == null)
continue;
//如果域名匹配就处理,因为一个域名不能映射多个IP,要不然你访问哪一个IP呢?
if (hostLine.Domain.Equals(domain, StringComparison.OrdinalIgnoreCase)) {
find = true;//标记找到了
//如果IP不同就修改,这样以免多次写入文件,对系统不好
if (!hostLine.IP.Equals(ip)) {
hostLine.IP = ip;
changed = true;
}
//如果注释不一样也修改,
if (!string.Equals(hostLine.Comment, comment, StringComparison.OrdinalIgnoreCase)) {
hostLine.Comment = comment;
changed = true;
}
break;
}
}
//没找到就新加一条了
if (!find) {
list.Add(new HostLine() {
IP = ip,
Domain = domain,
Comment = comment,
});
changed = true;
}
//如果有修改就保存
if (changed)
Save(list);
}
}
#endregion
#region Save
private static void Save(List<Line> list) {
//if (File.Exists(_path)) {
// File.SetAttributes(_path, FileAttributes.Normal);
// File.Delete(_path);
//}
using (StreamWriter writer = new StreamWriter(_path, false, Encoding.Default)) {
//所有的都是行,所以一行一行的保存就行了,这里用了多态,每一行自己去处理如何输出
foreach (Line line in list) {
writer.WriteLine(line.ToString());
}
}
//string[] lines = new string[list.Count];
//for(int i=0;i<lines.Length;i ){
// lines[i] = list[i].ToString();
//}
//File.WriteAllLines(_path, lines, Encoding.Default);
}
#endregion
#region RemoveByIP
/// <summary>
/// 移除映射:通过IP地址
/// </summary>
/// <param name="ip">IP地址,只要匹配此IP映射都会被移除</param>
public static void RemoveByIP(string ip) {
if (string.IsNullOrEmpty(ip)) {
throw new ArgumentNullException("ip", "IP地址不能为空");
}
lock (_syncObject) {
List<Line> list = ListInternal();
HostLine hostLine = null;
//移除匹配的项,如果成功移除会返回条数,那么成功移除才保存
if (list.RemoveAll(line => {
hostLine = line as HostLine;
if (hostLine == null)
return false;
//必须是IP匹配的
return hostLine.IP.Equals(ip, StringComparison.OrdinalIgnoreCase);
}) > 0)
Save(list);
}
}
#endregion
#region RemoveByDomain
/// <summary>
/// 移除映射:通过域名
/// </summary>
/// <param name="domain">域名,匹配此域名的映射项都会被移除</param>
public static void RemoveByDomain(string domain) {
if (string.IsNullOrEmpty(domain)) {
throw new ArgumentNullException("domain", "域名不能为空");
}
lock (_syncObject) {
List<Line> list = ListInternal();
HostLine hostLine = null;
if (list.RemoveAll(line => {
hostLine = line as HostLine;
if (hostLine == null)
return false;
//必须是域名匹配的,不区分大小写
return hostLine.Domain.Equals(domain, StringComparison.OrdinalIgnoreCase);
}) > 0)
Save(list);
}
}
#endregion
}
}