السلام عليكم
* هذا الموضوع للغرض التعليمي لاغير . بالنسبه للمبرمجين المحترفين يفضل تعدي هذا الموضوع .
قبل فتره كنت قد بدأت في عمل برنامج يقوم باعطاء معلومات عن الــ Processes الشغاله حاليا في الكمبيوتر . هناك العديد من البرامج التي تقوم بهذا الشئ احدها Task Manager التابع لـ win2k/xp , او برنامج pviewer الذي ياتي مع Support Tools الموجود ضمن win2k/xp CD .
احد البرامج الجيده ايضا والتي افضلها هو PrcView
http://www.prcview.com وغيرها ...
لاحظت ان البرامج الغير تابعه لمايكروسوفت جميعها تستخدم ملف DLL اسمه PSAPI.DLL ياتي مع الـ VC , يمكن تنزيله من صفحه MS ايضا. هذا الملف يقوم باستدعاء عدد من دوال الــ native api التي تساعد في تجميع المعلومات الخاصه بالــ Processes و الــ Threads ...
لاحظت ان TaskManager و Pviewer تستدعي نفس الدوال بصوره مباشره دون اعتماد على الـ DLL المذكور ..
هنا سأضع كود يعطي بعض المعلومات عن الـ Process الحاليه.
بالنسبه للبرنامج الذي اقوم ببرمجته - ان شاء الله - اضع كوده في العطله بعد شهر تقريبا , البرنامج يعتمد تماما على دوال native api ( اي انه لا يعتمد على PSAPI.DLL ) .
Add a button and Memo to a form
// Add this after the declaration of form calss
TPDword=^DWORD;
PProcess_Basic_Information =^TProcess_Basic_Information;
TProcess_Basic_Information = record
ExitStatus : DWORD;
PebBaseAddress : DWORD;
AffinityMask : DWORD;
BasePriority : DWORD;
UniqueProcessId : ULONG;
InheritedFormUniqueProcessId : ULONG;
end;
PProcess_Quata_Limits=^TProcess_Quata_Limits;
TProcess_Quata_Limits=record
PagedPoolLimit : ULONG;
NonPagedPoolLimit : ULONG;
MinimumWorkingSetSize : ULONG;
MaximumWorkingSetSize : ULONG;
PagefileLimit : ULONG;
TimeLimit : LARGE_INTEGER;
end;
PProcess_IO_Counters=^TProcess_IO_Counters;
TProcess_IO_Counters=record
ReadOperationCount : LARGE_INTEGER;
WriteOperationCount : LARGE_INTEGER;
OtherOperatoinCount : LARGE_INTEGER;
ReadTransferCount : LARGE_INTEGER;
WriteTransferCount : LARGE_INTEGER;
OtherTransferCount : LARGE_INTEGER;
end;
function NtQueryInformationProcess
(
ProcessHandle : Thandle;
PrcInfoClass : DWORD ;
PrcInfo : Pointer ;
PrcInfoLength : ULONG;
returnlength : TPDword
):
DWORD; stdcall ;external 'ntdll.dll' name 'NtQueryInformationProcess';
...
// Button Click event
procedure TForm1.Button1Click(Sender: TObject);
var
status : DWORD;
retlen : DWORD;
Prc_Basic_Info : TProcess_Basic_Information;
Prc_Quta_Limits : TProcess_Quata_Limits;
Prc_IO_Counter : TProcess_IO_Counters ;
hProcess : THandle;
begin
hProcess := GetCurrentProcess();
status:=NtQueryInformationProcess
(
hProcess,
0,//ProcessBasicInformatio
@Prc_Basic_Info,
sizeof(TProcess_Basic_Information),
@retlen
);
if(status<>0) then
exit;
status:=NtQueryInformationProcess
(
hProcess,
1,//ProcessQuataLimits
@Prc_Quta_Limits,
sizeof(TProcess_Quata_Limits),
@retlen
);
if(status<>0) then
exit;
status:=NtQueryInformationProcess
(
hProcess,
2,//ProcessIOCounters
@Prc_IO_Counter,
sizeof(TProcess_IO_Counters),
@retlen
);
if(status<>0) then
exit;
Memo1.Clear;
Memo1.Lines.Add('ExitStatus : '+IntToStr(Prc_Basic_Info.ExitStatus));
Memo1.Lines.Add('PebBaseAddress : '+IntToStr(Prc_Basic_Info.PebBaseAddress));
Memo1.Lines.Add('AffinityMask : '+IntToStr(Prc_Basic_Info.AffinityMask));
Memo1.Lines.Add('BasePriority : '+IntToStr(Prc_Basic_Info.BasePriority));
Memo1.Lines.Add('UniqueProcessId : '+IntToStr(Prc_Basic_Info.UniqueProcessId));
Memo1.Lines.Add('Parent ProcessId : '+IntToStr(Prc_Basic_Info.InheritedFormUniqueProcessId));
Memo1.Lines.Add('PagedPool : '+IntToStr(Prc_Quta_Limits.PagedPoolLimit));
Memo1.Lines.Add('NonPagedPool : '+IntToStr(Prc_Quta_Limits.NonPagedPoolLimit));
Memo1.Lines.Add('MinWorkingSet : '+IntToStr(Prc_Quta_Limits.MinimumWorkingSetSize));
Memo1.Lines.Add('MaxWorkingSet : '+IntToStr(Prc_Quta_Limits.MaximumWorkingSetSize));
Memo1.Lines.Add('Pagefile : '+IntToStr(Prc_Quta_Limits.PagefileLimit));
Memo1.Lines.Add('TimeLimit : '+IntToStr(Prc_Quta_Limits.TimeLimit.QuadPart));
Memo1.Lines.Add('I/O Read : '+IntToStr(Prc_IO_Counter.ReadOperationCount.QuadPart));
Memo1.Lines.Add('I/O Write : '+IntToStr(Prc_IO_Counter.WriteOperationCount.QuadPart));
Memo1.Lines.Add('I/O Other : '+IntToStr(Prc_IO_Counter.OtherOperatoinCount.QuadPart));
Memo1.Lines.Add('I/O Read Byte : '+IntToStr(Prc_IO_Counter.ReadTransferCount.QuadPart));
Memo1.Lines.Add('I/O Write Byte : '+IntToStr(Prc_IO_Counter.WriteTransferCount.QuadPart));
Memo1.Lines.Add('I/O Other Byte : '+IntToStr(Prc_IO_Counter.OtherTransferCount.QuadPart));
end;
بالنسبه للدوال والانواع المعرفه في الكود يمكن مراجعه كتاب Window NT/2000 Native API , رابط تنزيل الكتاب موجود في موضوع Delphi&Native API و في موضوع لي في قسم الفيجوال سي .
يمكن مقارنه النتائج مع القيم في TaskManager . طبعا هناك العديد من المعلومات التي يمكن الحصول عليها .
----------
By kcahcn , Computer Idiot Organization
(f)