• 程序监控 小结(1)


    最近一直忙一个专案,是做一个程式监控系统,这个系统其实没有什么,就是要达到在网络上去控制公司其他的程式,主要包括更新程式文件,上传文件,查看运行状态,编辑监控程式的配置文件,开启关闭预约重起目标电脑,下载log档案,在线查看操作日志。

    这个系统设计主要分三层架构设计,一个是目标机器中的管理程式,一个是放置于中间网络的传输程式,一个是用来查看并操作的客户端,其中中间程式可以由1个到n个,这个就方便了扩展,因为程式不是在一个地方运行,可能在很多地方运行很多。

    在这个系统中重点我想应该有这么几个

    1.是网络传输,定义一套用来传输的协议格式,使用tcp的方式进行连接,同时确保tcp连接的有效性,即需要有自动重连接机制以及其他的安全机制。

    2.程式的运行状态的获取,这个获取包括获取很多信息,包括程式的图标,CPU,Memory, ThreadCount,Handle等...

    3.程式文件的更新上传等操作,这个部分我想应该归纳到网络传输的部分。

    其实功能上看没有什么,但是要把这些组织起来并且生成一个系统统一管理还是挺麻烦的,因为监控端很多,并且每个监控端都要监控很多程式,还要保证监控端不能过多的使用CPU等资源。网络传递大文件时的传输机制...等等,反正烦的事有好多,不过还好现在已经基本完成了。

    现在把我做这个系统是涉及到的一些小知识点记录下来,以便以后使用。

    下面开始了

    一.程序运行状态的获取,包括CPU利用率,内存使用情况,线程个数等信息。

    运行状态的获取我使用的方法是使用性能计数器组件,PerformanceCounter。

    首先定义一些计数器,如下:

    #region ForProcessFun
    PerformanceCounter pcCPU ;
    PerformanceCounter pcMemory ;
    PerformanceCounter pcVMemory;
    PerformanceCounter pcMemoryPeak;
    PerformanceCounter pcHandle;
    PerformanceCounter pcThread;
    PerformanceCounter pcID;
    PerformanceCounter pTimes;

    #endregion

    #region ForProcess
    public const string ProcessObject = "Process";
    public const string CPUPerS = "% Processor Time";
    public const string MemoryS = "Working Set";
    public const string MemoryPeakS = "Working Set Peak";
    public const string VMemoryS = "Private Bytes";
    public const string VMemoryPeekS = "";
    public const string HandleS = "Handle Count";
    public const string ThreadS = "Thread Count";
    public const string IDS = "ID Process";
    public const string ElapsedTimes = "Elapsed Time";

    public const string ProcessorObject = "Processor";
    public const string TotalS ="_Total";
    #endregion

    调用方法如下:

    pcCPU = new PerformanceCounter(ProcessObject,CPUPerS,this._ExeName);
    pinfo.CPU = ((int)pcCPU.NextValue()).ToString() + " %";

    pcMemory = new PerformanceCounter(ProcessObject,MemoryS,this._ExeName);
    pinfo.Memory = Common.Adddouhao((pcMemory.NextValue() /1024).ToString()) + " k";

    pcVMemory = new PerformanceCounter(ProcessObject,VMemoryS,this._ExeName);
    pinfo.VMemory = Common.Adddouhao((pcVMemory.NextValue() /1024).ToString()) + " k";

    pcMemoryPeak = new PerformanceCounter(ProcessObject,MemoryPeakS,this._ExeName);
    pinfo.MemoryPeek = Common.Adddouhao((pcMemoryPeak.NextValue() /1024).ToString()) + " k";

    pcHandle = new PerformanceCounter(ProcessObject,HandleS,this._ExeName);
    pinfo.Handle = pcHandle.NextValue().ToString();

    pcThread = new PerformanceCounter(ProcessObject,ThreadS,this._ExeName);
    pinfo.ThreadCount = pcThread.NextValue().ToString();

    其实很简单,就是定义一个性能计数器,然后获取值。其中_ExeName是在进程管理器中的名称。

    因为这个地方我是通过路径名去获取这个程式在进程中的名称,但是在进程管理器中显示的名称有时会显示短名称(不知道是不是这么这叫,就是不是exe的名称了,变成有^的那在种了),如果变名了就获取不到它的运行值了。

    可以使用API把长路径和短路径进行转换,API的定义如下:

    [DllImport("kernel32.dll",CharSet = CharSet.Auto)]
    public static extern int GetShortPathName(
      [MarshalAs(UnmanagedType.LPTStr)]
      string path,
      [MarshalAs(UnmanagedType.LPTStr)]
      System.Text.StringBuilder shortPath,
      int shortPathLength);

    [DllImport("kernel32.dll",CharSet = CharSet.Auto)]
    public static extern int GetLongPathName(
      [MarshalAs(UnmanagedType.LPTStr)]
      string path,
      [MarshalAs(UnmanagedType.LPTStr)]
      System.Text.StringBuilder shortPath,
      int shortPathLength);
    调用方法:

    变成短路径:

    System.Text.StringBuilder shortname = new System.Text.StringBuilder(128);

    Common.GetShortPathName(this.AppPath,shortname,128);
    _ExeName = System.IO.Path.GetFileNameWithoutExtension(shortname.ToString());

    使用WMI获取运行的状态,这个方法是开始设计的时候打算使用的方法,但是后来取消这个方法了全部使用上面的方法,不过这里也说一下.

    代码片断:

    public void GetProcessAll()
    {
    try
    {
    SelectQuery query=new SelectQuery("Select * From Win32_PerfFormattedData_PerfProc_Process");
    ManagementObjectSearcher searcher=new ManagementObjectSearcher(query);
    this.ProcessAllTable.count = 0;
    ManagementObjectCollection coll = searcher.Get();
    this.ProcessAllTable.count = coll.Count;
    this.ProcessAllTable.table = new Win32_PerfFormattedData_PerfProc_Process[this.ProcessAllTable.count];
    int i = 0;
    foreach(ManagementBaseObject p in coll)
    {
    Win32_PerfFormattedData_PerfProc_Process po = new Win32_PerfFormattedData_PerfProc_Process();
    po.Caption = p["Caption"]==null?"":p["Caption"].ToString();
    po.CreatingProcessID = p["CreatingProcessID"]==null?"":p["CreatingProcessID"].ToString();
    po.Description = p["Description"]==null?"":p["Description"].ToString();
    po.ElapsedTime = p["ElapsedTime"]==null?"":p["ElapsedTime"].ToString();
    po.Frequency_Object = p["Frequency_Object"]==null?"":p["Frequency_Object"].ToString();
    po.Frequency_PerfTime = p["Frequency_PerfTime"]==null?"":p["Frequency_PerfTime"].ToString();
    po.Frequency_Sys100NS = p["Frequency_Sys100NS"]==null?"":p["Frequency_Sys100NS"].ToString();
    po.HandleCount = p["HandleCount"]==null?"":p["HandleCount"].ToString();
    po.IDProcess = p["IDProcess"]==null?"":p["IDProcess"].ToString();
    po.IODataBytesPerSec = p["IODataBytesPerSec"]==null?"":p["IODataBytesPerSec"].ToString();
    po.IODataOperationsPerSec = p["IODataOperationsPerSec"]==null?"":p["IODataOperationsPerSec"].ToString();
    po.IOOtherBytesPerSec = p["IOOtherBytesPerSec"]==null?"":p["IOOtherBytesPerSec"].ToString();
    po.IOOtherOperationsPerSec = p["IOOtherOperationsPerSec"]==null?"":p["IOOtherOperationsPerSec"].ToString();
    po.IOReadBytesPerSec = p["IOReadBytesPerSec"]==null?"":p["IOReadBytesPerSec"].ToString();
    po.IOReadOperationsPerSec = p["IOReadOperationsPerSec"]==null?"":p["IOReadOperationsPerSec"].ToString();
    po.IOWriteBytesPerSec = p["IOWriteBytesPerSec"]==null?"":p["IOWriteBytesPerSec"].ToString();
    po.IOWriteOperationsPerSec = p["IOWriteOperationsPerSec"]==null?"":p["IOWriteOperationsPerSec"].ToString();
    po.Name = p["Name"]==null?"":p["Name"].ToString();
    po.PageFaultsPerSec = p["PageFaultsPerSec"]==null?"":p["PageFaultsPerSec"].ToString();
    po.PageFileBytes = p["PageFileBytes"]==null?"":p["PageFileBytes"].ToString();
    po.PageFileBytesPeak = p["PageFileBytesPeak"]==null?"":p["PageFileBytesPeak"].ToString();
    po.PercentPrivilegedTime = p["PercentPrivilegedTime"]==null?"":p["PercentPrivilegedTime"].ToString();
    po.PercentProcessorTime = p["PercentProcessorTime"]==null?"":p["PercentProcessorTime"].ToString();
    po.PercentUserTime = p["PercentUserTime"]==null?"":p["PercentUserTime"].ToString();
    po.PoolNonpagedBytes = p["PoolNonpagedBytes"]==null?"":p["PoolNonpagedBytes"].ToString();
    po.PoolPagedBytes = p["PoolPagedBytes"]==null?"":p["PoolPagedBytes"].ToString();
    po.PriorityBase = p["PriorityBase"]==null?"":p["PriorityBase"].ToString();
    po.PrivateBytes = p["PrivateBytes"]==null?"":p["PrivateBytes"].ToString();
    po.ThreadCount = p["ThreadCount"]==null?"":p["ThreadCount"].ToString();
    po.Timestamp_Object = p["Timestamp_Object"]==null?"":p["Timestamp_Object"].ToString();
    po.Timestamp_PerfTime = p["Timestamp_PerfTime"]==null?"":p["Timestamp_PerfTime"].ToString();
    po.Timestamp_Sys100NS = p["Timestamp_Sys100NS"]==null?"":p["Timestamp_Sys100NS"].ToString();
    po.VirtualBytes = p["VirtualBytes"]==null?"":p["VirtualBytes"].ToString();
    po.VirtualBytesPeak = p["VirtualBytesPeak"]==null?"":p["VirtualBytesPeak"].ToString();
    po.WorkingSet = p["WorkingSet"]==null?"":p["WorkingSet"].ToString();
    po.WorkingSetPeak = p["WorkingSetPeak"]==null?"":p["WorkingSetPeak"].ToString();
    this.ProcessAllTable.table[i] = po;
    i++;
    }
    }
    catch(System.Exception exp)
    {
    string s = exp.Message;
    this.ProcessAllTable.count = 0;
    }
    }
    其中Win32_PerfFormattedData_PerfProc_Process 为一个自己定义的类,定义如下:

    public class Win32_PerfFormattedData_PerfProc_Process
    {
    public string Caption= "";
    public string CreatingProcessID= "";//指创建的处理的处理 Process ID。创建进程可能已终止,这个值可能已          经不在识别一个运行的处理。
    public string Description= "";
    public string ElapsedTime= "";//这个处理运行的总时间(用秒计算)
    public string Frequency_Object= "";
    public string Frequency_PerfTime= "";
    public string Frequency_Sys100NS= "";
    public string HandleCount= "";
    public string IDProcess= "";//ID Process 指这个处理的特别的识别符。ID Process 号可重复使用,所以这些 ID Process 号只能在一个处理的寿命期内识别那个处理。
    public string IODataBytesPerSec= "";//处理从 I/O 操作读取/写入字节的速度。这个计数器为所有由本处理产生的包括文件、网络和设备 I/O 的活动计数。
    public string IODataOperationsPerSec= "";
    public string IOOtherBytesPerSec= "";
    public string IOOtherOperationsPerSec= "";
    public string IOReadBytesPerSec= "";
    public string IOReadOperationsPerSec= "";
    public string IOWriteBytesPerSec= "";
    public string IOWriteOperationsPerSec= "";
    public string Name= "";
    public string PageFaultsPerSec= "";
    public string PageFileBytes= "";
    public string PageFileBytesPeak= "";
    public string PercentPrivilegedTime= "";
    public string PercentProcessorTime= "";//cpu利用率
    public string PercentUserTime= "";
    public string PoolNonpagedBytes= "";
    public string PoolPagedBytes= "";
    public string PriorityBase= "";
    public string PrivateBytes= "";
    public string ThreadCount= "";
    public string Timestamp_Object= "";
    public string Timestamp_PerfTime= "";
    public string Timestamp_Sys100NS= "";
    public string VirtualBytes= "";//虚拟地址空间的以字节数
    public string VirtualBytesPeak= "";
    public string WorkingSet= "";//Working Set 指这个处理的 Working Set 中的当前字节数。
    public string WorkingSetPeak= "";// Working Set 的最大字节数
    }

    上面的方法只是获取进程的一些信息,如果要获取OS的信息或其他信息可以参考MSDN中对WMI的描述在改一个如上的。不过.net中好像有关于WMI的类。不过我没有去找过。有兴趣的朋友可以查一下看看。

    获取硬盘信息的WMI处理方法:

    SelectQuery query=new SelectQuery("Select * From Win32_LogicalDisk where DriveType=3");
    ManagementObjectSearcher searcher=new ManagementObjectSearcher(query);
    System.Management.ManagementObjectCollection moc = searcher.Get();
    int count = moc.Count;
    einfo.DiskName = new string[count];
    einfo.DiskTotalSize = new string[count];
    einfo.DiskFreeSize = new string[count];
    int i = 0;
    foreach(ManagementBaseObject disk in searcher.Get())
    {
    if(disk["VolumeName"].ToString() == "")
    {
    einfo.DiskName[i] = disk["Name"].ToString();
    }
    else
    {
    einfo.DiskName[i] = disk["Name"].ToString() + "[" + disk["VolumeName"].ToString() + "]";
    }
    einfo.DiskTotalSize[i] = disk["Size"].ToString();
    einfo.DiskFreeSize[i] = disk["FreeSpace"].ToString();
    i++;
    Console.WriteLine("\r\n"+disk["Name"] +" "+disk["DriveType"] + " " + disk["VolumeName"]);
    }

    二.获取程序的icon及设定的日志文件程式文件列表。

    获取ICON我使用的是API获取,因为这个方法获取到程式的ICON效果不是很好,但是在我这个系统中这个方法也可以了。要获取更清晰的ICON我也不知道,要是哪位高手知道希望也告诉我一下,这里先谢谢了。

    获取ICON的类:也是在网络上找到的。

    public class CIcon
    {
    private const UInt32 SHGFI_ICON = 0x100;
    private const UInt32 SHGFI_LARGEICON = 0x0; // 'Large icon
    private const UInt32 SHGFI_SMALLICON = 0x1; // 'Small icon

    [DllImport("shell32.dll")]
    private static extern IntPtr SHGetFileInfo(string pszPath,
    UInt32 dwFileAttributes, ref SHFILEINFO psfi, UInt32 cbSizeFileInfo,
    UInt32 uFlags);

    [StructLayout(LayoutKind.Sequential)]
    private struct SHFILEINFO
    {
    public IntPtr hIcon;
    public IntPtr iIcon;
    public UInt32 dwAttributes;
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
    public string szDisplayName;
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 80)]
    public string szTypeName;
    };

    public static System.Drawing.Icon GetIcon(string filename,bool
    b_large_icon)
    {
    UInt32 icon_size;
    if (b_large_icon)
    icon_size=SHGFI_LARGEICON;
    else
    icon_size=SHGFI_SMALLICON;

    IntPtr hImgSmall;
    SHFILEINFO shinfo = new SHFILEINFO();

    hImgSmall = SHGetFileInfo(filename, 0, ref
    shinfo,(UInt32)Marshal.SizeOf(shinfo),SHGFI_ICON |icon_size);
    System.Drawing.Icon myIcon =
    System.Drawing.Icon.FromHandle(shinfo.hIcon);

    return myIcon;
    }

    }

    文件列表的获取方法就不说了,其实就是遍历获取需要的文件。

    今天先写这些吧...

  • 相关阅读:
    第02组 Alpha冲刺(2/6)
    第02组 Alpha冲刺(1/6)
    第02组 团队Git现场编程实战
    第02组 团队项目-需求分析报告
    团队项目-选题报告
    第二次结对编程作业
    第一次结对编程作业
    第2组 团队展示(组长)
    Exchange 2013 中的 OAB (脱机通讯簿)以及如何管理
    vmware esxi 查看网卡、Raid卡驱动
  • 原文地址:https://www.cnblogs.com/zhucl1006/p/667078.html
Copyright © 2020-2023  润新知