使用C#制做进程监视器

王朝学院·作者佚名  2009-02-05  
宽屏版  字体: |||超大  

1)可以查看进程的各项基本信息,如cpu,内存,父进程,执行路径,创建者等

2)可以中止进程,创建新进程

3)可以配置目标进程,配置刷新速度

(以下给出部分代码,其余像进程的创建、中止等,使用process类将很容易实现)

1)使用wmi获取父进程id,进程创建者

(注意,使用wmi获得的内容,不宜循环刷新,这样代价比较大)

添加命名空间:

using System.Management;

/**//// <summary>

/// 使用Wmi获取指定进程的创建者等信息

/// </summary>

/// <param name="pID">进程ID</param>

private void FillDetailUseWmi(int pID)

{

ManagementObjectSearcher searcher = new ManagementObjectSearcher("Select * From Win32_Process Where ProcessID=" + pID);

ManagementObjectCollection moc = searcher.Get();

ManagementOperationObserver observer = new ManagementOperationObserver();

HandleObjectReady hor = new HandleObjectReady();

//监测异步方法是否已成功返回

observer.ObjectReady += new ObjectReadyEventHandler(hor.Done);

foreach (ManagementObject mo in moc)

{

//异步调用该对象的GetOwner方法,获取进程创建者

mo.InvokeMethod(observer, "GetOwner", null);

//等待异步调用返回

while (!hor.Complete)

{

System.Threading.Thread.Sleep(500);

}

string user = "";

//判断获取用户名的操作是否成功

if (hor.Obj["returnValue"].ToString() == "0")

{

user = hor.Obj.Properties["User"].Value.ToString();

}

//判断字典中是否已移除该项

if (!this.mDict.ContainsKey(pID))

{

return;

}

if (mo["ParentProcessID"] != null && this.mDict.ContainsKey(Convert.ToInt32(mo["ParentProcessID"])))

{

//根据父进程ID获取父进程名称

this.mDict[pID].ParentProce = this.mDict[Convert.ToInt32(mo["ParentProcessID"])].ProceName;

}

this.mDict[pID].Creator = user;

//触发刷新进程详细信息事件

if (this.HandleDetailList != null)

{

this.HandleDetailList(this.mDict[pID]);

}

}

//释放资源

searcher.Dispose();

searcher = null;

moc.Dispose();

moc = null;

observer = null;

hor = null;

}

/**//// <summary>

/// 该类用于监测Wmi异步调用方法是否已经返回

/// </summary>

public class HandleObjectReady

{

private bool complete = false;

private ManagementBaseObject obj;

public void Done(object sender, ObjectReadyEventArgs e)

{

complete = true;

obj = e.NewObject;

}

public bool Complete

{

get

{

return complete;

}

}

public ManagementBaseObject Obj

{

get

{

return obj;

}

}

}

2)使用性能计数器计算cpu利用率

2.1)计算过程

//通过计数器获取idle空闲进程cpu占用率r1;

//通过process类的TotalProcessorTime属性获取各进程的cpu时间,求和,得各进程(除空闲进程idle,该进程无法通过process类获得cpu时间)cpu时间和t1;

//通过t1/(100-r1)得到总cpu时间t;

//对各进程,通过TotalProcessorTime获得进程cpu时间tnew,计算:

(Tnew-told)/t,即得该进程的cpu占用率,其中told是程序中记录的该进程上一次的TotalProcessorTime。

2.2)关于性能计数器

系统会为每个进程分配一个计数器,通过

new PerformanceCounter("Process", "% Processor Time", "进程名称")实例化该计数器,使用计数器对象的NextValue方法可以得到进程占用cpu的百分比(第一次调用NextValue获取的值都为0,之后就没问题了,这个要注意)。

2.3)Idle进程的含义

Idle意为懒散的、无所事事。事实上,idle不能算着一个进程,它用于表示cpu空闲资源,它所占的比率越高,表示你的机器越空闲。

2.4)多核CPU或使用超线程技术的CPU

对于多核或使用超线程技术的cpu,根据计数器求得的idle进程cpu占用比率将超过100%,此时应将idle的cpu利用率/总的cpu利用率,所得作为真正的idle的cpu利用率。

添加命名空间:

using System.Diagnostics;

/**//// <summary>

/// 性能计数器,用于获取CPU空闲百分比

/// </summary>

private static PerformanceCounter mIdle = new PerformanceCounter("Process", "% Processor Time", "Idle");

/**//// <summary>

/// 性能计数器,用于获取CPU总利用率

/// </summary>

private static PerformanceCounter mTotal = new PerformanceCounter("Process", "% Processor Time", "_Total");

private void FillNeedRefreshInfo(params Process[] pCurrentAll)

{

…………

//以下计算CPU利用率

this.mCurrentTotalCpuTime = this.CalCurrentTotalCpuTime();

for (int i = 0; i < pCurrentAll.Length; i++)

{

//空闲进程idle

if (pCurrentAll[i].Id == 0)

{

this.mDict[pCurrentAll[i].Id].CpuPercent = this.mIdleCpuPercent;

}

else

{

try

{

//无法保证进程不会中途退出,此时无法获取其Cpu时间

long ms = (long)pCurrentAll[i].TotalProcessorTime.TotalMilliseconds;

double d = (ms - this.mDict[pCurrentAll[i].Id].OldCpuTime) * 1.0 / this.mCurrentTotalCpuTime;

this.mDict[pCurrentAll[i].Id].CpuPercent = d;

this.mDict[pCurrentAll[i].Id].OldCpuTime = ms;

}

catch

{

}

}

//调用刷新事件

if (this.HandleProceRefresh != null)

{

this.HandleProceRefresh(this.mDict[pCurrentAll[i].Id], 100 - this.mIdleCpuPercent);

}

}

}

private double CalCurrentTotalCpuTime()

{

double d = 0;

//获取性能计数器值

double idlePercent = mIdle.NextValue();

double totalPercent = mTotal.NextValue();

//避免除0异常

if (totalPercent == 0)

{

this.mIdleCpuPercent = 0;

}

else

{

//可能遇到多核或超线程CPU,CPU空闲进程比率不能直接使用计数器的值

this.mIdleCpuPercent = idlePercent * 100 / totalPercent;

}

//以下获取上一次计算至当前总的非空闲CPU时间

foreach (Process p in this.mCurrentAll)

{

//对空闲进程及中途退出的进程不做处理

if (p.Id == 0 || p.HasExited)

{

continue;

}

if (this.mDict ==null || !this.mDict.ContainsKey(p.Id))

{

d += p.TotalProcessorTime.TotalMilliseconds;

}

else

{

d += p.TotalProcessorTime.TotalMilliseconds - this.mDict[p.Id].OldCpuTime;

}

}

//当前非空闲CPU时间/当前非空闲时间所占比率=当前总CPU时间

//return d / (totalPercent - idlePercent);

return d / (100 - mIdleCpuPercent);

}

代码下载

转自:http://www.cnblogs.com/kissknife/archive/2007/03/20/681739.html

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
© 2005- 王朝网络 版权所有