联想天工802.1x认证掉线重连程序,for 1xclient 3.0

    blog文章太少了,继续帖代码凑数。这个程序基本上没什么看点,有兴趣就看吧,挑错和改进建议更是求之不得。。。

    学校渣网络用的是联想天工的802.1x认证系统。由于常常掉线,给挂机下载工作造成了非常大的影响,所以我赶制了这个程序。。。

    以下是代码:(诶?前言就这么点吗?)

首先是对用到的一些API函数的声明:

namespace Takamachi660.Common.Windows.API

{

    public static class User32

    {

        [DllImport("user32.dll")]

        public static extern IntPtr GetForegroundWindow();



        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]

        public static extern int GetWindowText(IntPtr hWnd, StringBuilder lpString, int nMaxCount);



        [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]

        public static extern int GetWindowTextLength(IntPtr hWnd);



        [DllImport("user32.dll")]

        public static extern IntPtr SetActiveWindow(IntPtr hWnd);



        [DllImport("user32.dll")]

        [return: MarshalAs(UnmanagedType.Bool)]

        public static extern bool SetForegroundWindow(IntPtr hWnd);



        [DllImport("user32.dll", SetLastError = true)]

        public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);



        /// <summary>

        /// Find window by Caption only. Note you must pass IntPtr.Zero as the first parameter.

        /// </summary>

        [DllImport("user32.dll", EntryPoint = "FindWindow", SetLastError = true)]

        public static extern IntPtr FindWindowByCaption(IntPtr ZeroOnly, string lpWindowName);



        [DllImport("user32.dll", SetLastError = true)]

        public static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);



        [DllImport("user32.dll", SetLastError = true)]

        public static extern IntPtr FindWindowEx(IntPtr parentHandle, IntPtr childAfter, string className, IntPtr windowTitle);



        [DllImport("user32.dll", CharSet = CharSet.Auto)]

        public static extern int GetClassName(IntPtr hWnd, StringBuilder lpClassName, int nMaxCount);



        [DllImport("user32.dll")]

        public static extern IntPtr GetTopWindow(IntPtr hWnd);



        [DllImport("user32.dll", SetLastError = true)]

        public static extern IntPtr GetWindow(IntPtr hWnd, uint uCmd);

        public enum GetWindow_Cmd : uint

        {

            GW_HWNDFIRST = 0,

            GW_HWNDLAST = 1,

            GW_HWNDNEXT = 2,

            GW_HWNDPREV = 3,

            GW_OWNER = 4,

            GW_CHILD = 5,

            GW_ENABLEDPOPUP = 6

        }



        [DllImport("user32.dll")]

        public static extern IntPtr GetLastActivePopup(IntPtr hWnd);



        [DllImport("user32.dll")]

        public static extern bool AnyPopup();



        [return: MarshalAs(UnmanagedType.Bool)]

        [DllImport("user32.dll", SetLastError = true)]

        public static extern bool PostMessage(IntPtr hWnd, int Msg, IntPtr wParam, IntPtr lParam);



        [DllImport("user32.dll", CharSet = CharSet.Auto)]

        public static extern IntPtr SendMessage(IntPtr hWnd, int Msg, IntPtr wParam, IntPtr lParam);

    }

}
 
 
第一个类,用来对1xclient进行控制(其实就是start和kill进程)
using System;

using System.Diagnostics;

using System.Linq;



namespace Takamachi660._1xHelper

{

    

    /// <summary>

    /// 1xclient客户端程序控制类

    /// </summary>

    public class C1xController : IDisposable

    {

        /// <summary>

        /// 1xclient客户端程序可执行文件名(不带".exe")

        /// </summary>

        protected string m_ExeFileName;

        /// <summary>

        /// 1xclient客户端程序所在的目录

        /// </summary>

        protected string m_ExePath;

        /// <summary>

        /// 与1xclient客户端进程关联的Process对象

        /// </summary>

        protected Process m_1xProcess;



        /// <summary>

        /// 获取一个值,该值指示1xclient的运行状态

        /// </summary>

        public virtual bool Status

        {

            get

            {

                if (m_1xProcess == null)

                    Reset1xProcess();

                if (m_1xProcess == null)

                    return false;

                else

                {

                    return !m_1xProcess.HasExited;

                }

            }

        }

        /// <summary>

        /// 获取或设置等待1xclient.exe退出时间

        /// </summary>

        public int WaitForExeExitTime { get; set; }

        /// <summary>

        /// 获取或设置轮询间隔时间

        /// </summary>

        public int QueryInterval { get; set; }

        /// <summary>

        /// 获取或设置轮询重试次数

        /// </summary>

        public Int16 QueryRetry { get; set; }



        /// <param name="ExePath">1xclient客户端程序所在的目录</param>

        /// <param name="ExeFileName">1xclient客户端程序可执行文件名(不带".exe")</param>

        public C1xController(string ExePath, string ExeFileName)

        {

            m_ExePath = ExePath;

            m_ExeFileName = ExeFileName;

            Reset1xProcess();



            WaitForExeExitTime = 5000;

            QueryInterval = 300;

            QueryRetry = 30;

        }

        protected virtual void Reset1xProcess()

        {

            Process[] ps = Process.GetProcessesByName(m_ExeFileName + @".dll");

            if (ps.Length > 0)

                m_1xProcess = ps.Single();

            else

                m_1xProcess = null;

        }

        /// <summary>

        /// 启动ixclient

        /// </summary>

        public virtual void Start()

        {

            if (m_1xProcess != null && !m_1xProcess.HasExited)

                throw new InvalidOperationException("1xclient is already running!");

            ProcessStartInfo startinfo = new ProcessStartInfo();

            startinfo.FileName = m_ExePath + @"\" + m_ExeFileName + @".exe";

            startinfo.CreateNoWindow = startinfo.UseShellExecute = startinfo.RedirectStandardInput = startinfo.RedirectStandardOutput = startinfo.RedirectStandardError = false;

            startinfo.WindowStyle = ProcessWindowStyle.Hidden;

            m_1xProcess = Process.Start(startinfo);

            if (!m_1xProcess.WaitForExit(WaitForExeExitTime))

                throw new Exception("1xclient.exe didn't exit");

            Int16 counter = 0;

            do

            {

                Reset1xProcess();

                if (m_1xProcess != null)

                    break;

                counter++;

                System.Threading.Thread.Sleep(QueryInterval);

            } while (counter < QueryRetry);

            if (counter >= QueryRetry)

                throw new Exception("1xclient.dll didn't start");

        }

        /// <summary>

        /// 关闭1xclient

        /// </summary>

        public virtual void Stop()

        {

            do

            {

                m_1xProcess.Kill();

            } while (!m_1xProcess.WaitForExit(WaitForExeExitTime));

            m_1xProcess = null;

        }

        /// <summary>

        /// 重新启动1xclient

        /// </summary>

        public virtual void Restart()

        {

            Stop();

            Start();

        }

        /// <summary>

        /// 释放与此组件关联的资源

        /// </summary>

        public virtual void Dispose()

        {

            if (m_1xProcess != null)

                m_1xProcess.Close();

        }

    }

}

 

 

第二个类,对第一个类的改进,增加了对1xclient窗口的控制以及错误信息的读取

using System;

using System.Text;

using Takamachi660.Common.Windows.API;



namespace Takamachi660._1xHelper

{

    /// <summary>

    /// 1xclient控制器异常

    /// </summary>

    public class C1xControllerException : Exception

    {

        public C1xControllerException(string message) : base(message) { }

        public C1xControllerException(string message, Exception innerException) : base(message, innerException) { }

    }

    /// <summary>

    /// 1xclient客户端程序控制类改进版

    /// </summary>

    public class C1xControllerEx : C1xController

    {

        /// <summary>

        /// 获取认证成功提示信息窗口的句柄

        /// </summary>

        protected IntPtr HWND_Succeed { get { return Takamachi660.Common.Windows.API.User32.FindWindowByCaption(IntPtr.Zero, "提示信息"); } }

        /// <summary>

        /// 获取认证失败提示信息窗口的句柄

        /// </summary>

        //protected IntPtr HWND_Failed { get { return Takamachi660.Common.Windows.API.User32.FindWindowByCaption(IntPtr.Zero, "1xClient"); } }

        protected IntPtr HWND_Failed

        {

            get

            {

                IntPtr[] hwnds = new IntPtr[2];

                hwnds[0] = Takamachi660.Common.Windows.API.User32.FindWindowByCaption(IntPtr.Zero, "1xClient");

                hwnds[1] = Takamachi660.Common.Windows.API.User32.FindWindowByCaption(IntPtr.Zero, "出错提示");

                foreach (IntPtr hwnd in hwnds)

                {

                    if (hwnd != IntPtr.Zero)

                        return hwnd;

                }

                return IntPtr.Zero;

            }

        }

        /// <summary>

        /// 获取认证过程提示信息窗口的句柄

        /// </summary>

        protected IntPtr HWND_Authentication

        {

            get

            {

                IntPtr[] hwnds = new IntPtr[4];

                hwnds[0] = Takamachi660.Common.Windows.API.User32.FindWindowByCaption(IntPtr.Zero, "寻找交换机......");

                hwnds[1] = Takamachi660.Common.Windows.API.User32.FindWindowByCaption(IntPtr.Zero, "正在连接......");

                hwnds[2] = Takamachi660.Common.Windows.API.User32.FindWindowByCaption(IntPtr.Zero, "认证成功!");

                hwnds[3] = Takamachi660.Common.Windows.API.User32.FindWindowByCaption(IntPtr.Zero, "出错提示");

                foreach (IntPtr hwnd in hwnds)

                {

                    if (hwnd != IntPtr.Zero)

                        return hwnd;

                }

                return IntPtr.Zero;

            }

        }



        public C1xControllerEx(string ExePath, string ExeFileName) : base(ExePath, ExeFileName) { }

        /// <summary>

        /// 启动ixclient

        /// </summary>

        public override void Start()

        {

            IntPtr ForeWindowHandle = User32.GetForegroundWindow();

            try

            {

                base.Start();

                int counter = 0;

                do

                {

                    IntPtr hwnd_dlg = HWND_Authentication;

                    if (hwnd_dlg == IntPtr.Zero)

                    {

                        counter++;

                    }

                    else

                    {

                        IntPtr hwnd_dlg2 = IntPtr.Zero;

                        if ((hwnd_dlg2 = HWND_Succeed) != IntPtr.Zero)

                        {

                            ClickButton(hwnd_dlg2, "确定");

                            break;

                        }

                        else if ((hwnd_dlg2 = HWND_Failed) != IntPtr.Zero)

                        {

                            IntPtr hwnd_msg = User32.GetWindow(hwnd_dlg2, (uint)User32.GetWindow_Cmd.GW_CHILD);

                            string Message = "Unknown error message";

                            do

                            {

                                if (User32.GetWindowTextLength(hwnd_msg) > 4)

                                {

                                    StringBuilder sb = new StringBuilder(200);

                                    User32.GetWindowText(hwnd_msg, sb, 200);

                                    Message = sb.ToString();

                                }

                            } while ((hwnd_msg = User32.GetWindow(hwnd_msg, (uint)User32.GetWindow_Cmd.GW_HWNDNEXT)) != IntPtr.Zero);

                            this.Stop();

                            throw new C1xControllerException(Message);

                        }

                        else

                        {

                            StringBuilder sb = new StringBuilder(200);

                            Takamachi660.Common.Windows.API.User32.GetWindowText(hwnd_dlg, sb, 200);

                            if (sb.ToString() == "认证成功!")

                                counter++;

                        }

                    }

                    System.Threading.Thread.Sleep(QueryInterval);

                } while (counter < QueryRetry);

                if (counter >= QueryRetry)

                    throw new Exception("Unknown error occurred!");

            }

            catch (Exception e)

            {

                User32.SetForegroundWindow(ForeWindowHandle);

                throw new C1xControllerException("An exception occurred when starting 1xclient", e);

            }

            finally

            {

                User32.SetForegroundWindow(ForeWindowHandle);

            }

        }

        /// <summary>

        /// 关闭1xclient

        /// </summary>

        public override void Stop()

        {

            try

            {

                base.Stop();

            }

            catch (Exception e)

            {

                throw new C1xControllerException("An exception occurred when stopping 1xclient", e);

            }

        }

        /// <summary>

        /// 重新启动1xclient

        /// </summary>

        public override void Restart()

        {

            try

            {

                base.Restart();

            }

            catch (Exception e)

            {

                throw new C1xControllerException("An exception occurred when restarting 1xclient", e);

            }

        }

        protected virtual void ClickButton(IntPtr parentHandle, string buttonTitle)

        {

            const int BM_CLICK = 0x00F5;

            User32.SetForegroundWindow(parentHandle);

            if (string.IsNullOrEmpty(buttonTitle))

                User32.PostMessage(User32.FindWindowEx(parentHandle, IntPtr.Zero, "Button", IntPtr.Zero), BM_CLICK, IntPtr.Zero, IntPtr.Zero);

            else

                User32.PostMessage(User32.FindWindowEx(parentHandle, IntPtr.Zero, "Button", buttonTitle), BM_CLICK, IntPtr.Zero, IntPtr.Zero);

        }

    }

}

 

 

第三个类,很简单,ping网关以检测网络状态

(关于Ping造成的内存泄漏问题顺便再这里bs一下微软,到现在都没有修正)

using System.Net;

using System.Net.NetworkInformation;

namespace Takamachi660._1xHelper

{

    /// <summary>

    /// 网络测试类

    /// </summary>

    public class NetworkStatusTester

    {

        /// <summary>

        /// 获取或设置网关的IP地址

        /// </summary>

        public IPAddress IpGateway { get; set; }

        /// <summary>

        /// 获取一个值,该值指示网络当前是否连通

        /// </summary>

        public virtual bool IsConnected

        {

            get

            {

                using (Ping p = new Ping())

                {

                    bool IsSucceed = p.Send(IpGateway, 1000).Status == IPStatus.Success;

                    return IsSucceed;

                }

            }

        }

    }

}

 

第四个类,监视器,包含一个计时器和以上两个类的实例,作用是定期检查网络状态,发现断网即重连

using System;

using System.Net;

using System.Timers;

using System.IO;



namespace Takamachi660._1xHelper

{

    /// <summary>

    /// 连接监视类

    /// </summary>

    public class C1xWatcher

    {

        /// <summary>

        /// 1xclient控制器的弱引用对象

        /// </summary>

        private WeakReference m_wref_1xController;

        /// <summary>

        /// 日志写入器的弱引用对象

        /// </summary>

        private WeakReference m_wref_LogWriter;

        /// <summary>

        /// 网络状态测试器

        /// </summary>

        protected NetworkStatusTester m_Tester;

        /// <summary>

        /// 计时器

        /// </summary>

        protected Timer m_Tmr;

        /// <summary>

        /// 1xclient客户端程序可执行文件名(不带".exe")

        /// </summary>

        protected string m_1xExeFileName;

        /// <summary>

        /// 1xclient客户端程序所在的目录

        /// </summary>

        protected string m_1xExePath;

        /// <summary>

        /// 最后发生的事件消息

        /// </summary>

        protected string m_LastMessage;

        /// <summary>

        /// 连续失败次数

        /// </summary>

        protected Int16 m_CounterFail;

        /// <summary>

        /// 本次运行过程中的掉线次数

        /// </summary>

        protected Int16 m_CounterDisconnect;



        /// <summary>

        /// 获取1xclient控制器的强引用对象

        /// </summary>

        protected C1xControllerEx m_1xController

        {

            get

            {

                if (!m_wref_1xController.IsAlive)

                    m_wref_1xController.Target = new C1xControllerEx(m_1xExePath, m_1xExeFileName);

                return (C1xControllerEx)m_wref_1xController.Target;

            }

        }

        /// <summary>

        /// 获取日志写入器的强引用对象

        /// </summary>

        protected StreamWriter m_LogWriter

        {

            get

            {

                if (!m_wref_LogWriter.IsAlive)

                    m_wref_LogWriter.Target = new StreamWriter(new FileStream(Environment.CurrentDirectory + @"\" + LogFileName, FileMode.Append), System.Text.Encoding.UTF8);

                return (StreamWriter)m_wref_LogWriter.Target;

            }

        }

        /// <summary>

        /// 获取或设置测试网络状态的时间间隔,单位:毫秒

        /// </summary>

        public double Interval

        {

            get { return m_Tmr.Interval; }

            set { m_Tmr.Interval = value; }

        }

        /// <summary>

        /// 获取或设置测试网络状态的重试次数

        /// </summary>

        public Int16 PingRetry { get; set; }

        /// <summary>

        /// 检测到掉线后重新连接的延迟时间,单位:毫秒

        /// </summary>

        public int DelayBeforeReconnect { get; set; }

        /// <summary>

        /// 重新连接后再次检测的延迟时间,单位:毫秒

        /// </summary>

        public int DelayAfterReconnect { get; set; }

        /// <summary>

        /// 获取一个值,该值指示监视器是否工作中

        /// </summary>

        public bool IsAlive { get { return m_Tmr.Enabled; } }

        /// <summary>

        /// 获取或设置网关的IP地址

        /// </summary>

        public IPAddress IpGateway

        {

            get { return m_Tester.IpGateway; }

            set { m_Tester.IpGateway = value; }

        }

        /// <summary>

        /// 获取一个值,该值指示1xclient的运行状态

        /// </summary>

        public bool ClientStatus

        {

            get { return m_1xController.Status; }

        }

        /// <summary>

        /// 获取一个值,该值指示网络当前是否连通

        /// </summary>

        public bool ConnectionStatus

        {

            get { return m_Tester.IsConnected; }

        }

        /// <summary>

        /// 获取或设置日志文件名

        /// </summary>

        public string LogFileName { get; set; }

        /// <summary>

        /// 获取最后发生的事件消息

        /// </summary>

        public string LastMessage { get { return m_LastMessage; } }

        /// <summary>

        /// 获取连续失败次数

        /// </summary>

        public Int16 CounterFail { get { return m_CounterFail; } }

        /// <summary>

        /// 获取本次运行过程中的掉线次数

        /// </summary>

        public Int16 CounterDisconnect { get { return m_CounterDisconnect; } }



        /// <summary>

        /// 检测到掉线后发生

        /// </summary>

        public event EventHandler Disconnected;

        /// <summary>

        /// 重新连接成功后发生

        /// </summary>

        public event EventHandler Reconnected;

        /// <summary>

        /// 重新连接失败后发生

        /// </summary>

        public event EventHandler ReconnectFailed;



        /// <param name="_1xExePath">1xclient客户端程序所在的目录</param>

        /// <param name="_1xExeFileName">1xclient客户端程序可执行文件名(不带".exe")</param>

        /// <param name="IpGateway">网关的IP地址</param>

        /// <param name="Interval">测试网络状态的时间间隔</param>

        public C1xWatcher(string _1xExePath, string _1xExeFileName, IPAddress IpGateway, double Interval)

        {

            m_1xExePath = _1xExePath;

            m_1xExeFileName = _1xExeFileName;

            m_wref_1xController = new WeakReference(null);

            m_wref_LogWriter = new WeakReference(null);

            m_Tester = new NetworkStatusTester();

            m_Tester.IpGateway = IpGateway;

            m_Tmr = new Timer(Interval);

            m_Tmr.AutoReset = false;

            m_Tmr.Elapsed += new ElapsedEventHandler(m_Tmr_Elapsed);

            Disconnected += new EventHandler(C1xWatcher_Disconnected);



            PingRetry = 3;

            DelayBeforeReconnect = 0;

            DelayAfterReconnect = 5000;

            LogFileName = "Logs.txt";

        }

        /// <summary>

        /// 立即检测网络状态

        /// </summary>

        public virtual void CheckAtOnce()

        {

            lock (m_Tmr)

            {

                bool IsConnected = m_Tester.IsConnected;

                if (!IsConnected)

                {

                    for (int count = 0; count < PingRetry; count++)

                    {

                        if (m_Tester.IsConnected)

                        {

                            IsConnected = true;

                            break;

                        }

                    }

                    if (!IsConnected)

                    {

                        try

                        {

                            OnDisconnected();

                            OnReconnected();

                            if (DelayAfterReconnect != 0)

                                System.Threading.Thread.Sleep(DelayAfterReconnect);

                            if (!m_Tester.IsConnected)

                                OnReconnectFailed("警告:虽然1xclient显示连接成功,但网络依然没有接通!");

                        }

                        catch (C1xControllerException ex)

                        {

                            Exception innerexception = ex;

                            while (innerexception.InnerException != null)

                            {

                                innerexception = innerexception.InnerException;

                            }

                            OnReconnectFailed("重新连接失败!信息:" + innerexception.Message);

                        }

                    }

                }

            }

        }

        /// <summary>

        /// 立即检测网络状态并优先检测1xclient客户端的状态

        /// </summary>

        public virtual void CheckAtOnceEx()

        {

            if (!m_1xController.Status)

            {

                try

                {

                    m_1xController.Start();

                }

                catch (C1xControllerException ex)

                {

                    Exception innerexception = ex;

                    while (innerexception.InnerException != null)

                    {

                        innerexception = innerexception.InnerException;

                    }

                    if (innerexception.Message == "请求的操作需要提升。")

                        throw innerexception;

                }

            }

            else

                CheckAtOnce();

        }

        /// <summary>

        /// 通过计时器定期检测网络状态

        /// </summary>

        protected virtual void m_Tmr_Elapsed(object sender, ElapsedEventArgs e)

        {

            CheckAtOnce();

            m_Tmr.Start();

        }

        /// <summary>

        /// 检测到掉线后的处理方法

        /// </summary>

        void C1xWatcher_Disconnected(object sender, EventArgs e)

        {

            if (DelayBeforeReconnect != 0)

                System.Threading.Thread.Sleep(DelayBeforeReconnect);

            WriteLog("开始重新连接!");

            if (m_1xController.Status)

                m_1xController.Restart();

            else

                m_1xController.Start();            

        }

        /// <summary>

        /// 启动监视器

        /// </summary>

        public virtual void Start()

        {

            lock (m_Tmr)

                m_Tmr.Start();

        }

        /// <summary>

        /// 停止监视器

        /// </summary>

        public virtual void Stop()

        {

            lock (m_Tmr)

                m_Tmr.Stop();

        }

        /// <summary>

        /// 触发Disconnected事件

        /// </summary>

        protected virtual void OnDisconnected()

        {

            if (m_CounterFail == 0)

                m_CounterDisconnect++;

            WriteLog("检测到连接中断!");

            m_LastMessage = FormatTimeSpan(DateTime.Now.TimeOfDay) + " 检测到连接中断!";

            if (Disconnected != null)

                Disconnected(this, new EventArgs());

        }

        /// <summary>

        /// 触发Reconnected事件

        /// </summary>

        protected virtual void OnReconnected()

        {

            m_CounterFail = 0;

            WriteLog("重新连接成功!");

            m_LastMessage = FormatTimeSpan(DateTime.Now.TimeOfDay) + " 重新连接成功!";

            if (Reconnected != null)

                Reconnected(this, new EventArgs());

        }

        /// <summary>

        /// 触发ReconnectFailed事件

        /// </summary>

        protected virtual void OnReconnectFailed(string message)

        {

            m_CounterFail++;

            WriteLog(message);

            m_LastMessage = FormatTimeSpan(DateTime.Now.TimeOfDay) + " " + message;

            if (ReconnectFailed != null)

                ReconnectFailed(this, new EventArgs());



        }

        protected virtual void WriteLog(string Msg)

        {

            StreamWriter sw = m_LogWriter;

            sw.WriteLine(DateTime.Now.ToString() + "\t" + Msg);

            sw.Flush();

        }

        protected string FormatTimeSpan(TimeSpan t)

        {

            return t.Hours.ToString("00") + ":" + t.Minutes.ToString("00") + ":" + t.Seconds.ToString("00");

        }

    }

}

 

 

最后是几个配置类,对xml文档的读写进行封装,方便使用

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Xml;

using Microsoft.Win32;



namespace Takamachi660._1xHelper

{

    /// <summary>

    /// 配置信息读写类

    /// </summary>

    public class Configurations

    {

        private const string ConfigFileName = "config.xml";

        internal XmlDocument m_XmlDoc;

        private ConfigNode[] m_ConfigNodes;



        /// <summary>

        /// 获取1xClient配置节点

        /// </summary>

        public Config_1xClient Config_1xClient { get { return (Config_1xClient)m_ConfigNodes[0]; } }

        /// <summary>

        /// 获取网络信息配置节点

        /// </summary>

        public Config_Network Config_Network { get { return (Config_Network)m_ConfigNodes[1]; } }

        /// <summary>

        /// 获取监视器配置节点

        /// </summary>

        public Config_1xWatcher Config_1xWatcher { get { return (Config_1xWatcher)m_ConfigNodes[2]; } }

        /// <summary>

        /// 获取杂项配置节点

        /// </summary>

        public Config_Others Config_Others { get { return (Config_Others)m_ConfigNodes[3]; } }



        public Configurations()

        {

            m_XmlDoc = new XmlDocument();

            m_ConfigNodes = new ConfigNode[4];

            m_ConfigNodes[0] = new Config_1xClient(this);

            m_ConfigNodes[1] = new Config_Network(this);

            m_ConfigNodes[2] = new Config_1xWatcher(this);

            m_ConfigNodes[3] = new Config_Others(this);

        }

        /// <summary>

        /// 初始化配置

        /// 若配置文件存在则读取

        /// 不存在则以默认配置建立配置文件

        /// </summary>

        public void Initialize()

        {

            string filepath = Environment.CurrentDirectory + @"\" + ConfigFileName;

            if (System.IO.File.Exists(filepath))

                m_XmlDoc.Load(filepath);

            else

                CreateDefaultConfigFile(filepath);

        }

        /// <summary>

        /// 保存配置文件

        /// </summary>

        public void SaveConfig()

        {

            m_XmlDoc.Save(Environment.CurrentDirectory + @"\" + ConfigFileName);

        }



        /// <summary>

        /// 以默认配置建立配置文件

        /// </summary>

        /// <param name="filepath">文件名</param>

        private void CreateDefaultConfigFile(string filepath)

        {

            m_XmlDoc.AppendChild(m_XmlDoc.CreateNode(XmlNodeType.XmlDeclaration, "", ""));

            m_XmlDoc.AppendChild(m_XmlDoc.CreateElement("Configurations"));

            m_XmlDoc.DocumentElement.AppendChild(m_XmlDoc.CreateElement("_1xClient"));

            ((XmlElement)m_XmlDoc.DocumentElement.ChildNodes[0]).SetAttribute("Name", "1xClient");

            ((XmlElement)m_XmlDoc.DocumentElement.ChildNodes[0]).SetAttribute("Path", Get1xClientPathFromReg());

            m_XmlDoc.DocumentElement.AppendChild(m_XmlDoc.CreateElement("Network"));

            ((XmlElement)m_XmlDoc.DocumentElement.ChildNodes[1]).SetAttribute("GatewayIp", GetDefaultGatewayIp());

            m_XmlDoc.DocumentElement.AppendChild(m_XmlDoc.CreateElement("Watcher"));

            ((XmlElement)m_XmlDoc.DocumentElement.ChildNodes[2]).SetAttribute("Interval", "10000.0");

            ((XmlElement)m_XmlDoc.DocumentElement.ChildNodes[2]).SetAttribute("PingRetry", "2");

            ((XmlElement)m_XmlDoc.DocumentElement.ChildNodes[2]).SetAttribute("DelayBeforeReconnect", "0");

            ((XmlElement)m_XmlDoc.DocumentElement.ChildNodes[2]).SetAttribute("DelayAfterReconnect", "5000");

            ((XmlElement)m_XmlDoc.DocumentElement.ChildNodes[2]).SetAttribute("LogFileName", "Logs.txt");

            m_XmlDoc.DocumentElement.AppendChild(m_XmlDoc.CreateElement("Others"));

            ((XmlElement)m_XmlDoc.DocumentElement.ChildNodes[3]).SetAttribute("ResponseTimeLimitMsg", "True");

            ((XmlElement)m_XmlDoc.DocumentElement.ChildNodes[3]).SetAttribute("BalloonTipTimeout", "300");

            ((XmlElement)m_XmlDoc.DocumentElement.ChildNodes[3]).SetAttribute("MaxRetry", "20");

            m_XmlDoc.Save(filepath);

        }

        /// <summary>

        /// 从注册表读出1xClient的安装目录

        /// </summary>

        private static string Get1xClientPathFromReg()

        {

            RegistryKey Key_SOFTWARE = Registry.LocalMachine.OpenSubKey("SOFTWARE");

            RegistryKey Key_1xClient = null;

            string path = string.Empty;

            try

            {

                if (Key_SOFTWARE.OpenSubKey("Wow6432Node") != null)

                    Key_1xClient = Key_SOFTWARE.OpenSubKey(@"Wow6432Node\Microsoft\Windows\CurrentVersion\App Paths\联想网络");

                else

                    Key_1xClient = Key_SOFTWARE.OpenSubKey(@"Microsoft\Windows\CurrentVersion\App Paths\联想网络");

                if (Key_1xClient != null)

                    path = ((string)Key_1xClient.GetValue("Path", string.Empty)).TrimEnd('\\');

            }

            catch { }

            finally

            {

                Key_SOFTWARE.Close();

                if (Key_1xClient != null)

                    Key_1xClient.Close();

            }

            return path;

        }

        /// <summary>

        /// 获取默认网关地址

        /// </summary>

        private static string GetDefaultGatewayIp()

        {

            System.Net.NetworkInformation.NetworkInterface[] nets = System.Net.NetworkInformation.NetworkInterface.GetAllNetworkInterfaces();

            foreach (System.Net.NetworkInformation.NetworkInterface net in nets)

            {

                if (net.NetworkInterfaceType != System.Net.NetworkInformation.NetworkInterfaceType.Ethernet)

                    continue;

                RegistryKey Key_Net = Registry.LocalMachine.OpenSubKey(@"SYSTEM\CurrentControlSet\Services\" + net.Id + @"\Parameters\Tcpip");

                if (Key_Net != null)

                {

                    string gatewayip = ((string[])Key_Net.GetValue("DefaultGateway", string.Empty)).First(s => { System.Net.IPAddress ip; return System.Net.IPAddress.TryParse(s, out ip); });

                    Key_Net.Close();

                    if (!string.IsNullOrEmpty(gatewayip))

                        return gatewayip;

                }

            }

            return string.Empty;

        }

    }

    /// <summary>

    /// 配置节点基类

    /// </summary>

    public abstract class ConfigNode

    {

        private Configurations m_ConfigSet;

        /// <summary>

        /// 节点名

        /// </summary>

        private string m_NodeName;

        /// <summary>

        /// 读写该节点属性

        /// </summary>

        /// <param name="AttributeName">属性名</param>

        /// <returns>属性值</returns>

        protected string this[string AttributeName]

        {

            get

            {

                return m_ConfigSet.m_XmlDoc.DocumentElement.GetElementsByTagName(m_NodeName)[0].Attributes[AttributeName].Value;

            }

            set

            {

                m_ConfigSet.m_XmlDoc.DocumentElement.GetElementsByTagName(m_NodeName)[0].Attributes[AttributeName].Value = value;

            }

        }

        public ConfigNode(Configurations ConfigSet, string NodeName)

        {

            m_ConfigSet = ConfigSet;

            m_NodeName = NodeName;

        }

    }

    /// <summary>

    /// 1xClient配置节点类

    /// </summary>

    public sealed class Config_1xClient : ConfigNode

    {

        public Config_1xClient(Configurations ConfigSet) : base(ConfigSet, "_1xClient") { }

        /// <summary>

        /// 获取或设置文件名(不带".exe")

        /// </summary>

        public string Name

        {

            get

            {

                return base["Name"];

            }

            set

            {

                base["Name"] = value;

            }

        }

        /// <summary>

        /// 获取或设置客户端安装目录

        /// </summary>

        public string Path

        {

            get

            {

                return base["Path"];

            }

            set

            {

                base["Path"] = value;

            }

        }

    }

    /// <summary>

    /// 网络信息配置节点类

    /// </summary>

    public sealed class Config_Network : ConfigNode

    {

        public Config_Network(Configurations ConfigSet) : base(ConfigSet, "Network") { }

        /// <summary>

        /// 获取或设置网关IP地址

        /// </summary>

        public System.Net.IPAddress IpGateway

        {

            get

            {

                return System.Net.IPAddress.Parse(base["GatewayIp"]);

            }

            set

            {

                base["GatewayIp"] = value.ToString();

            }

        }

    }

    /// <summary>

    /// 监视器配置节点类

    /// </summary>

    public sealed class Config_1xWatcher : ConfigNode

    {

        public Config_1xWatcher(Configurations ConfigSet) : base(ConfigSet, "Watcher") { }

        /// <summary>

        /// 获取或设置测试网络状态的时间间隔,单位:毫秒

        /// </summary>

        public double Interval

        {

            get

            {

                return double.Parse(base["Interval"]);

            }

            set

            {

                base["Interval"] = value.ToString();

            }

        }

        /// <summary>

        /// 获取或设置测试网络状态的重试次数

        /// </summary>

        public Int16 PingRetry

        {

            get

            {

                return Int16.Parse(base["PingRetry"]);

            }

            set

            {

                base["PingRetry"] = value.ToString();

            }

        }

        /// <summary>

        /// 获取或设置检测到掉线后重新连接的延迟时间,单位:毫秒

        /// </summary>

        public int DelayBeforeReconnect

        {

            get

            {

                return int.Parse(base["DelayBeforeReconnect"]);

            }

            set

            {

                base["DelayBeforeReconnect"] = value.ToString();

            }

        }

        /// <summary>

        /// 获取或设置重新连接后再次检测的延迟时间,单位:毫秒

        /// </summary>

        public int DelayAfterReconnect

        {

            get

            {

                return int.Parse(base["DelayAfterReconnect"]);

            }

            set

            {

                base["DelayAfterReconnect"] = value.ToString();

            }

        }

        /// <summary>

        /// 获取或设置日志文件名

        /// </summary>

        public string LogFileName

        {

            get

            {

                return base["LogFileName"];

            }

            set

            {

                base["LogFileName"] = value;

            }

        }

    }

    /// <summary>

    /// 杂项配置节点类

    /// </summary>

    public sealed class Config_Others : ConfigNode

    {

        public Config_Others(Configurations ConfigSet) : base(ConfigSet, "Others") { }

        /// <summary>

        /// 获取或设置一个值,该值指示程序是否在收到“本时间段限制上网”消息时自动退出

        /// </summary>

        public bool ResponseTimeLimitMsg

        {

            get

            {

                return bool.Parse(base["ResponseTimeLimitMsg"]);

            }

            set

            {

                base["ResponseTimeLimitMsg"] = value.ToString();

            }

        }

        /// <summary>

        /// 获取或设置气球提示延迟时间

        /// </summary>

        public int BalloonTipTimeout

        {

            get

            {

                return int.Parse(base["BalloonTipTimeout"]);

            }

            set

            {

                base["BalloonTipTimeout"] = value.ToString();

            }

        }

        /// <summary>

        /// 获取或设置最大重试次数

        /// </summary>

        public Int16 MaxRetry

        {

            get

            {

                return Int16.Parse(base["MaxRetry"]);

            }

            set

            {

                base["MaxRetry"] = value.ToString();

            }

        }

    }

}

 

 

至于主程序就不帖了,就是创建C1xWatcher类的实例进行监控,和提供参数设置的GUI界面。
/Files/takamachi660/1xHelper1.5_final_bin_src.rar

你可能感兴趣的:(client)