如何对系统中的某个进程进行监控

来源:互联网 发布:unity3d学院 编辑:程序博客网 时间:2024/04/28 12:47
如何对系统中的某个进程进行监控
最近看到一篇文章,就是如何对系统某个进程进行监控,并且当这个进程触发某些事件的时候,能进行相应。而且发现有人问这方面的问题,我就大致在其原有的基础进行如下的修改。
 
首先说明的一点,方法是基于WMI的。以下是我扩展类的代码说明:
//------------------------ProcessInfo Class------------------------------------
//-----------------------------------------------------------------------------
//---File:clsProcessInfo.cs
//---Description:This class demonstrates the use of WMI.
//               It provides a static method to query the list of running processes.
//               And it provides two delegated events binding specific application.
//---Author:Knight
//---Date:Mar.21, 2006
//-----------------------------------------------------------------------------
//----------------------{ ProcessInfo Class }----------------------------------
using System;
using System.Data;
using System.Management;       
using System.Diagnostics;
 
namespace WinProcess
{
    ///<summary>
    /// ProcessInfo class.
    ///</summary>
    public class ProcessInfo
    {
        // defenition of the delegates
        public delegate void StartedEventHandler(object sender, EventArgs e);
        public delegate void TerminatedEventHandler(object sender, EventArgs e);
       
        // events to subscribe
        public StartedEventHandler Started = null;
        public TerminatedEventHandler Terminated = null;
 
        // WMI event watcher
        private ManagementEventWatcher watcher;
 
        ///<summary>
        /// Construction that binds specific application with event declared
        ///</summary>
        ///<param name="LocalServerName"></param>
        ///<param name="appName"></param>
        public ProcessInfo( string appName)
        {
            // querry every 2 seconds
            string pol = "2";
 
            string queryString =
                "SELECT *" +
                " FROM __InstanceOperationEvent " +
                "WITHIN " + pol +
                " WHERE TargetInstance ISA 'Win32_Process' " +                
                "   AND TargetInstance.Name = '" + appName + "'";
                               
            string scope = @"//127.0.0.1/root/CIMV2";
           
            // create the watcher and start to listen
            watcher = new ManagementEventWatcher(scope, queryString);
            watcher.EventArrived += new EventArrivedEventHandler(this.OnEventArrived);         
            watcher.Start();
        }
 
        ///<summary>
        /// Destruction function
        ///</summary>
        public void Dispose()
        {
            watcher.Stop();
            watcher.Dispose();
        }
 
        ///<summary>
        /// Get all processes that running in local machine
        ///</summary>
        ///<returns></returns>
        public static DataTable RunningProcesses( )
        {
            // The second way of constructing a query
            string queryString =
                "SELECT Name, ProcessId, Caption, ExecutablePath" +
                " FROM Win32_Process";
                               
            SelectQuery query = new SelectQuery(queryString);
            ManagementScope scope = new ManagementScope( @"//127.0.0.1/root/CIMV2" );
           
            ManagementObjectSearcher searcher = new ManagementObjectSearcher(scope, query);
            ManagementObjectCollection processes = searcher.Get();
           
            DataTable result = new DataTable();
            result.Columns.Add("Name", Type.GetType("System.String"));
            result.Columns.Add("ProcessId", Type.GetType("System.Int32"));
            result.Columns.Add("Caption", Type.GetType("System.String"));
            result.Columns.Add("Path", Type.GetType("System.String"));
           
            foreach(ManagementObject mo in processes)
            {
                DataRow row = result.NewRow();
                row["Name"] = mo["Name"].ToString();
                row["ProcessId"] = Convert.ToInt32(mo["ProcessId"]);
                if (mo["Caption"]!= null)
                    row["Caption"] = mo["Caption"].ToString();
                if (mo["ExecutablePath"]!= null)
                    row["Path"] = mo["ExecutablePath"].ToString();
                result.Rows.Add( row );
            }
            return result;
        }
 
        ///<summary>
        /// Get all processes that running in specific server
        ///</summary>
        ///<param name="sServerName"></param>
        ///<param name="sUserName"></param>
        ///<param name="sPassword"></param>
        ///<returns></returns>
        public static DataTable RunningProcesses(
            string sServerName,
            string sUserName,
            string sPassword )
        {
            // The second way of constructing a query
            string queryString =
                "SELECT Name, ProcessId, Caption, ExecutablePath" +
                " FROM Win32_Process";
                               
            SelectQuery query = new SelectQuery(queryString);
 
            //Set connection parameters
            ConnectionOptions options = new ConnectionOptions();
            options.Username = sUserName;
            options.Password = sPassword;
           
            //Create management scope
            ManagementScope scope = new ManagementScope(
                string.Format( @"//{0}/root/CIMV2", sServerName ),
                options );
 
            //To connect
            try
            {
                scope.Connect();
            }
            catch( Exception err )
            {
                Debug.WriteLine( err.Message );
                return null;
            }
            catch
            {
                return null;
            }
 
            ManagementObjectSearcher searcher = new ManagementObjectSearcher(scope, query);
            ManagementObjectCollection processes = searcher.Get();
           
            DataTable result = new DataTable();
            result.Columns.Add("Name", Type.GetType("System.String"));
            result.Columns.Add("ProcessId", Type.GetType("System.Int32"));
            result.Columns.Add("Caption", Type.GetType("System.String"));
            result.Columns.Add("Path", Type.GetType("System.String"));
           
            foreach(ManagementObject mo in processes)
            {
                DataRow row = result.NewRow();
                row["Name"] = mo["Name"].ToString();
                row["ProcessId"] = Convert.ToInt32(mo["ProcessId"]);
                if (mo["Caption"]!= null)
                    row["Caption"] = mo["Caption"].ToString();
                if (mo["ExecutablePath"]!= null)
                    row["Path"] = mo["ExecutablePath"].ToString();
                result.Rows.Add( row );
            }
            return result;
        }
 
        ///<summary>
        /// Event handle function
        ///</summary>
        ///<param name="sender"></param>
        ///<param name="e"></param>
        private void OnEventArrived(object sender, System.Management.EventArrivedEventArgs e)
        {
            try
            {
                string eventName = e.NewEvent.ClassPath.ClassName;
                Debug.WriteLine( eventName );
 
                if (eventName.CompareTo("__InstanceCreationEvent")==0)
                {
                    // Started
                    if (Started!=null)
                        Started(this, e);
                }
                else if (eventName.CompareTo("__InstanceDeletionEvent")==0)
                {
                    // Terminated
                    if (Terminated!=null)
                        Terminated(this, e);
 
                }              
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex.Message);
            }
        }
       
    }
}
 
       大致类的说明如下:
1. 两个静态方法,是获得系统中所有进程(一个是获得本地;另一个是获得某个指定的服务器);
2. OnEventArrived,事件响应函数,当根据事件类型来进行传递;
类的使用大致如下:
1. 获得本地系统中所有进程:
using WinProcess;
        DataTable dt = ProcessInfo.RunningProcesses( );
        dataGrid1.DataSource = dt;
 
2. 获得某个指定系统中所有进程:
using WinProcess;
        DataTable dt = ProcessInfo.RunningProcesses( Server, UserName, Psw );
        dataGrid1.DataSource = dt;
 
3. 监控某个程序并(以下是监控NotePad程序):
using WinProcess;
        private ProcessInfo notePad;
             
              //In your form load event
        notePad = new ProcessInfo("notepad.exe" );
        notePad.Started += new ProcessInfo.StartedEventHandler(this.NotepadStarted);
        notePad.Terminated += new ProcessInfo.TerminatedEventHandler (this.NotepadTerminated);
      
              //Define your event handle
        private void NotepadStarted(object sender, EventArgs e)
        {
            //Process start event
        }
        private void NotepadTerminated(object sender, EventArgs e)
        {
            //Process terminate event
        }
 
 
本来,想修改构造函数,使之能适应捕获到远程系统某个程序的事件,但是很不幸的是,捕获到的信息只是错误信息,其原因就是事件无法通过RPC获得,所以不得不放弃。


Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=631196