111,093
社区成员




using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
namespace ConsoleApplication3
{
class Program
{
static void Main(string[] args)
{
Stopwatch sw = new Stopwatch();
sw.Start();
string categoryName = "Process";
string counterName = "% Processor Time";
List<InstanceInfo> list = GetInstanceList(categoryName);
list.RemoveAll(p => p.InstanceName == "_Total" || p.InstanceName == "Idle" );
float total = GetCounterValue(categoryName, counterName, "_Total");
for(int i=0;i<list.Count;i++)
{
InstanceInfo info = list[i];
info.CounterValue = GetCounterValue(categoryName, counterName, info.InstanceName);
info.Percent = Math.Round(info.CounterValue * 100 / total, 2) ;
}
list.Sort();
if (list.Count > 3)
list.RemoveRange(3, list.Count() - 3);
foreach(InstanceInfo info in list)
Console.WriteLine("{0}\r\n-- {1}, {2}%\r\n", info.InstanceName, info.CounterValue, info.Percent);
sw.Stop();
Console.WriteLine("消耗 ms :{0}",sw.ElapsedMilliseconds);
Console.Read();
}
/// <summary>
/// 获取计数器的当前值
/// </summary>
/// <param name="categoryName"></param>
/// <param name="counterName"></param>
/// <param name="instanceName"></param>
/// <returns></returns>
[Microsoft.SqlServer.Server.SqlProcedure]
public static float GetCounterValue(string categoryName, string counterName, string instanceName)
{
PerformanceCounter pc = new PerformanceCounter(categoryName, counterName, instanceName);
pc.ReadOnly = true;
float[] arr = new float[5];
for(int i=0;i<arr.Length;i++)
{
arr[i] = pc.NextValue();
}
return arr.Max();
}
/// <summary>
/// 获取实例列表
/// </summary>
/// <param name="categoryName"></param>
/// <returns></returns>
[Microsoft.SqlServer.Server.SqlProcedure]
public static List<InstanceInfo> GetInstanceList(string categoryName)
{
List<InstanceInfo> resultList = new List<InstanceInfo>();
PerformanceCounterCategory counterCategory = new PerformanceCounterCategory(categoryName);
List<string> strList = new List<string>();
string[] instanceArr = counterCategory.GetInstanceNames();
if (instanceArr == null || instanceArr.Length == 0)
{
return resultList;
}
strList.AddRange(instanceArr);
strList.Sort();
foreach (string str in strList)
{
resultList.Add(new InstanceInfo() { RowNum = resultList.Count + 1, InstanceName = str });
}
return resultList;
}
}
public class InstanceInfo : IComparable
{
public int RowNum { get; set; }
public string InstanceName { get; set; }
public float CounterValue { get; set; }
public double Percent { get; set; }
#region IComparable 成员
public int CompareTo(object obj)
{
if (obj is InstanceInfo)
{
InstanceInfo temp = obj as InstanceInfo;
return temp.CounterValue.CompareTo(this.CounterValue);
}
throw new NotImplementedException("obj is not a ExportParameter!");
}
#endregion
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Diagnostics;
namespace ConsoleApplication8
{
class Program
{
static void Main(string[] args)
{
var random = new Random();
var sessionId = Process.GetCurrentProcess().SessionId;
var processes = Process.GetProcesses().Where(p => p.SessionId == sessionId).ToList();
var processInfoList = processes.Select(p => new ProcessInfo(p)).ToList();
int i = 0;
while (true)
{
Thread.Sleep(random.Next(500, 2000));
Console.Clear();
foreach (var item in processInfoList)
{
try
{
if (!item.Process.HasExited)
{
Console.WriteLine("{0}->{1:0.##}%", item.Process.ProcessName, item.CpuPencentage);
}
}
catch (Exception)
{
}
}
i++;
if (i >= 3)
break;
}
Console.Read();
}
class ProcessInfo
{
public ProcessInfo(System.Diagnostics.Process process)
{
this.Process = process;
}
/// <summary>
/// CPU使用数据,用于统计使用率
/// </summary>
[NonSerialized]
protected CpuUsage _cpuUsage;
[NonSerialized]
public readonly Process Process;
public float CpuPencentage
{
get
{
if (this._cpuUsage == null)
{
this._cpuUsage = new CpuUsage(this.Process.TotalProcessorTime.TotalMilliseconds);
return 5f;
}
return (float)this._cpuUsage.GetCpuPencentage(this.Process.TotalProcessorTime.TotalMilliseconds, DateTime.Now);
}
}
}
public class CpuUsage
{
public CpuUsage(double totalCpuTime)
{
this.TotalProcessorTime = totalCpuTime;
this.UpdateTime = DateTime.Now;
}
/// <summary>
/// 上次检测到的CPU占用总时间(毫秒)
/// </summary>
public double TotalProcessorTime;
/// <summary>
/// 上次的检测时间
/// </summary>
public DateTime UpdateTime;
/// <summary>
/// 获取CPU使用率的百分比数
/// </summary>
/// <param name="nextTotalMilliseconds">自上一次采样后的CPU占用毫秒数</param>
/// <param name="nextTime">CPU采样的时间</param>
/// <returns></returns>
public double GetCpuPencentage(double nextTotalMilliseconds, DateTime nextTime)
{
lock (this)
{
var cpuPercentage = (nextTotalMilliseconds - this.TotalProcessorTime)
/ nextTime.Subtract(this.UpdateTime).TotalMilliseconds * 100;
this.TotalProcessorTime = nextTotalMilliseconds;
this.UpdateTime = nextTime;
//Console.WriteLine(cpuPercentage);
return cpuPercentage;
}
}
}
}
}
static void Main(string[] args)
{
var random = new Random();
var sessionId = Process.GetCurrentProcess().SessionId;
var processes = Process.GetProcesses().Where(p => p.SessionId == sessionId).ToList();
var processInfoList = processes.Select(p => new ProcessInfo(p)).ToList();
while (true)
{
Thread.Sleep(random.Next(500, 2000));
Console.Clear();
foreach (var item in processInfoList)
{
if (!item.Process.HasExited)
{
Console.WriteLine("{0}->{1:0.##}%", item.Process.ProcessName, item.CpuPencentage);
}
}
}
Console.Read();
}
class ProcessInfo
{
public ProcessInfo(System.Diagnostics.Process process)
{
this.Process = process;
}
/// <summary>
/// CPU使用数据,用于统计使用率
/// </summary>
[NonSerialized]
protected CpuUsage _cpuUsage;
[NonSerialized]
public readonly Process Process;
public float CpuPencentage
{
get
{
if (this._cpuUsage == null)
{
this._cpuUsage = new CpuUsage(this.Process.TotalProcessorTime.TotalMilliseconds);
return 5f;
}
return (float)this._cpuUsage.GetCpuPencentage(this.Process.TotalProcessorTime.TotalMilliseconds, DateTime.Now);
}
}
}
没有考虑新开启的进程。你可以用轮询,然后将采样到的Processes跟processInfoList对比查找
所以之前的代码中没有Process Process属性,只需要记个int PID作查找用
对于新开启的进程,可以用系统钩子监测主窗口开启的通知(不需要轮询了)
但对于没有界面的进程会比较复杂,控制台程序是当前用户的,对于system服务Process.HasExited会报错
主要是OpenProcess没权限取句柄,而且对于 360这样的程序可以在这里挂线程钩子或者驱动层拦截(从任务管理器你干不掉它)
因为我之前写的是window服务,基本没那些问题。刚一到控制台里跑就发现有些报错
所以为测试,我上面只取当前会话的进程 Process.GetProcesses().Where(p => p.SessionId == sessionId)
你可以用(p => p.Id > 4)来取所有的(PID=4的System进程特殊一点,通常可不考虑)using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
namespace ConsoleApplication6
{
class Program
{
static void Main(string[] args)
{
ProcessInfo info = new ProcessInfo();
info.GetResult();
Console.ReadLine();
}
class ProcessInfo
{
public void GetResult()
{
foreach (Process item in Process.GetProcesses())
{
try
{
GetCpuPencentage(item);
}
catch (Exception ex)
{
continue;
}
Console.WriteLine("{0}->{1}", item.ProcessName, GetCpuPencentage(item));
//Console.WriteLine();
}
}
/// <summary>
/// CPU使用数据,用于统计使用率
/// </summary>
[NonSerialized]
protected CpuUsage _cpuUsage;
public float GetCpuPencentage(System.Diagnostics.Process process)
{
if(this._cpuUsage == null)
{
this._cpuUsage = new CpuUsage(process.TotalProcessorTime.TotalMilliseconds);
return 5f; //首次检测的值可忽略,这里随便给个值
}
return (float)this._cpuUsage.GetCpuPencentage(process.TotalProcessorTime.TotalMilliseconds, DateTime.Now);
}
}
public class CpuUsage
{
public CpuUsage(double totalCpuTime)
{
this.TotalProcessorTime = totalCpuTime;
this.UpdateTime = DateTime.Now;
}
/// <summary>
/// 上次检测到的CPU占用总时间(毫秒)
/// </summary>
public double TotalProcessorTime;
/// <summary>
/// 上次的检测时间
/// </summary>
public DateTime UpdateTime;
/// <summary>
/// 获取CPU使用率的百分比数
/// </summary>
/// <param name="nextTotalMilliseconds">自上一次采样后的CPU占用毫秒数</param>
/// <param name="nextTime">CPU采样的时间</param>
/// <returns></returns>
public double GetCpuPencentage(double nextTotalMilliseconds, DateTime nextTime)
{
lock (this)
{
var cpuPercentage = (nextTotalMilliseconds - this.TotalProcessorTime)
/ nextTime.Subtract(this.UpdateTime).TotalMilliseconds * 100;
this.TotalProcessorTime = nextTotalMilliseconds;
this.UpdateTime = nextTime;
//Console.WriteLine(cpuPercentage);
return cpuPercentage;
}
}
}
}
}