关闭

[愚翁专栏]如何对系统中的某个进程进行监控

标签: stringdatagridquerynullobjectexception
1028人阅读 评论(0) 收藏 举报
分类:

最近看到一篇文章,就是如何对系统某个进程进行监控,并且当这个进程触发某些事件的时候,能进行相应。而且发现有人问这方面的问题,我就大致在其原有的基础进行如下的修改。

 

首先说明的一点,方法是基于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获得,所以不得不放弃。


0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:306452次
    • 积分:4271
    • 等级:
    • 排名:第7062名
    • 原创:79篇
    • 转载:33篇
    • 译文:55篇
    • 评论:103条
    文章分类
    最新评论