C# 从特定进程获取CPU和RAM(性能计数器)
我想检索前台进程(或特定进程)此时的 cpu 和 ram 使用情况。 检索窗口的标题不是问题,并且该部分可以工作。但即使活动窗口以 70% 或更高的 cpu 运行,cpu 显示仍保持在 0%。
(int)pCPU.NextValue(); // <<<<<不断返回 0...
注意:我想用性能计数器来做到这一点。我不想使用 Process 变量来执行此操作,因为这可能会引发“权限不足错误”。
[DllImport("user32.dll")]
static extern IntPtr GetForegroundWindow();
[DllImport("user32.dll")]
static extern int GetWindowText(IntPtr hWnd, StringBuilder text, int count);
[DllImport("user32.dll")]
public static extern IntPtr GetWindowThreadProcessId(IntPtr hWnd, out uint ProcessId);
public void GetActiveCPUAndRam(out string windowTitle, out int CPUUsagePerc, out int RAMUsage)
{
IntPtr hwnd = GetForegroundWindow();
uint pid;
GetWindowThreadProcessId(hwnd, out pid);
Process activeProc = Process.GetProcessById((int) pid);
#region Window Title
const int nChars = 256;
StringBuilder Buff = new StringBuilder(nChars);
if (GetWindowText(hwnd, Buff, nChars) > 0)
windowTitle = Buff.ToString();
else
{
windowTitle = "";
CPUUsagePerc = 0;
RAMUsage = 0;
return;
}
#endregion
#region RAM/CPU
PerformanceCounter pCPU = new PerformanceCounter("Process", "% Processor Time", activeProc.ProcessName, true);
pCPU.NextValue();
CPUUsagePerc = (int)pCPU.NextValue(); // <<<<< problem here.
RAMUsage = 0; // TODO:
#endregion
}
EDIT: I tried the new solution: But when I run a cpu stress test program that pushes the cpu usage to 100% (single core) . Then the solution below shows that the cpu usage of that process is like 300-400% of the total cpu... Obviously something is still wrong.
private PerformanceCounter pCPU = null;
private IntPtr PreviousProcHwnd = IntPtr.Zero;
private CounterSample PreviousCPUCounterSample = CounterSample.Empty;
public void GetActiveCPUAndRam(out string windowTitle, out int CPUUsagePerc, out int RAMUsage)
{
...
#region RAM/CPU
if (PreviousProcHwnd != hwnd)
{
PreviousProcHwnd = hwnd;
pCPU = new PerformanceCounter("Process", "% Processor Time", activeProc.ProcessName,
true);
PreviousCPUCounterSample = CounterSample.Empty;
}
CounterSample sample1 = pCPU.NextSample();
CPUUsagePerc = (int)CounterSample.Calculate(PreviousCPUCounterSample, sample1);
PreviousCPUCounterSample = sample1;
RAMUsage = 0; // TODO:
#endregion
}
I would like to retrieve the cpu and ram usage at that point for the foreground process (or a specific one).
Retrieving the window's title is not a problem and that part works. But the cpu display stays at 0% even when the active window is running at 70% cpu or more.
(int)pCPU.NextValue(); // <<<< keeps returning 0...
Note: I want to do it with a performance counter. I don't want to do it using the Process variable because that one might raise 'insufficient privilege errors'.
[DllImport("user32.dll")]
static extern IntPtr GetForegroundWindow();
[DllImport("user32.dll")]
static extern int GetWindowText(IntPtr hWnd, StringBuilder text, int count);
[DllImport("user32.dll")]
public static extern IntPtr GetWindowThreadProcessId(IntPtr hWnd, out uint ProcessId);
public void GetActiveCPUAndRam(out string windowTitle, out int CPUUsagePerc, out int RAMUsage)
{
IntPtr hwnd = GetForegroundWindow();
uint pid;
GetWindowThreadProcessId(hwnd, out pid);
Process activeProc = Process.GetProcessById((int) pid);
#region Window Title
const int nChars = 256;
StringBuilder Buff = new StringBuilder(nChars);
if (GetWindowText(hwnd, Buff, nChars) > 0)
windowTitle = Buff.ToString();
else
{
windowTitle = "";
CPUUsagePerc = 0;
RAMUsage = 0;
return;
}
#endregion
#region RAM/CPU
PerformanceCounter pCPU = new PerformanceCounter("Process", "% Processor Time", activeProc.ProcessName, true);
pCPU.NextValue();
CPUUsagePerc = (int)pCPU.NextValue(); // <<<<< problem here.
RAMUsage = 0; // TODO:
#endregion
}
EDIT:
I tried the new solution:
But when I run a cpu stress test program that pushes the cpu usage to 100% (single core) . Then the solution below shows that the cpu usage of that process is like 300-400% of the total cpu... Obviously something is still wrong.
private PerformanceCounter pCPU = null;
private IntPtr PreviousProcHwnd = IntPtr.Zero;
private CounterSample PreviousCPUCounterSample = CounterSample.Empty;
public void GetActiveCPUAndRam(out string windowTitle, out int CPUUsagePerc, out int RAMUsage)
{
...
#region RAM/CPU
if (PreviousProcHwnd != hwnd)
{
PreviousProcHwnd = hwnd;
pCPU = new PerformanceCounter("Process", "% Processor Time", activeProc.ProcessName,
true);
PreviousCPUCounterSample = CounterSample.Empty;
}
CounterSample sample1 = pCPU.NextSample();
CPUUsagePerc = (int)CounterSample.Calculate(PreviousCPUCounterSample, sample1);
PreviousCPUCounterSample = sample1;
RAMUsage = 0; // TODO:
#endregion
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
不要直接使用该值,使用计算出的样本,
如果您的计数器是“速率”类型样本,那么您将需要获取两个样本,
Do not use the value directly, use the calculated sample,
if your counter is a 'rate' type sample, then you will need to get two samples,