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

posted on 2009-09-29 23:19  高町⑥⑥○  阅读(3231)  评论(2编辑  收藏  举报