如何对系统中的某个进程进行监控
最近看到一篇文章,就是如何对系统某个进程进行监控,并且当这个进程触发某些事件的时候,能进行相应。而且发现有人问这方面的问题,我就大致在其原有的基础进行如下的修改。
首先说明的一点,方法是基于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