ورود

View Full Version : CPU Usage در ویندوز 11



seyed_farid
دوشنبه 19 آذر 1403, 15:34 عصر
با سلام
برای دریافت CPU Usage برنامه ها در ویندوز 11 64 بیت دستور چیه؟
من با دستورات زیر در ویندوز 10 جواب گرفتم ولی الان برنامه رو رو ویندوز 11 اجرا که میکنم، مقدار درست را نمیدهد و با تسک منیجر ویندوز خیلی فرق میکنه.


function FindProcessByModuleNameNT(Name: string): THandle;
var
PIDList: array[0..1023] of THandle;
i: integer;
ListCount, size: cardinal;
hProcess, hModule: THandle;
ModuleName: array[0..MAX_PATH] of char;
begin
result:= 0;
EnumProcesses(@PIDList, sizeof(PIDList), ListCount);
ListCount:= ListCount div sizeof(THandle);
for i:= 0 to ListCount-1 do
begin
// get process handle for each process id we got
hProcess:= OpenProcess(PROCESS_QUERY_INFORMATION +
PROCESS_VM_READ, false, PIDList[i]);
try
if hProcess <> 0 then
begin
// get handle to first module, which is the exe
if EnumProcessModules(hProcess, @hModule,
sizeof(hModule), size) then
begin
// extract the filename
GetModuleFileNameEx(hProcess, hModule,
ModuleName, sizeof(ModuleName));
if AnsiCompareText(ExtractFileName(StrPas(@ModuleName )),Name) = 0 then
begin
result:= PIDList[i];
exit;
end;
end;
end;
finally
CloseHandle(hProcess);
end;
end;
end;

//
A function that returns CPU usage (in percent) for a given process id
function GetCpuUsage(PID:cardinal):single;
const
cWaitTime = 1000;// 750;
var
h: Cardinal;
mCreationTime,mExitTime,mKernelTime, mUserTime: _FILETIME;
TotalTime1,TotalTime2: Int64;
SysInfo : _SYSTEM_INFO;
CpuCount: Word;
begin
//We need to know the number of CPUs and divide the result by that, otherwise we will get wrong percentage on multi-core systems
GetSystemInfo(SysInfo);
CpuCount := SysInfo.dwNumberOfProcessors;

//f add............................................... .......
form1.Label12.Caption := 'CPU Count: '+ IntToStr(CpuCount);
//f add............................................... .......

//We need to get a handle of the process with PROCESS_QUERY_INFORMATION privileges.
h := OpenProcess(PROCESS_QUERY_INFORMATION,false,PID);
//We can use the GetProcessTimes() function to get the amount of time the process has spent in kernel mode and user mode.
GetProcessTimes(h,mCreationTime,mExitTime,mKernelT ime,mUserTime);
TotalTime1:=int64(mKernelTime.dwLowDateTime or (mKernelTime.dwHighDateTime shr 32))
+ int64(mUserTime.dwLowDateTime or (mUserTime.dwHighDateTime shr 32));

//Wait a little
Sleep(cWaitTime);

GetProcessTimes(h,mCreationTime,mExitTime,mKernelT ime,mUserTime);
TotalTime2 := int64(mKernelTime.dwLowDateTime or (mKernelTime.dwHighDateTime shr 32))+
int64(mUserTime.dwLowDateTime or (mUserTime.dwHighDateTime shr 32));

//This should work out nicely, as there were approx. 250 ms between the calls
//and the result will be a percentage between 0 and 100


Result:=((TotalTime2-TotalTime1)/cWaitTime)/100 /CpuCount;

Result := Round(10* Result) / 10;


// result := StrToFloat(FormatFloat('0.0' , Result));
CloseHandle(h);
end;


...................... دستور استفاده .................................................

CPU := GetCpuUsage(FindProcessByModuleNameNT(ss));

.................................................. .................................................. .................



دوستان میدونید مشکل چی هست ؟
ممنون

khoshblagh
چهارشنبه 21 آذر 1403, 10:20 صبح
با سلام
من در ویندوز 10 نتونستم از این کد استفاده نمایم. برای مثال
"numProcesses" شناسایی نمیشه. شاید متغیرهایی باید به کد اضافه شود.متشکرم

seyed_farid
پنج شنبه 22 آذر 1403, 16:09 عصر
این سورس برنامه هست.
دوستان ببینید و راهنمایی بفرمایید لطفا

دلفــي
شنبه 24 آذر 1403, 12:30 عصر
uses PsAPI;


function GetProcessCpuUsage(ProcessID: DWORD): Double;
var
hProcess: THandle;
ProcessMemoryCounters: TProcessMemoryCounters;
CreationTime, ExitTime, KernelTime, UserTime: TFileTime;
TotalTime: Int64;
SystemTime: TSystemTime;
begin
Result := 0.0;
hProcess := OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_READ, False, ProcessID);
if hProcess <> 0 then
begin
try
GetProcessTimes(hProcess, CreationTime, ExitTime, KernelTime, UserTime);
TotalTime := (Int64(UserTime.dwHighDateTime) shl 32 + UserTime.dwLowDateTime) +
(Int64(KernelTime.dwHighDateTime) shl 32 + KernelTime.dwLowDateTime);
GetSystemTime(SystemTime);
Result := TotalTime / (SystemTime.wHour * 3600 + SystemTime.wMinute * 60 + SystemTime.wSecond);
finally
CloseHandle(hProcess);
end;
end
else
raise Exception.Create('Could not open process.');
end;


procedure TForm1.Button1Click(Sender: TObject);
var PUsage: Double;
ProcessID: DWORD;
begin
PUsage := GetProcessCpuUsage(ProcessID);
end;

seyed_farid
سه شنبه 27 آذر 1403, 22:03 عصر
سلام و تشکر از ارسال پاسختون:تشویق:

با استفاده از دستورات شما ، خروجی عددیست که با هر بار مقدارش اضاف میشه و CPU Usage رو نشون نمیده.
فک کنم خروجی دستورات شما پروسس تایم را میدهد نه پروسس یوزیج.:متفکر:

دلفــي
شنبه 01 دی 1403, 09:22 صبح
سلام و تشکر از ارسال پاسختون:تشویق:

با استفاده از دستورات شما ، خروجی عددیست که با هر بار مقدارش اضاف میشه و CPU Usage رو نشون نمیده.
فک کنم خروجی دستورات شما پروسس تایم را میدهد نه پروسس یوزیج.:متفکر:

اینم یه تست بزن:

uses
PSAPI, TlHelp32;


Function EnumThreadProc( wnd: HWND; Var appHwnd: HWND ): LongBool;
stdcall;
Var
buf: array [0..128] of Char;
Begin
Result := LongBool(1);
if GetClassname( wnd, buf, sizeof(buf)) > 0 then
If StrComp( buf, 'TApplication' ) = 0 Then Begin
appHwnd := Wnd;
Result := False;
End;
End;


Function FindApplicationWindow( forThreadID: DWORD ): HWND;
Begin
Result := 0;
EnumThreadWindows( forThreadID, @EnumThreadProc, lparam(@result));
End;


Function ProcessIDFromAppName( appname: String ): DWORD;
{ Take only the application filename, not full path! }
Var
snapshot: THandle;
processEntry : TProcessEntry32;
Begin
Result := 0;
appName := UpperCase( appname );
snapshot := CreateToolhelp32Snapshot(
TH32CS_SNAPPROCESS,
0 );
If snapshot <> 0 Then
try
processEntry.dwSize := Sizeof( processEntry );
If Process32First( snapshot, processEntry ) Then
Repeat
If Pos(appname,
UpperCase(ExtractFilename(
StrPas(processEntry.szExeFile)))) > 0
Then Begin
Result:= processEntry.th32ProcessID;
Break;
End; { If }
Until not Process32Next( snapshot, processEntry );
finally
CloseHandle( snapshot );
End; { try }
End;


function GetCpuUsage(PID:cardinal):single;
var
hProcess: Cardinal;
mCreationTime,mExitTime,mKernelTime, mUserTime: _FILETIME;
TotalTime1,TotalTime2: Int64;
SysInfo : _SYSTEM_INFO;
CpuCount: Word;
begin
GetSystemInfo(SysInfo);
CpuCount := SysInfo.dwNumberOfProcessors;
hProcess:=OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_READ,False,PID);
if hProcess <> 0 then
begin
try
GetProcessTimes(hProcess,mCreationTime,mExitTime,m KernelTime,mUserTime);
TotalTime1:=(Int64(mUserTime.dwHighDateTime) shl 32 + mUserTime.dwLowDateTime) +
(Int64(mKernelTime.dwHighDateTime) shl 32 + mKernelTime.dwLowDateTime);


Sleep(750);


GetProcessTimes(hProcess,mCreationTime,mExitTime,m KernelTime,mUserTime);
TotalTime2:=(Int64(mUserTime.dwHighDateTime) shl 32 + mUserTime.dwLowDateTime) +
(Int64(mKernelTime.dwHighDateTime) shl 32 + mKernelTime.dwLowDateTime);


Result:=((TotalTime2-TotalTime1)/750)/100/CpuCount;
finally
CloseHandle(hProcess);
end;
end;
end;


procedure TForm1.Timer1Timer(Sender: TObject);
var
CPU: Single;
PName: string;
begin
PName:= 'bds';
CPU := GetCpuUsage(ProcessIDFromAppName(PName));
Label1.Caption := FormatFloat('0%', CPU);
end;

seyed_farid
سه شنبه 04 دی 1403, 15:48 عصر
اینم یه تست بزن:

uses
PSAPI, TlHelp32;


Function EnumThreadProc( wnd: HWND; Var appHwnd: HWND ): LongBool;
stdcall;
Var
buf: array [0..128] of Char;
Begin
Result := LongBool(1);
if GetClassname( wnd, buf, sizeof(buf)) > 0 then
If StrComp( buf, 'TApplication' ) = 0 Then Begin
appHwnd := Wnd;
Result := False;
End;
End;


Function FindApplicationWindow( forThreadID: DWORD ): HWND;
Begin
Result := 0;
EnumThreadWindows( forThreadID, @EnumThreadProc, lparam(@result));
End;


Function ProcessIDFromAppName( appname: String ): DWORD;
{ Take only the application filename, not full path! }
Var
snapshot: THandle;
processEntry : TProcessEntry32;
Begin
Result := 0;
appName := UpperCase( appname );
snapshot := CreateToolhelp32Snapshot(
TH32CS_SNAPPROCESS,
0 );
If snapshot <> 0 Then
try
processEntry.dwSize := Sizeof( processEntry );
If Process32First( snapshot, processEntry ) Then
Repeat
If Pos(appname,
UpperCase(ExtractFilename(
StrPas(processEntry.szExeFile)))) > 0
Then Begin
Result:= processEntry.th32ProcessID;
Break;
End; { If }
Until not Process32Next( snapshot, processEntry );
finally
CloseHandle( snapshot );
End; { try }
End;


function GetCpuUsage(PID:cardinal):single;
var
hProcess: Cardinal;
mCreationTime,mExitTime,mKernelTime, mUserTime: _FILETIME;
TotalTime1,TotalTime2: Int64;
SysInfo : _SYSTEM_INFO;
CpuCount: Word;
begin
GetSystemInfo(SysInfo);
CpuCount := SysInfo.dwNumberOfProcessors;
hProcess:=OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_READ,False,PID);
if hProcess <> 0 then
begin
try
GetProcessTimes(hProcess,mCreationTime,mExitTime,m KernelTime,mUserTime);
TotalTime1:=(Int64(mUserTime.dwHighDateTime) shl 32 + mUserTime.dwLowDateTime) +
(Int64(mKernelTime.dwHighDateTime) shl 32 + mKernelTime.dwLowDateTime);


Sleep(750);


GetProcessTimes(hProcess,mCreationTime,mExitTime,m KernelTime,mUserTime);
TotalTime2:=(Int64(mUserTime.dwHighDateTime) shl 32 + mUserTime.dwLowDateTime) +
(Int64(mKernelTime.dwHighDateTime) shl 32 + mKernelTime.dwLowDateTime);


Result:=((TotalTime2-TotalTime1)/750)/100/CpuCount;
finally
CloseHandle(hProcess);
end;
end;
end;


procedure TForm1.Timer1Timer(Sender: TObject);
var
CPU: Single;
PName: string;
begin
PName:= 'bds';
CPU := GetCpuUsage(ProcessIDFromAppName(PName));
Label1.Caption := FormatFloat('0%', CPU);
end;


ممنونم مهندس جان:قلب:

ولی
این همون دستورات ارسال اول هست که خودم ارسال کردم دیگه.
مشکل اینه که مقادیر حاصله با مقادیر نمایش داده شده در تسک منیجر ویندوز فرق داره.
در ویندوز 10 فرقش خیلی نیست ولی در 11 خیلی متفاوت هست.

اساتید محترم هم یه مشارکت بفرمائید تا به کدهای صحیح برسیم. :تشویق::تشویق::تشویق:

seyed_farid
سه شنبه 04 دی 1403, 15:52 عصر
این سورس برنامه هست.
دوستان ببینید و راهنمایی بفرمایید لطفا

این کدها باز شدند براتون؟

دلفــي
شنبه 08 دی 1403, 09:42 صبح
از کامپوننت Mitec استفاده کن
اینجا هم دمو رو میتونی ببینی: https://www.mitec.cz/tmx.html

seyed_farid
سه شنبه 11 دی 1403, 23:58 عصر
از کامپوننت Mitec استفاده کن
اینجا هم دمو رو میتونی ببینی: https://www.mitec.cz/tmx.html

این کامپوننت دلفی 7 رو ساپورت نمیکه ظاهرا.
راه دیگه ای نیست برای بدست آوردن مقدار CPU در ویندوز 11 ؟؟؟

seyed_farid
جمعه 14 دی 1403, 16:58 عصر
مشکل موقعی پیش میاد که برنامه ما As Admin نباشه و بخواهیم پروسس یک برنامه که As Admin اجرا شده رو بدست بیاریم.
در حالت عادی مشکلی نداره.
دوستان برخورد نکردید با این مورد؟

سورس جدید رو ببینید.

Mask
چهارشنبه 19 دی 1403, 12:29 عصر
وقتی سطح دسترسی واکشی اطلاعات در سطح ادمین رو ندارید که نمیشه معجزه کرد.خب سطح دسترسی بدید به برنامتون.

seyed_farid
چهارشنبه 19 دی 1403, 17:03 عصر
با سلام و تشکر از پاسختون:قلب:

خوب مشکل با ویندوزهای جدید هست دیگه
که اجازه نمیدند برنامه رو با دسترسی ادمین تو استارت آپ ویندوز قرار بدی.:افسرده:

راه کار حل این مشکل چیه؟

من خیلی تو سایتهای مختلف جستجو کردم، هر کسی یه راهکاری داده ولی تو آپدیدتهای جدید ویندوز جواب نمیدند.:گریه:

اساتید سایت لطفا راهنمایی بفرمائید.:تشویق::تشویق::تشوی ق:

دلفــي
پنج شنبه 20 دی 1403, 10:58 صبح
این کامپوننت دلفی 7 رو ساپورت نمیکه ظاهرا.
راه دیگه ای نیست برای بدست آوردن مقدار CPU در ویندوز 11 ؟؟؟

این نسخه از دلفی 7 هم پشتیبانی میکنه:
MiTeC System Information Component Suite 12.4.0 for D7-D10.2 (https://dl.downloadly.ir/Files/Software/MiTeC_System_Information_Component_Suite_12.4.0_Do wnloadly.ir.rar?nocache=1736450089236)