问题描述
.net 平台中有一个 PerformanceCounter,可以检索每个进程的cpu使用情况.
There is a PerformanceCounter in .net platform, which can retrieve the cpu usage of every single process.
delphi 有没有类似的解决方案?
Is there any similar solution in delphi?
请注意,所有进程的名称都已经可用.
推荐答案
这篇文章 似乎提供了使用原生 Delphi 监控进程的 CPU 使用率所需的代码.以下内容直接引自上述文章.
This article appears to provide the code you need to monitor CPU usage for a process using native Delphi. What follows is a direct quote from the above article.
使用本机
当开始监控一个进程时,调用cnt:=wsCreateUsageCounter(Process_id) 来初始化一个使用计数器.当您需要获取该进程的当前 CPU 使用率时,请使用用法:=wsGetCpuUsage(cnt).当您完成监控进程,调用 wsDestroyUsageCounter(cnt) 来释放被使用使用的内存计数器并关闭打开的手柄.
When starting to monitor a process, call cnt:=wsCreateUsageCounter(Process_id) to initialize a usage counter. When you need to get the current CPU usage of that process, use usage:=wsGetCpuUsage(cnt). When you have finished monitoring the process, call wsDestroyUsageCounter(cnt) to free memory used by usage counter and close open handles.
uCpuUsage 单元
The uCpuUsage unit
unit uCpuUsage;
interface
const
wsMinMeasurementInterval=250; {minimum amount of time that must have elapsed to calculate CPU usage, miliseconds. If time elapsed is less than this, previous result is returned, or zero, if there is no previous result.}
type
TCPUUsageData=record
PID,Handle:cardinal;
oldUser,oldKernel:Int64;
LastUpdateTime:cardinal;
LastUsage:single;
//Last result of wsGetCpuUsage is saved here
Tag:cardinal;
//Use it for anythin you like, not modified by this unit
end;
PCPUUsageData=^TCPUUsageData;
function wsCreateUsageCounter(PID:cardinal):PCPUUsageData;
function wsGetCpuUsage(aCounter:PCPUUsageData):single;
procedure wsDestroyUsageCounter(aCounter:PCPUUsageData);
implementation
uses Windows;
function wsCreateUsageCounter(PID:cardinal):PCPUUsageData;
var
p:PCPUUsageData;
mCreationTime,mExitTime,mKernelTime, mUserTime:_FILETIME;
h:cardinal;
begin
result:=nil;
//We need a handle with PROCESS_QUERY_INFORMATION privileges
h:=OpenProcess(PROCESS_QUERY_INFORMATION,false,PID);
if h=0 then exit;
new(p);
p.PID:=PID;
p.Handle:=h;
p.LastUpdateTime:=GetTickCount;
p.LastUsage:=0;
if GetProcessTimes(p.Handle, mCreationTime, mExitTime, mKernelTime, mUserTime) then begin
//convert _FILETIME to Int64
p.oldKernel:=int64(mKernelTime.dwLowDateTime or (mKernelTime.dwHighDateTime shr 32));
p.oldUser:=int64(mUserTime.dwLowDateTime or (mUserTime.dwHighDateTime shr 32));
Result:=p;
end else begin
dispose(p);
end;
end;
procedure wsDestroyUsageCounter(aCounter:PCPUUsageData);
begin
CloseHandle(aCounter.Handle);
dispose(aCounter);
end;
function wsGetCpuUsage(aCounter:PCPUUsageData):single;
var
mCreationTime,mExitTime,mKernelTime, mUserTime:_FILETIME;
DeltaMs,ThisTime:cardinal;
mKernel,mUser,mDelta:int64;
begin
result:=aCounter.LastUsage;
ThisTime:=GetTickCount; //Get the time elapsed since last query
DeltaMs:=ThisTime-aCounter.LastUpdateTime;
if DeltaMs < wsMinMeasurementInterval then exit;
aCounter.LastUpdateTime:=ThisTime;
GetProcessTimes(aCounter.Handle,mCreationTime, mExitTime, mKernelTime, mUserTime);
//convert _FILETIME to Int64.
mKernel:=int64(mKernelTime.dwLowDateTime or (mKernelTime.dwHighDateTime shr 32));
mUser:=int64(mUserTime.dwLowDateTime or (mUserTime.dwHighDateTime shr 32));
//get the delta
mDelta:=mUser+mKernel-aCounter.oldUser-aCounter.oldKernel;
aCounter.oldUser:=mUser;
aCounter.oldKernel:=mKernel;
Result:=(mDelta/DeltaMs)/100;
//mDelta is in units of 100 nanoseconds, so…
aCounter.LastUsage:=Result;
//just in case you want to use it later, too
end;
end.
这篇关于如何检索每个进程的 CPU 使用率的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!