using System;
using System.Collections.Generic;
using System.Text;
using System.Collections;
using System.Diagnostics;
using System.Runtime.InteropServices;
using Core.Mes.Common;
using Core.Mes.ServerFrameWork;
using System.Threading;
using System.IO;
using System.Management;
using System.Data;
using System.Security.Cryptography;
using System.Windows.Forms.DataVisualization.Charting;

namespace Core.Mes.ServerFrameWork
{
    public class ResDaemon : IDisposable
    {
        private bool disposed = false;
        private string filePath = System.Environment.CurrentDirectory + @"\log\Daemon\";
        private object lockObj = new object();
        private FileStream daemon_fs = null;
        private FileStream read_fs = null;

        private ManualResetEvent _RunningEvent = new ManualResetEvent(false);
        public delegate void ShowResDataEvent(List<DataPoint> ps1, List<DataPoint> ps2);

        private TimeSpan prevCpuTime = TimeSpan.Zero;
        private DateTime prevTime = DateTime.Now;
        public void GetMemoryUsed(out double MemUsedMB, out double CpuUsed, out DateTime curTime)
        {
            const int MB_DIV = 1024 * 1024;
            Process cur = Process.GetCurrentProcess();

            PerformanceCounter curpc = new PerformanceCounter("Process", "Working Set", cur.ProcessName);
            MemUsedMB = curpc.NextValue() / MB_DIV;

            curTime = DateTime.Now;
            if (prevCpuTime == TimeSpan.Zero)
            {
                CpuUsed = 0;
                prevTime = curTime;
                prevCpuTime = cur.TotalProcessorTime;
                return;
            }

            TimeSpan ts1 = new TimeSpan(curTime.Ticks);
            TimeSpan ts2 = new TimeSpan(prevTime.Ticks);
            double interval = ts1.Subtract(ts2).Duration().TotalMilliseconds;

            TimeSpan curCpuTime = cur.TotalProcessorTime;
            CpuUsed = (curCpuTime - prevCpuTime).TotalMilliseconds / interval / Environment.ProcessorCount * 100;
            prevCpuTime = curCpuTime;
            prevTime = curTime;

            // Debug.Print(string.Format("MEM: {0} MB    CPU: {1}", MemUsedMB, CpuUsed));
        }

        public void GetSysFreeMem(out double FreeMemMB)
        {
            SystemInfo sys = new SystemInfo();
            FreeMemMB = sys.MemoryAvailable / 1024 / 1024;
        }

        public void StartDaemon()
        {
            Thread daemon_thread = new Thread(DaemonResFunc);
            daemon_thread.Name = "资源监控实时存档";
            daemon_thread.Start();
        }

        #region 系统资源监控
        private void DaemonResFunc()
        {
            DateTime curTime;
            double memUsed = 0;
            double cpuUsed = 0;
            GetMemoryUsed(out memUsed, out cpuUsed, out curTime);

            if (!Directory.Exists(filePath))
            {
                Directory.CreateDirectory(filePath);
            }
            string logFile = Path.Combine(filePath, "DM_" + curTime.ToString("yyyyMMdd") + ".dat");
            daemon_fs = new FileStream(logFile, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.Read);

            do
            {
                WriteResData(filePath, daemon_fs);
                Thread.Sleep(1000);
            } while (true);
        }

        DateTime prev_WriteFileDate = new DateTime(2000, 1, 1);
        private void WriteResData(string _filePath, FileStream fs)
        {
            string logFile = "";
            lock (lockObj)
            {
                try
                {
                    DateTime curTime;
                    double memUsed = 0;
                    double cpuUsed = 0;
                    GetMemoryUsed(out memUsed, out cpuUsed, out curTime);

                    if (prev_ReadFileDate.Date != curTime.Date)
                    {
                        if (fs != null)
                        {
                            fs.Close();
                        }
                        if (!Directory.Exists(_filePath))
                        {
                            Directory.CreateDirectory(_filePath);
                        }
                        logFile = Path.Combine(_filePath, "DM_" + curTime.ToString("yyyyMMdd") + ".dat");

                        daemon_fs = new FileStream(logFile, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.Read);
                    }

                    try
                    {

                        int offset = (sizeof(double) + sizeof(double)) * (curTime.Hour * 60 * 60 + curTime.Minute * 60 + curTime.Second);
                        byte[] s1 = System.BitConverter.GetBytes(memUsed);
                        byte[] s2 = System.BitConverter.GetBytes(cpuUsed);
                        daemon_fs.Seek(offset, SeekOrigin.Begin);
                        daemon_fs.Write(s1, 0, s1.GetLength(0));
                        daemon_fs.Write(s2, 0, s2.GetLength(0));

                        daemon_fs.Flush();
                        prev_WriteFileDate = curTime;
                    }
                    catch (Exception ex) { Debug.Print(ex.Message); }
                }
                catch
                {
                    // do nothing.
                }
            }
        }

        public DataTable DaemonResData(DateTime curDate, int count, int interval)
        {
            if (count < 1) count = 1;
            if (interval < 1) interval = 1;
            DateTime idx_date = curDate.AddSeconds(-1 * (count - 1) * interval);

            DateTime prev_Date = idx_date.Date;
            string logFile = Path.Combine(filePath, "DM_" + curDate.ToString("yyyyMMdd") + ".dat");

            DataTable table = new DataTable();
            table.Columns.Add("Time", typeof(DateTime));
            table.Columns.Add("MemUsed", typeof(double));
            table.Columns.Add("CpuUsed", typeof(double));
            table.Columns.Add("EMPTY", typeof(int));

            do
            {
                getFile(idx_date);
                if (read_fs != null)
                {
                    double d_memUsed = 0;
                    double d_cpuUsed = 0;
                    byte[] data1 = new byte[sizeof(double)];
                    byte[] data2 = new byte[sizeof(double)];
                    try
                    {
                        read_fs.Seek((idx_date.Hour * 60 * 60 + idx_date.Minute * 60 + idx_date.Second) * (sizeof(double) + sizeof(double)), SeekOrigin.Begin);
                        read_fs.Read(data1, 0, sizeof(double));
                        read_fs.Read(data2, 0, sizeof(double));
                        d_memUsed = System.BitConverter.ToDouble(data1, 0);
                        d_cpuUsed = System.BitConverter.ToDouble(data2, 0);
                    }
                    catch { }
                    DataRow dr = table.NewRow();
                    dr[0] = idx_date;
                    dr[1] = d_memUsed;
                    dr[2] = d_cpuUsed;

                    if (d_memUsed < 0.00001)
                    {
                        dr[3] = 0;
                        if (table.Rows.Count > 0 && (int)(table.Rows[table.Rows.Count - 1][3]) == 1)
                        {
                            dr[1] = table.Rows[table.Rows.Count - 1][1];
                            dr[2] = table.Rows[table.Rows.Count - 1][2];
                        }
                    }
                    else
                    {
                        dr[3] = 1;
                    }

                    table.Rows.Add(dr);
                }
                idx_date = idx_date.AddSeconds(interval);
            } while (idx_date <= curDate);

            table.AcceptChanges();
            return table;
        }

        DateTime prev_ReadFileDate = new DateTime(2000, 1, 1);
        private void getFile(DateTime cur_Date)
        {
            string logFile = Path.Combine(filePath, "DM_" + cur_Date.ToString("yyyyMMdd") + ".dat");
            if (cur_Date.Date == prev_ReadFileDate.Date)
            {
                if (read_fs == null && File.Exists(logFile))
                {
                    read_fs = new FileStream(logFile, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
                }
            }
            else
            {
                if (read_fs != null)
                {
                    read_fs.Close();
                }
                read_fs = null;
                if (File.Exists(logFile))
                {
                    read_fs = new FileStream(logFile, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
                }
            }
            prev_ReadFileDate = cur_Date;
        }

        public void SuspendMe()
        {
            _RunningEvent.Reset();
        }
        public void ResumeMe()
        {
            _RunningEvent.Set();
        }

        public void ShowResData(Chart ctl_chart, ShowResDataEvent srde)
        {
            do
            {
                _RunningEvent.WaitOne();
                List<DataPoint> s1 = new List<DataPoint>();
                List<DataPoint> s2 = new List<DataPoint>();

                if (ctl_chart.Series[0].Points.Count > 0)
                {
                    foreach (DataPoint dp in ctl_chart.Series[0].Points)
                    {
                        s1.Add(dp);
                    }
                }
                if (ctl_chart.Series[1].Points.Count > 0)
                {
                    foreach (DataPoint dp in ctl_chart.Series[1].Points)
                    {
                        s2.Add(dp);
                    }
                }

                int Interval = 2000;
                DataTable datas = DaemonResData(DateTime.Now.AddSeconds(-1), 100, Interval / 1000);

                if (s1 != null && s1.Count > 0 && datas.Rows.Count > 0)
                {
                    if (((DateTime)(datas.Rows[0][0])).CompareTo((DateTime)(s1[0].Tag)) < 0)
                    {
                        s1.Clear();
                        s2.Clear();
                    }
                }

                if (s1.Count == 0)
                {
                    foreach (DataRow dr in datas.Rows)
                    {
                        DataPoint dp1 = new DataPoint();
                        dp1.SetValueXY((DateTime)dr[0], (double)dr[1]);

                        dp1.Tag = (DateTime)dr[0];
                        s1.Add(dp1);

                        DataPoint dp2 = new DataPoint();
                        dp2.SetValueXY((DateTime)dr[0], (double)dr[2]);
                        dp2.Tag = (DateTime)dr[0];
                        s2.Add(dp2);

                        //Debug.Print(string.Format("READ MEM:{0}  CPU:{1}", dp1.YValues[0], dp2.YValues[0]));
                    }
                }
                else
                {
                    string str_date = ((DateTime)(s1[s1.Count - 1].Tag)).ToString("yyyy-MM-dd HH:mm:ss");

                    DataRow[] drs = datas.Select(string.Format("TIME > CONVERT( '{0}','System.DateTime')", str_date), "TIME");
                    foreach (DataRow dr in drs)
                    {

                        DataPoint dp1 = new DataPoint();
                        dp1.SetValueXY((DateTime)dr[0], (double)dr[1]);
                        dp1.Tag = (DateTime)dr[0];
                        s1.Add(dp1);

                        DataPoint dp2 = new DataPoint();
                        dp2.SetValueXY((DateTime)dr[0], (double)dr[2]);
                        dp2.Tag = (DateTime)dr[0];
                        s2.Add(dp2);

                        //Debug.Print(string.Format("READ MEM:{0}  CPU:{1}", dp1.YValues[0], dp2.YValues[0]));

                        s1.RemoveAt(0);
                        s2.RemoveAt(0);
                    }
                }

                if (srde != null)
                {
                    srde.Invoke(s1, s2);
                }

                Thread.Sleep(2000);
            } while (true);
        }

        #endregion

        public void Dispose()
        {
            if (!disposed)
            {
                if (daemon_fs != null)
                {
                    daemon_fs.Close();
                }
                if (read_fs != null)
                {
                    read_fs.Close();
                }
                disposed = true;
            }
        }
    }

    public class SrvDaemon //: IDisposable
    {
        private ManualResetEvent _RunningEvent = new ManualResetEvent(false);
        public delegate void ShowSrvDataEvent(List<DataPoint> ps1, List<DataPoint> ps2);
        private object obj_lock = new object();
        private FileStream write_fs = null;
        private string filePath = System.Environment.CurrentDirectory + @"\log\Daemon\";

        private Hashtable HtAssemblyServer = null;
        private Hashtable _srvClassManager = new Hashtable();
        private Hashtable _srvUsedManager = new Hashtable();

        public Hashtable SrvClassManager
        {
            get { return _srvClassManager; }
        }

        public SrvDaemon(Hashtable HtServers)
        {
            HtAssemblyServer = HtServers;
            InitSrvDaemon();
        }

        private void InitSrvDaemon()
        {
            if (HtAssemblyServer == null) return;
            foreach (string serverName in HtAssemblyServer.Keys)
            {
                IServerPool sPool = (IServerPool)HtAssemblyServer[serverName];
                foreach (string className in sPool.HtComponent.Keys)
                {
                    GetSrvClsInfo(serverName, className, "");
                    sPool.srvDaemon = this;
                }
            }
        }

        public SrvClassInfo GetSrvClsInfo(string serverName, string className, string methodName)
        {
            SrvClassInfo svi = null;
            string _sName = serverName.Trim().ToUpper();
            string _cName = string.IsNullOrEmpty(className.Trim().ToUpper()) ? "" : ("." + className.Trim().ToUpper());
            string _mName = string.IsNullOrEmpty(methodName.Trim().ToUpper()) ? "" : ("." + methodName.Trim().ToUpper());
            string _name = _sName + _cName + _mName;
            if (!_srvClassManager.ContainsKey(_name))
            {
                svi = new SrvClassInfo();
                svi.ServerName = serverName.ToUpper();
                svi.ClassName = className.ToUpper();
                svi.AvgMemUsed = 30;
                svi.TotalCalled = 0;
                svi.MethodName = "";
                svi.SrvEvents = new LinkedList<SrvEventItem>();

                _srvClassManager.Add(_name, svi);
            }
            else
            {
                svi = (SrvClassInfo)(_srvClassManager[_name]);
            }
            return svi;
        }

        public void StartDaemon()
        {
            Thread daemon_thread = new Thread(DaemonResFunc);
            daemon_thread.Name = "服务监控实时存档";
            daemon_thread.Start();
        }

        #region 系统资源监控
        public void SuspendMe()
        {
            _RunningEvent.Reset();
        }

        public void ResumeMe()
        {
            _RunningEvent.Set();
        }

        private void DaemonResFunc()
        {
            do
            {
                try
                {
                    CreateMemSnap();
                }
                catch (Exception ex)
                {
                    Debug.Print(ex.Message);
                }
                Thread.Sleep(2000);
            } while (true);
        }

        DateTime PrevSnapTime = new DateTime(1900, 1, 1);
        private void CreateMemSnap()
        {
            if (HtAssemblyServer == null) return;

            lock (obj_lock)
            {
                PrevSnapTime = DateTime.Now;

                Process cur = Process.GetCurrentProcess();
                PerformanceCounter curpc = new PerformanceCounter("Process", "Working Set", cur.ProcessName);
                double MemUsedMB = curpc.NextValue() / 1024 / 1024;

                double CurBsy_HisMem = 0;
                Hashtable CurBsySrv = new Hashtable();

                foreach (string serverName in HtAssemblyServer.Keys)
                {
                    try
                    {
                        SrvUsedInfo sui = null;

                        //循环服务,获取服务使用情况
                        if (!_srvUsedManager.ContainsKey(serverName))
                        {
                            sui = new SrvUsedInfo();
                            sui.ServerName = serverName.ToUpper();
                            _srvUsedManager.Add(serverName, sui);
                        }
                        else
                        {
                            sui = (SrvUsedInfo)_srvUsedManager[serverName];
                            sui.CallingMethod.Clear();
                        }

                        lock (_srvUsedManager[serverName])
                        {
                            sui.CurrentUsed = 0;
                            sui.MaxLimit = 0;

                            //循环服务提供类
                            IServerPool sPool = (IServerPool)HtAssemblyServer[serverName];
                            foreach (string className in sPool.HtComponent.Keys)
                            {
                                Hashtable classPoolHash = (Hashtable)sPool.HtComponent[className];

                                sui.MaxLimit += classPoolHash.Contains(2) ? ((int)classPoolHash[2]) : 30;

                                string _clsFullName = serverName.ToUpper() + "." + className.ToUpper();
                                if (classPoolHash != null)
                                {
                                    if (classPoolHash.ContainsKey(1) && classPoolHash[1] != null)
                                    {
                                        ArrayList bsyList = (ArrayList)classPoolHash[1];
                                        sui.CurrentUsed += bsyList.Count;

                                        //循环忙列表
                                        foreach (IComponent module in bsyList)
                                        {
                                            sui.CallingMethod.Add(module.CallingMethod.ToUpper());

                                            string method_name = _clsFullName + "." + module.CallingMethod.ToUpper();
                                            SrvClassInfo sci = null;
                                            if (!_srvClassManager.ContainsKey(method_name))
                                            {
                                                sci = new SrvClassInfo();
                                                sci.ServerName = serverName.ToUpper();
                                                sci.ClassName = className.ToUpper();
                                                sci.MethodName = module.CallingMethod.ToUpper();
                                                if (sci.TotalCalled == long.MaxValue) sci.TotalCalled = 0;
                                                sci.TotalCalled += 1;

                                                sci.AvgMemUsed = 30;

                                                _srvClassManager.Add(method_name, sci);
                                            }
                                            else
                                            {
                                                sci = (SrvClassInfo)_srvClassManager[method_name];
                                            }

                                            if (!CurBsySrv.ContainsKey(method_name))
                                            {
                                                CurBsySrv.Add(method_name, 1);
                                                CurBsy_HisMem += sci.AvgMemUsed;
                                            }
                                            else
                                            {
                                                CurBsySrv[method_name] = (int)(CurBsySrv[method_name]) + 1;
                                                CurBsy_HisMem += sci.AvgMemUsed;
                                            }
                                        }

                                    }
                                }
                            }
                        }
                    }
                    catch { }
                }


                //计算主线程
                SrvClassInfo main_sci;
                if (!_srvClassManager.ContainsKey("MAIN"))
                {
                    main_sci = new SrvClassInfo();
                    main_sci.ServerName = "MAIN";
                    main_sci.AvgMemUsed = 30;

                    _srvClassManager.Add("MAIN", main_sci);
                }
                else
                {
                    main_sci = (SrvClassInfo)_srvClassManager["MAIN"];
                }

                if (!CurBsySrv.ContainsKey("MAIN"))
                {
                    CurBsySrv.Add("MAIN", 1);
                    CurBsy_HisMem += main_sci.AvgMemUsed;
                }

                foreach (string cbs in CurBsySrv.Keys)
                {
                    lock (_srvClassManager[cbs])
                    {
                        for (int idx = 0; idx < (int)(CurBsySrv[cbs]); idx++)
                        {
                            double cm = (long)(((SrvClassInfo)_srvClassManager[cbs]).AvgMemUsed * 1.0 / CurBsy_HisMem * MemUsedMB);
                            LinkedList<SrvEventItem> nodes = ((SrvClassInfo)_srvClassManager[cbs]).SrvEvents;
                            ((SrvClassInfo)_srvClassManager[cbs]).AvgMemUsed = (((SrvClassInfo)_srvClassManager[cbs]).AvgMemUsed * nodes.Count + cm) / (nodes.Count + 1);
                            SrvEventItem sei;
                            sei.dt = PrevSnapTime;
                            sei._memUsed = cm;

                            nodes.AddLast(sei);
                            if (nodes.Count > 100) nodes.RemoveFirst();
                        }
                    }
                }
            }
        }
        #endregion

        public void ShowSrvData(ShowSrvDataEvent ssde)
        {
            do
            {
                _RunningEvent.WaitOne();
                List<DataPoint> s1 = new List<DataPoint>();
                List<DataPoint> s2 = new List<DataPoint>();

                ArrayList _keys = new ArrayList();

                foreach (string ServerName in _srvUsedManager.Keys)
                {
                    _keys.Add(ServerName);
                }
                _keys.Sort();

                int idx = 0;
                foreach (string ServerName in _keys)
                {
                    SrvUsedInfo sui = (SrvUsedInfo)_srvUsedManager[ServerName];
                    DataPoint dp = new DataPoint();
                    dp.SetValueXY(idx, sui.CurrentUsed);
                    //dp.SetValueXY(idx, sui.MaxLimit == 0 ? (sui.CurrentUsed > 0 ? 1 : 0) : sui.CurrentUsed / sui.MaxLimit);
                    dp.ToolTip = string.Format("{0}\n {1}/{2}", ServerName, sui.CurrentUsed, sui.MaxLimit);
                    dp.LabelToolTip = ServerName;
                    s1.Add(dp);

                    dp = new DataPoint();
                    //dp.SetValueXY(idx, sui.MaxLimit - sui.CurrentUsed > 0 ? sui.MaxLimit - sui.CurrentUsed : 0);
                    dp.SetValueXY(idx, sui.MaxLimit);
                    dp.ToolTip = string.Format("{0}\n {1}/{2}", ServerName, sui.CurrentUsed, sui.MaxLimit);
                    dp.LabelToolTip = ServerName;
                    s2.Add(dp);
                    idx++;
                }

                if (ssde != null)
                {
                    ssde.Invoke(s1, s2);
                }

                Thread.Sleep(2500);
            } while (true);
        }

        private void WriteSrvData(Hashtable srv)
        {
            string logFile = Path.Combine(filePath, "DM_ServerUsed.tmp");
            string logFile1 = Path.Combine(filePath, "DM_ServerUsed.dat");
            if (write_fs != null)
            {
                write_fs.Close();
            }
            lock (srv)
            {
                try
                {
                    write_fs = new FileStream(logFile, FileMode.OpenOrCreate, FileAccess.Write, FileShare.None);
                    write_fs.Seek(0, SeekOrigin.Begin);
                    write_fs.SetLength(0);
                    foreach (SrvClassInfo svi in srv)
                    {
                        byte[] b_svi = Utility.SerializeAndCompressObject(svi);
                        long l_size = b_svi.GetLongLength(0);
                        byte[] b_size = System.BitConverter.GetBytes(l_size);

                        write_fs.Write(b_size, 0, b_size.GetLength(0));
                        write_fs.Write(b_svi, 0, b_svi.GetLength(0));
                    }
                    write_fs.Flush();
                    write_fs.Close();
                    if (File.Exists(logFile1))
                    {
                        File.Delete(logFile1);
                    }
                    File.Move(logFile, logFile1);
                }
                catch { }
                finally
                {
                    write_fs.Close();
                }
            }

        }
    }

    public class ExtSrvDaemon
    {
        public delegate void ShowExtSrvEvent();
        private ManualResetEvent _RunningEvent = new ManualResetEvent(false);

        #region 扩展服务监控
        public void ShowExtServer(ShowExtSrvEvent sese)
        {
            do
            {
                if (sese != null)
                {
                    sese();
                }
                Thread.Sleep(5000);
            } while (true);
        }

        public void SuspendMe()
        {
            _RunningEvent.Reset();
        }
        public void ResumeMe()
        {
            _RunningEvent.Set();
        }
        #endregion
    }

    public class SystemInfo
    {
        private int m_ProcessorCount = 0;   //CPU个数
        private PerformanceCounter pcCpuLoad;   //CPU计数器
        private long m_PhysicalMemory = 0;   //物理内存

        private const int GW_HWNDFIRST = 0;
        private const int GW_HWNDNEXT = 2;
        private const int GWL_STYLE = (-16);
        private const int WS_VISIBLE = 268435456;
        private const int WS_BORDER = 8388608;

        #region AIP声明
        [DllImport("IpHlpApi.dll")]
        extern static public uint GetIfTable(byte[] pIfTable, ref uint pdwSize, bool bOrder);

        [DllImport("User32")]
        private extern static int GetWindow(int hWnd, int wCmd);

        [DllImport("User32")]
        private extern static int GetWindowLongA(int hWnd, int wIndx);

        [DllImport("user32.dll")]
        private static extern bool GetWindowText(int hWnd, StringBuilder title, int maxBufSize);

        [DllImport("user32", CharSet = CharSet.Auto)]
        private extern static int GetWindowTextLength(IntPtr hWnd);
        #endregion

        #region 构造函数
        /// <summary>
        /// 构造函数，初始化计数器等
        /// </summary>
        public SystemInfo()
        {
            //初始化CPU计数器
            pcCpuLoad = new PerformanceCounter("Processor", "% Processor Time", "_Total");
            pcCpuLoad.MachineName = ".";
            pcCpuLoad.NextValue();

            //CPU个数
            m_ProcessorCount = Environment.ProcessorCount;

            //获得物理内存
            ManagementClass mc = new ManagementClass("Win32_ComputerSystem");
            ManagementObjectCollection moc = mc.GetInstances();
            foreach (ManagementObject mo in moc)
            {
                if (mo["TotalPhysicalMemory"] != null)
                {
                    m_PhysicalMemory = long.Parse(mo["TotalPhysicalMemory"].ToString());
                }
            }
        }
        #endregion

        #region CPU个数
        /// <summary>
        /// 获取CPU个数
        /// </summary>
        public int ProcessorCount
        {
            get
            {
                return m_ProcessorCount;
            }
        }
        #endregion

        #region CPU占用率
        /// <summary>
        /// 获取CPU占用率
        /// </summary>
        public float CpuLoad
        {
            get
            {
                return pcCpuLoad.NextValue();
            }
        }
        #endregion

        #region 可用内存
        /// <summary>
        /// 获取可用内存
        /// </summary>
        public long MemoryAvailable
        {
            get
            {
                long availablebytes = 0;
                //ManagementObjectSearcher mos = new ManagementObjectSearcher("SELECT * FROM Win32_PerfRawData_PerfOS_Memory");
                //foreach (ManagementObject mo in mos.Get())
                //{
                //    availablebytes = long.Parse(mo["Availablebytes"].ToString());
                //}
                ManagementClass mos = new ManagementClass("Win32_OperatingSystem");
                foreach (ManagementObject mo in mos.GetInstances())
                {
                    if (mo["FreePhysicalMemory"] != null)
                    {
                        availablebytes = 1024 * long.Parse(mo["FreePhysicalMemory"].ToString());
                    }
                }
                return availablebytes;
            }
        }
        #endregion

        #region 物理内存
        /// <summary>
        /// 获取物理内存
        /// </summary>
        public long PhysicalMemory
        {
            get
            {
                return m_PhysicalMemory;
            }
        }
        #endregion

        #region 结束指定进程
        /// <summary>
        /// 结束指定进程
        /// </summary>
        /// <param name="pid">进程的 Process ID</param>
        public static void EndProcess(int pid)
        {
            try
            {
                Process process = Process.GetProcessById(pid);
                process.Kill();
            }
            catch { }
        }
        #endregion


        #region 查找所有应用程序标题
        /// <summary>
        /// 查找所有应用程序标题
        /// </summary>
        /// <returns>应用程序标题范型</returns>
        public static List<string> FindAllApps(int Handle)
        {
            List<string> Apps = new List<string>();

            int hwCurr;
            hwCurr = GetWindow(Handle, GW_HWNDFIRST);

            while (hwCurr > 0)
            {
                int IsTask = (WS_VISIBLE | WS_BORDER);
                int lngStyle = GetWindowLongA(hwCurr, GWL_STYLE);
                bool TaskWindow = ((lngStyle & IsTask) == IsTask);
                if (TaskWindow)
                {
                    int length = GetWindowTextLength(new IntPtr(hwCurr));
                    StringBuilder sb = new StringBuilder(2 * length + 1);
                    GetWindowText(hwCurr, sb, sb.Capacity);
                    string strTitle = sb.ToString();
                    if (!string.IsNullOrEmpty(strTitle))
                    {
                        Apps.Add(strTitle);
                    }
                }
                hwCurr = GetWindow(hwCurr, GW_HWNDNEXT);
            }

            return Apps;
        }

        private byte[] CalcSHA(string Content)
        {
            SHA256Managed sh = new SHA256Managed();
            byte[] bs = System.Text.Encoding.Default.GetBytes(Content);
            return sh.ComputeHash(bs);
        }

        #endregion
    }

    [Serializable]
    public struct SrvEventItem
    {
        public DateTime dt;
        public double _memUsed;
    }

    [Serializable]
    public class SrvClassInfo
    {
        public string ServerName = "";
        public string ClassName = "";
        public string MethodName = "";
        public long TotalCalled = 0;
        public double AvgMemUsed = 10;
        public LinkedList<SrvEventItem> SrvEvents = new LinkedList<SrvEventItem>();
    }

    public class SrvUsedInfo
    {
        public string ServerName = "";
        public string ClassName = "";
        public int MaxLimit = 0;
        public int CurrentUsed = 0;
        public ArrayList CallingMethod = new ArrayList();
    }

}
