السلام عليكم 
* هذا الموضوع للغرض التعليمي لاغير .  بالنسبه للمبرمجين المحترفين يفضل تعدي هذا الموضوع  .
 . 
قبل فتره كنت  قد بدأت في عمل برنامج يقوم باعطاء معلومات عن الــ  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)