/// <summary>
        /// Checkbox列ReadOnly为false时,Value经常与Checkbox状态不符
        /// 只好改成ReadOnly=true,再通过CellClick来处理
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void dataGridView1_CellClick(object sender, DataGridViewCellEventArgs e)
        {
            if (e.RowIndex < 0 || e.ColumnIndex < 0)
                return;

            DataGridViewRow dgvRow = dataGridView1.Rows[e.RowIndex];

            #region 点击折叠的代码
            if (e.RowIndex < dataGridView1.Rows.Count && e.ColumnIndex == COL_COLLPASE)
            {
                if (txtFindStripTextBox1.Text == string.Empty || txtFindStripTextBox1.Text == "请输入查找关键字")
                {
                    string val = Convert.ToString(dgvRow.Cells[e.ColumnIndex].Value).Trim();
                    if (val != string.Empty)
                    {
                        bool visable;
                        if (val == SYM_COL)
                        {
                            dgvRow.Cells[e.ColumnIndex].Value = SYM_EXT;
                            visable = false;
                        }
                        else
                        {
                            dgvRow.Cells[e.ColumnIndex].Value = SYM_COL;
                            visable = true;
                        }
                        for (var i = e.RowIndex + 1; i < dataGridView1.Rows.Count; i++)
                        {
                            var row = dataGridView1.Rows[i];
                            if (row.IsNewRow)
                                break;
                            val = Convert.ToString(row.Cells[e.ColumnIndex].Value).Trim();
                            if (val != string.Empty)
                                break;
                            row.Visible = visable;
                        }
                    }
                }
            }

            #endregion

            #region 修改CheckBox的代码
            if (e.RowIndex < dataGridView1.Rows.Count && e.ColumnIndex == COL_USE)
            {
                bool isUsing = dgvRow.Cells[e.ColumnIndex].Value == null ? true : !(bool)dgvRow.Cells[e.ColumnIndex].Value;

                dgvRow.Cells[e.ColumnIndex].Value = isUsing;

                SetFontBold(dgvRow, isUsing);   // 修改粗体显示

                // 启用host记录时,检查是否存在重复项
                if (isUsing)
                {
                    string name1 = Convert.ToString(dgvRow.Cells[COL_NAME].Value); // 当前行的域名
                    foreach (DataGridViewRow row in dataGridView1.Rows)
                    {
                        if (row.Index == e.RowIndex)                 // 同一行不比较
                            continue;
                        if (!Convert.ToBoolean(row.Cells[COL_USE].Value))  // 未启用,不比较
                            continue;

                        string name2 = Convert.ToString(row.Cells[COL_NAME].Value);
                        if (name2.Equals(name1, StringComparison.OrdinalIgnoreCase))
                        {
                            if (MessageBox.Show(name1 + " 域名配置已存在并启用,是否覆盖?", "配置已存在", MessageBoxButtons.YesNo)
                                != DialogResult.Yes)
                            {
                                dgvRow.Cells[e.ColumnIndex].Value = false;
                                break;
                            }
                            row.Cells[e.ColumnIndex].Value = false; // 覆盖同名的配置
                            //break;// 可能有多个重复项,所以不退出
                        }
                    }
                }
            }
            #endregion

            #region 点击删除按钮
            if (e.RowIndex < dataGridView1.Rows.Count - 1 && e.ColumnIndex == COL_DEL)//Rows.Count - 1是不让点击未提交的新行
            {
                isValueChanged = true;
                var ipcell = (DataGridViewComboBoxCell) dataGridView1.Rows[e.RowIndex].Cells[COL_IP];
                if (ipcell.Items.Count <= 1)
                {
                    dataGridView1.Rows.RemoveAt(e.RowIndex);
                    dataGridView1.ClearSelection();
                }
                else
                {
                    // 有多个ip时,只移除一个ip,必须加上下面2行,不然自定义的comboBox_Validating事件,又会把这个ip加上
                    var removeIp = ipcell.Value;
                    ipcell.Value = string.Empty;
                    ipcell.Items.Remove(removeIp);
                    if (ipcell.Items.Count > 0)
                        ipcell.Value = ipcell.Items[0];
                    dgvRow.Cells[COL_USE].Value = false;// 设置为不启用
                    SetFontBold(dgvRow, false);
                }
            }
            #endregion

            #region 点击IE打开按钮
            if (e.RowIndex < dataGridView1.Rows.Count - 1 && e.ColumnIndex == COL_IE)//Rows.Count - 1是不让点击未提交的新行
            {
                string url = Convert.ToString(dgvRow.Cells[COL_NAME].Value);
                if (!string.IsNullOrEmpty(url))
                    Process.Start("IExplore.exe", url);
                else
                    ShowMsg("请输入域名");
            }
            #endregion

            #region 点击加到快捷行按钮
            if (e.RowIndex < dataGridView1.Rows.Count - 1 && e.ColumnIndex == COL_QUICK)//Rows.Count - 1是不让点击未提交的新行
            {
                DataGridViewRow row = dgvRow;
                string ip = Convert.ToString(row.Cells[COL_IP].Value).Trim();
                string name = Convert.ToString(row.Cells[COL_NAME].Value).Trim();
                string desc = Convert.ToString(row.Cells[COL_DESC].Value).Trim();

                if (string.IsNullOrEmpty(ip) && string.IsNullOrEmpty(name) && string.IsNullOrEmpty(desc))
                {
                    ShowMsg("空行不能添加");
                    return;
                }

                HostItem item = new HostItem(ip, name, desc, true, 0);
                string rec = item.ToString();
                if (!HostsDal.RegItem.IsMatch(rec))
                {
                    ShowMsg("本行配置错误,不能添加");
                    return;
                }

                // 保存到快捷行
                string tmp = HostsDal.GetQuickLines();
                if (!string.IsNullOrEmpty(tmp))
                    tmp += "\r\n";
                HostsDal.SaveQuickLines(tmp + rec);
                ShowMsg("添加成功,请查看快捷行菜单");
                // 重新加载快捷行菜单
                BindQuickLines();
            }
            #endregion

            #region 点击PING按钮
            if (e.RowIndex < dataGridView1.Rows.Count - 1 && e.ColumnIndex == COL_PING)//Rows.Count - 1是不让点击未提交的新行
            {
                string url = Convert.ToString(dgvRow.Cells[COL_NAME].Value);
                if (!string.IsNullOrEmpty(url))
                {
                    using (Process p = new Process())
                    {
                        p.StartInfo.FileName = "cmd.exe";
                        p.StartInfo.UseShellExecute = true; // 在当前进程中启动,不使用系统外壳程序启动
                        //p.StartInfo.WindowStyle = ProcessWindowStyle.Maximized;// 让dos窗体最大化
                        p.StartInfo.Arguments = "/C ping " + url; //设定参数,其中的“/C”表示执行完命令后马上退出
                        p.StartInfo.RedirectStandardInput = false; //设置为true,后面可以通过StandardInput输入dos命令
                        //p.StartInfo.RedirectStandardInput = true;
                        p.StartInfo.RedirectStandardOutput = false;
                        //p.StartInfo.CreateNoWindow = true;     //不创建窗口
                        p.Start();
                        //SetWindowPos(p.Handle, 3, Left, Top, Width, Height, 8);
                        //p.StandardInput.WriteLine("ping " + url);
                        //p.WaitForExit(1000);
                        //MessageBox.Show(p.StandardOutput.ReadToEnd());
                        p.Close();
                    }
                }
                else
                    ShowMsg("请输入域名");
            }
            #endregion

            #region 点击NsLookup按钮
            if (e.RowIndex < dataGridView1.Rows.Count - 1 && e.ColumnIndex == COL_NSLOOKUP)//Rows.Count - 1是不让点击未提交的新行
            {
                string url = Convert.ToString(dgvRow.Cells[COL_NAME].Value);
                if (!string.IsNullOrEmpty(url))
                {
                    using (Process p = new Process())
                    {
                        p.StartInfo.FileName = "cmd.exe";
                        p.StartInfo.UseShellExecute = true; // 在当前进程中启动,不使用系统外壳程序启动
                        //p.StartInfo.WindowStyle = ProcessWindowStyle.Maximized;// 让dos窗体最大化

                        //设定参数,其中的“/C”表示执行完命令后马上退出
                        p.StartInfo.Arguments = string.Format("/C \"@echo =====电信结果===== && nslookup {0} {1} && " +
                            "@echo =====网通结果===== && nslookup {0} {2} && pause\"",
                            url, HostsDal.TelecomDns, HostsDal.UnicomDns); 
                        p.StartInfo.RedirectStandardInput = false; //设置为true,后面可以通过StandardInput输入dos命令
                        //p.StartInfo.RedirectStandardInput = true;
                        p.StartInfo.RedirectStandardOutput = false;
                        //p.StartInfo.CreateNoWindow = true;     //不创建窗口
                        p.Start();
                        //SetWindowPos(p.Handle, 3, Left, Top, Width, Height, 8);
                        //p.StandardInput.WriteLine("ping " + url);
                        //p.WaitForExit(11000);
                        //MessageBox.Show(p.StandardOutput.ReadToEnd());
                        p.Close();
                    }
                }
                else
                    ShowMsg("请输入域名");
            }
            #endregion
        }
        // 匹配单个host的正则:^\s*#?\s*(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})\s+([^\s]+)\s*#?(.*)$
        #endregion

        /// <summary>
        /// 从指定的路径获取host记录
        /// </summary>
        /// <param name="path"></param>
        /// <returns></returns>
        public static List<HostItem> GetHosts(string path)
        {
            path = GetFileName(path);

            //if(!File.Exists(path))
            //{
            //    MessageBox.Show("Hosts文件不存在,请手动选择文件路径");
            //    OpenFileDialog diag = new OpenFileDialog();
            //    diag.FileName = path;
            //    DialogResult result = diag.ShowDialog();
            //    if (result == DialogResult.OK || result == DialogResult.Yes)
            //    {
            //        path = diag.FileName;
            //    }
            //}
            if (File.Exists(path))
            {
                using (StreamReader reader = new StreamReader(path, Encode))
                {
                    List<HostItem> ret = new List<HostItem>();
                    while (!reader.EndOfStream)
                    {
                        string str = reader.ReadLine();
                        if (str == null)
                            continue;
                        str = str.Trim();

                        // 属于微软的2个注释时,跳过
                        if (str == "#      102.54.94.97     rhino.acme.com          # source server" ||
                            str == "#       38.25.63.10     x.acme.com              # x client host")
                            continue;

                        if (string.IsNullOrEmpty(str))
                        {
                            continue;
                        }

                        Match match = RegItem.Match(str);
                        if (match.Success)
                        {
                            string ip = match.Result("$1").Trim();
                            string name = match.Result("$2").Trim();
                            string desc = match.Result("$3").Trim();
                            int group = 0;
                            if (desc.StartsWith("#"))
                            {
                                desc = desc.Substring(1);
                                Match mGroup = RegDescGroup.Match(desc);
                                if(mGroup.Success)
                                {
                                    string tmp = mGroup.Value;
                                    group = int.Parse(tmp.Trim());
                                    desc = desc.Substring(0, mGroup.Index);
                                }
                            }
                            bool use = !str.StartsWith("#");
                            HostItem item = new HostItem(ip, name, desc, use, group);
                            ret.Add(item);
                        }
                    }
                    // 如果没有分组,则不排序
                    if (ret.Find(item => item.Group != 0) != null)
                    {
                        // 有进行分组时,按分组、是否使用、ip、域名排序
                        ret.Sort((x, y) =>
                        {
                            int retCompare = x.Group.CompareTo(y.Group);
                            if (retCompare == 0)
                            {
                                retCompare = -x.IsUsing.CompareTo(y.IsUsing);
                                if (retCompare == 0)
                                {
                                    retCompare = String.Compare(x.IP, y.IP, StringComparison.Ordinal);
                                    if (retCompare == 0)
                                    {
                                        retCompare = String.Compare(x.Name, y.Name, StringComparison.Ordinal);
                                    }
                                    else if (x.IP.StartsWith("127")) // 127的排前面
                                        retCompare = -1;
                                    else if (y.IP.StartsWith("127")) // 127的排前面
                                        retCompare = 1;
                                }
                            }
                            return retCompare;
                        });
                    }
                    return ret;
                }
            }
            return null;
        }
        /// <summary>
        /// 从DataGridView获取修改后的数据,用于保存
        /// </summary>
        /// <returns></returns>
        private List<HostItem> GetGridHost()
        {
            // 先清空搜索条件
            if (txtFindStripTextBox1.Text != string.Empty || txtFindStripTextBox1.Text != "请输入查找关键字")
            {
                txtFindStripTextBox1.Text = string.Empty;
                txtFindStripTextBox1_KeyUp(null, null);
            }

            List<HostItem> save = new List<HostItem>();
            StringBuilder groupStatus = new StringBuilder();
            foreach (DataGridViewRow row in dataGridView1.Rows)
            {
                string ipCurrent = Convert.ToString(row.Cells[COL_IP].EditedFormattedValue).Trim();// 不能用Value,会取得未提交的数据
                DataGridViewComboBoxCell ipcell = (DataGridViewComboBoxCell) row.Cells[COL_IP];
                bool use = Convert.ToBoolean(row.Cells[COL_USE].Value); //row.Cells[COL_USE].Selected;
                string name = Convert.ToString(row.Cells[COL_NAME].Value).Trim();
                string desc = Convert.ToString(row.Cells[COL_DESC].Value).Trim();
                int group;
                if (!int.TryParse(Convert.ToString(row.Cells[COL_GROUP].Value), out group))
                    group = 0;
                string collpase = Convert.ToString(row.Cells[COL_COLLPASE].Value).Trim();

                // 用于保存当前分组收缩展开状态
                if (!string.IsNullOrEmpty(collpase) && collpase == SYM_EXT)
                    groupStatus.AppendFormat("{0};", group);

                if (string.IsNullOrEmpty(name) && string.IsNullOrEmpty(desc))
                    continue;

                bool isCurrentUsed = false;
                foreach (string ip in ipcell.Items)
                {
                    if (string.IsNullOrEmpty(ip))
                        continue;

                    if (!isCurrentUsed) 
                        isCurrentUsed = ipCurrent == ip;
                    bool currentUse = (ipCurrent == ip ? use : false);
                    // 使用中的域名,要判断是否重复了
                    if (currentUse)
                    {
                        if (save.Find(i => (i.IsUsing && i.Name.Equals(name, StringComparison.OrdinalIgnoreCase))) !=
                            null)
                        {
                            MessageBox.Show("域名:" + name + "存在重复配置,请检查后再重新保存");
                            return null;
                        }
                    }
                    HostItem item = new HostItem(ip, name, desc, currentUse, group);
                    if (!HostsDal.RegItem.IsMatch(item.ToString()))
                    {
                        MessageBox.Show("ip:" + ip + " 域名:" + name + "配置错误,请检查后再重新保存");
                        return null;
                    }
                    save.Add(item);
                }
                if(!isCurrentUsed)
                {
                    // 使用中的域名,要判断是否重复了
                    if (use)
                    {
                        if (save.Find(i => (i.IsUsing && i.Name.Equals(name, StringComparison.OrdinalIgnoreCase))) !=
                            null)
                        {
                            MessageBox.Show("域名:" + name + "存在重复配置,请检查后再重新保存");
                            return null;
                        }
                    }
                    HostItem item = new HostItem(ipCurrent, name, desc, use, group);
                    if (!HostsDal.RegItem.IsMatch(item.ToString()))
                    {
                        MessageBox.Show("ip:" + ipCurrent + " 域名:" + name + "配置错误,请检查后再重新保存");
                        return null;
                    }
                    save.Add(item);
                }
            }

            // 用于保存当前分组收缩展开状态
            if (groupStatus.Length > 0)
                save.Add(new HostItem("1.1.1.1", "group", groupStatus.ToString(), false, 0));
            return save;
        }
Beispiel #4
0
        // 匹配单个host的正则:^\s*#?\s*(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})\s+([^\s]+)\s*#?(.*)$
        #endregion

        /// <summary>
        /// 从指定的路径获取host记录
        /// </summary>
        /// <param name="path"></param>
        /// <returns></returns>
        public static List <HostItem> GetHosts(string path)
        {
            path = GetFileName(path);

            //if(!File.Exists(path))
            //{
            //    MessageBox.Show("Hosts文件不存在,请手动选择文件路径");
            //    OpenFileDialog diag = new OpenFileDialog();
            //    diag.FileName = path;
            //    DialogResult result = diag.ShowDialog();
            //    if (result == DialogResult.OK || result == DialogResult.Yes)
            //    {
            //        path = diag.FileName;
            //    }
            //}
            if (File.Exists(path))
            {
                using (StreamReader reader = new StreamReader(path, Encode))
                {
                    List <HostItem> ret = new List <HostItem>();
                    while (!reader.EndOfStream)
                    {
                        string str = reader.ReadLine();
                        if (str == null)
                        {
                            continue;
                        }
                        str = str.Trim();

                        // 属于微软的2个注释时,跳过
                        if (str == "#      102.54.94.97     rhino.acme.com          # source server" ||
                            str == "#       38.25.63.10     x.acme.com              # x client host")
                        {
                            continue;
                        }

                        if (string.IsNullOrEmpty(str))
                        {
                            continue;
                        }

                        Match match = RegItem.Match(str);
                        if (match.Success)
                        {
                            string ip    = match.Result("$1").Trim();
                            string name  = match.Result("$2").Trim();
                            string desc  = match.Result("$3").Trim();
                            int    group = 0;
                            if (desc.StartsWith("#"))
                            {
                                desc = desc.Substring(1);
                                Match mGroup = RegDescGroup.Match(desc);
                                if (mGroup.Success)
                                {
                                    string tmp = mGroup.Value;
                                    group = int.Parse(tmp.Trim());
                                    desc  = desc.Substring(0, mGroup.Index);
                                }
                            }
                            bool     use  = !str.StartsWith("#");
                            HostItem item = new HostItem(ip, name, desc, use, group);
                            ret.Add(item);
                        }
                    }
                    // 如果没有分组,则不排序
                    if (ret.Find(item => item.Group != 0) != null)
                    {
                        // 有进行分组时,按分组、是否使用、ip、域名排序
                        ret.Sort((x, y) =>
                        {
                            int retCompare = x.Group.CompareTo(y.Group);
                            if (retCompare == 0)
                            {
                                retCompare = -x.IsUsing.CompareTo(y.IsUsing);
                                if (retCompare == 0)
                                {
                                    retCompare = String.Compare(x.IP, y.IP, StringComparison.Ordinal);
                                    if (retCompare == 0)
                                    {
                                        retCompare = String.Compare(x.Name, y.Name, StringComparison.Ordinal);
                                    }
                                    else if (x.IP.StartsWith("127")) // 127的排前面
                                    {
                                        retCompare = -1;
                                    }
                                    else if (y.IP.StartsWith("127")) // 127的排前面
                                    {
                                        retCompare = 1;
                                    }
                                }
                            }
                            return(retCompare);
                        });
                    }
                    return(ret);
                }
            }
            return(null);
        }