添加系统托盘和菜单项:

  • 显示/隐藏界面
  • ToolTipText显示已拨链接的名字和获取的IP地址
  • 针对每一个链接的连接/断开操作
  • 断开所有链接
  • 退出程序

App.Config

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <startup>
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.8"/>
  </startup>
	<appSettings>
		<!--存在多个路由条目时,使用分号连接,以拨号服务器地址为键名-->
		<add key="1.1.1.1" value="192.168.2.0 MASK 255.255.255.0 DIALIP"/>
		<add key="2.2.2.2" value="192.168.3.0 MASK 255.255.255.0 DIALIP"/>
		<add key="site1.example.com" value="192.168.0.0 MASK 255.255.255.0 DIALIP"/>
		<add key="3.example.com" value="192.168.8.0 MASK 255.255.255.0 DIALIP"/>
	</appSettings>
</configuration>

EntrySimple

    /// <summary>
    /// 一个简化的拨号连接对象
    /// </summary>
    public class EntrySimple
    {
        public string IP
        {
            get
            {
                try
                {
                    var ip = NetworkInterface.GetAllNetworkInterfaces().Where(i => i.Name == Name).FirstOrDefault().GetIPProperties().UnicastAddresses[0].Address.ToString();
                    if (string.IsNullOrEmpty(ip)) return "-";
                    return ip;
                }
                catch (Exception)
                {
                    return "-";
                }
            }
        }
        /// <summary>
        /// 拨号连接名
        /// </summary>
        public string Name { get; set; }
        /// <summary>
        /// 拨号服务器地址
        /// </summary>
        public string PhoneNumber { get; set; }
        /// <summary>
        /// 是否EAP认证,根据此项决定使用哪个程序拨号
        /// </summary>
        public bool TypeEAP { get; set; }
        /// <summary>
        /// 路由条目
        /// </summary>
        public List<string> Routes { get; set; }
        /// <summary>
        /// 获取这个拨号条目对应的连接,未拨号时将返回null
        /// </summary>
        RasConnection Connection => RasConnection.GetActiveConnections().FirstOrDefault(c => c.EntryName == Name);
        public EntrySimple(string name, string phoneNumber, bool eap)
        {
            TypeEAP = eap;
            Name = name;
            PhoneNumber = phoneNumber;
            Routes = new();
        }
        /// <summary>
        /// 拨号功能,先拨号,再添加路由
        /// </summary>
        public void Connect()
        {
            if (Connection is null)
            {
                if (TypeEAP)
                {
                    Process.Start(
                        new ProcessStartInfo("rasdial")
                        {
                            Arguments = Name,
                            WindowStyle = ProcessWindowStyle.Hidden
                        }).WaitForExit();
                }
                else
                {
                    Process.Start("rasphone", $"-d {Name}").WaitForExit();
                }
                var ip = IP;
                if (ip != "-")
                {//查询拨号连接获取到的地址
                    foreach (var route in Routes)
                    {
                        string strRoute = route.Replace("DIALIP", IP);
                        Process.Start(new ProcessStartInfo("cmd") { Arguments = $"/c ROUTE ADD {strRoute}" }).WaitForExit();
                    }

                }
            }
        }
        /// <summary>
        /// 是否处于连接状态
        /// </summary>
        public bool IsConnected => Connection != null;
        /// <summary>
        /// 挂断
        /// </summary>
        public void HangUp() => Connection?.HangUp();
    }

Form1

    public partial class Form1 : Form
    {
        public Point Position;
        readonly Dictionary<string, EntrySimple> DictEntries = new();
        readonly RasPhoneBook phoneBook = new();

        public Form1()
        {
            InitializeComponent();
            listEntries.MultiSelect = false;
            //打开默认电话簿(这个对象包含了所有拨号连接)
            phoneBook.Open(RasPhoneBook.GetPhoneBookPath(RasPhoneBookType.User));
            Timer timer = new();
            timer.Interval = 3000;
            timer.Tick += (s, e) => EnumEntries(false);
            timer.Start();
        }
        private void BtnQuit_Click(object sender, EventArgs e) => ExitApp();
        private void Form1_Shown(object sender, EventArgs e) => EnumEntries();
        private void EnumEntries(bool showmsg = true)
        {
            int selectedIndex = -1;
            if (listEntries.SelectedItems.Count > 0) selectedIndex = listEntries.SelectedItems[0].Index;
            if (showmsg) WriteMessage("开始检测本地拨号连接");
            listEntries.Clear();
            DictEntries.Clear();
            menuTrayEntries.DropDownItems.Clear();
            List<string> trayTips = new();
            var connections = RasConnection.GetActiveConnections();
            foreach (var entry in phoneBook.Entries)
            {//遍历电话簿里所有连接
                entry.Options.PreviewUserPassword = false;//不弹出登录窗口
                entry.Options.RemoteDefaultGateway = false;//不使用远程网关
                entry.NetworkProtocols.IPv6 = false;//不用IPV6
                entry.Update();//不管之前如何,一定重新设置这几项,并保存             
                var item = listEntries.Items.Add(entry.Name, connections.Any(c => c.EntryName == entry.Name) ? 1 : 2);
                var entrySimple = new EntrySimple(entry.Name, entry.PhoneNumber, entry.Options.RequireEap);
                try
                {//配置文件里不一定存在这个服务器的路由条目
                    entrySimple.Routes = ConfigurationManager.AppSettings[entry.PhoneNumber.ToLower()].
                        Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries).ToList();
                }
                catch (Exception) { }
                var menuTrayEntry = new ToolStripMenuItem() { Text = entry.Name, Checked = connections.Any(c => c.EntryName == entry.Name) };
                menuTrayEntry.Click += (s, o) =>
                {
                    if (entrySimple.IsConnected)
                    {
                        WriteMessage($"挂断 {entry.Name}", date: true);
                        entrySimple.HangUp();
                    }
                    else
                    {
                        WriteMessage($"开始连接到 {entry.Name}", date: true);
                        entrySimple.Connect();
                    }
                };
                menuTrayEntries.DropDownItems.Add(menuTrayEntry);
                item.Tag = entrySimple;
                DictEntries[entry.PhoneNumber.ToLower()] = entrySimple;
                if (entrySimple.IsConnected) trayTips.Add($"【{entrySimple.Name}】\r\n{entrySimple.IP}");
            }
            //如果先前选中了某个项,刷新后仍然尝试选择它
            if (trayTips.Count > 0)
            {
                notiIcon.Text = $"已连接\r\n{string.Join("\r\n", trayTips)}";
            }
            else
            {
                notiIcon.Text = "";
            }
            if (selectedIndex >= 0 && selectedIndex < listEntries.Items.Count) listEntries.Items[selectedIndex].Selected = true;
            if (showmsg) WriteMessage("所有连接检测完成");
        }
        private void LblTitle_MouseMove(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left) Location = new Point(Location.X + e.X - Position.X, Location.Y + e.Y - Position.Y);
        }

        private void LblTitle_MouseDown(object sender, MouseEventArgs e) => Position = e.Location;

        private void ListEntries_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (listEntries.SelectedItems.Count > 0)
            {
                ShowInfo(listEntries.SelectedItems[0].Tag as EntrySimple);
            }
            else
            {
                txtInfo.Clear();
            }
        }
        private void ShowInfo(EntrySimple entry) =>
            txtInfo.Text =
            $"{entry.Name} - [{(entry.IsConnected ? "Connected" : "DisConnected")}] \r\n" +
            $"Server:\t{entry.PhoneNumber}\r\n" +
            $"Routes:\r\n{string.Join("\r\n", entry.Routes)}";
        private void WriteMessage(string msg, bool date = true, bool msgbox = false)
        {
            string result = date ? DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") : "";
            txtLogs.AppendText($"{result}   {msg}\r\n");
            if (msgbox) MessageBox.Show(msg);
        }
        private void BtnMin_Click(object sender, EventArgs e) => WindowState = FormWindowState.Minimized;
        private void ListEntries_MouseDoubleClick(object sender, MouseEventArgs e)
        {//双击时,拨号,或挂断连接
            ListViewHitTestInfo info = listEntries.HitTest(e.X, e.Y);
            if (info.Item != null)
            {
                if (listEntries.SelectedItems.Count > 0)
                {
                    var entry = listEntries.SelectedItems[0].Tag as EntrySimple;
                    if (entry.IsConnected)
                    {
                        entry.HangUp();
                        WriteMessage($"挂断 {entry.Name}", date: true);
                    }
                    else
                    {
                        entry.Connect();
                        WriteMessage($"开始连接到 {entry.Name}", date: true);
                    }
                }
            }
        }
        private void MnuInit_Click(object sender, EventArgs e) => EnumEntries();

        private void MnuDisconnectAll_Click(object sender, EventArgs e) => DisconnectAll();
        private void MnuTrayDisconnectAll_Click(object sender, EventArgs e) => DisconnectAll();

        private void MenuTrayQuit_Click(object sender, EventArgs e) => ExitApp();

        private void MenuTrayEntries_Click(object sender, EventArgs e) => WindowState = FormWindowState.Normal;

        private void NotiIcon_MouseDoubleClick(object sender, MouseEventArgs e) => ShowWindow();

        private void BtnHide_Click(object sender, EventArgs e) => HideWindow();

        private void MenuTrayShow_Click(object sender, EventArgs e)
        {
            if (menuTrayShow.Text.Contains("隐藏"))
            {
                HideWindow();
            }
            else
            {
                ShowWindow();
            }
        }
        private void ShowWindow()
        {
            Show();
            menuTrayShow.Text = "隐藏(&H)";
            WindowState = FormWindowState.Normal;
        }
        private void HideWindow()
        {
            notiIcon.Visible = true;
            menuTrayShow.Text = "显示(&S)";
            Hide();
        }
        private void ExitApp()
        {
            notiIcon.Dispose();
            Environment.Exit(0);
        }
        private void DisconnectAll()
        {
            WriteMessage("断开所有连接");
            RasConnection.GetActiveConnections().ToList().ForEach(c => c.HangUp());
        }
    }
分类: articles