分享

Delphi 获取内存及CPU信息的函数

 Gavin-book 2014-09-06
  1. Uses MemoryCpuUtils;//首先引用该单元  
  2.   
  3. //声明下列变量用来存储读取的数值  
  4. Var  
  5.      iTotalPhysics, iTotalVirtual, iTotalPageFile,   
  6.      iCurPhysics, iCurVirtual, iCurPageFile : DWord;  
  7.   
  8. //CPU数量  
  9. Format('系统中共有 %d 个CPU中央存储器',[GetCPUCount]);  
  10. //其中i表示获取第几个CPU的使用率  
  11. Format('CPU使用率为 #%d - %5.2f%%',[i,GetCPUUsage(i)*100]);  
  12. //初始化OR读取各内存总量  
  13. GetMemoryTotalSize(iTotalPhysics ,iTotalVirtual ,iTotalPageFile);  
  14. //物理内存总量  
  15. InttoStr(Round(iTotalPhysics/1024/1024)) + ' MB';  
  16. //虚拟内存总量  
  17. InttoStr(Round(iTotalVirtual/1024/1024)) + ' MB';  
  18. //页面内存(交换内存)总量  
  19. InttoStr(Round(iTotalPageFile/1024/1024)) + ' MB';  
  20. //读取各内存当前可用容量  
  21. GetMemoryTotalSize(iCurPhysics,iCurVirtual,iCurPageFile);  
  22. //物理内存可用容量  
  23. InttoStr(Round(iCurPhysics/1024/1024)) + ' MB';  
  24. //虚拟内存可用容量  
  25. InttoStr(Round(iCurVirtual/1024/1024)) + ' MB';  
  26. //页面内存(交换内存)可用容量  
  27. InttoStr(Round(iCurPageFile/1024/1024)) + ' MB';  
  28. //获取内存使用率  
  29. Format('当前内存使用率为 %5.2f%%',[GetMemoryUsage]);  
  30. //直接获取CPU厂商  
  31. GetCPUVendor  
  32.   
  33. 那么如何计算当前各内存使用比例呢?  
  34. //物理内存使用比  
  35. Format('物理内存使用比为 %5.2f%%',[iCurPhysics/iTotalPhysics*100]);  
  36. //虚拟内存使用比  
  37. Format('虚拟内存使用比为 %5.2f%%',[iCurVirtual/iTotalVirtual*100]);  
  38. //页面内存使用比  
  39. Format('页面内存使用比为 %5.2f%%',[iCurPageFile/iTotalPageFile*100]);  
  40.   
  41.    
  42.   
  43. 下载后直接引用即可,如果您还不是会员,可以直接COPY下面的代码。  
  44.   
  45.   
  46. {==================================================================}  
  47. { Get Memory And Cpu Informations Utils         }  
  48. {==================================================================}  
  49.   
  50. Unit MemoryCpuUtils;  
  51.   
  52. interface  
  53.   
  54. Uses  
  55.      Windows, SysUtils;  
  56.   
  57. type  
  58.      TVendor = array[0..11] of Char;  
  59.   
  60. {内存区}  
  61. //获取物理内存、虚拟内存、交换区(页面)内存的总容量,做初始化动作。  
  62. procedure GetMemoryTotalSize(Var iPhysicsMemoryTotalSize,  
  63.          iVirtualMemoryTotalSize,  
  64.          iPageFileMemoryTotalSize : DWORD);  
  65.   
  66. //获取当前物理内存、虚拟内存、交换区(页面)内存的实时可用容量,做监控显示动作。  
  67. procedure GetMemoryCurrentSize(Var iPhysicsMemoryCurrentSize,  
  68.          iVirtualMemoryCurrentSize,  
  69.          iPageFileMemoryCurrentSize : DWORD);  
  70.   
  71. //返回内存当前使用率 总的是100%,传回的是0-100%间的使用率,可以自己做转换。          
  72. function GetMemoryUsage : Double;  
  73.   
  74. {CPU区}  
  75. //刷新CPU数据  
  76. procedure CollectCPUData;  
  77.   
  78. //获取CPU在系统中的总数  
  79. function GetCPUCount: Integer;  
  80.   
  81. //获取CPU使用率  
  82. function GetCPUUsage(Index: Integer): Double;  
  83.   
  84. procedure ReleaseCPUData;  
  85.   
  86. //获取CPU制造厂商  
  87. function GetCPUVendor : TVendor; assembler; register;  
  88.   
  89. implementation  
  90.   
  91. {$ifndef ver110}  
  92.   
  93.      {$ifndef ver90}  
  94.      {$ifndef ver100}  
  95.      {$define UseInt64}  
  96.      {$endif}  
  97.      {$endif}  
  98.   
  99.   
  100.      {$ifdef UseInt64}  
  101.      type TInt64 = Int64;  
  102.      {$else}  
  103.      type TInt64 = Comp;  
  104.      {$endif}  
  105.   
  106. {$else}  
  107.   
  108.      type TInt64 = TLargeInteger;  
  109.   
  110. {$endif}  
  111.   
  112. type  
  113.      PInt64 = ^TInt64;  
  114.   
  115. type  
  116.      TPERF_DATA_BLOCK = record  
  117.      Signature : array[0..4 - 1] of WCHAR;  
  118.      LittleEndian : DWORD;  
  119.      Version : DWORD;  
  120.      Revision : DWORD;  
  121.      TotalByteLength : DWORD;  
  122.      HeaderLength : DWORD;  
  123.      NumObjectTypes : DWORD;  
  124.      DefaultObject : Longint;  
  125.      SystemTime : TSystemTime;  
  126.      Reserved: DWORD;  
  127.      PerfTime : TInt64;  
  128.      PerfFreq : TInt64;  
  129.      PerfTime100nSec : TInt64;  
  130.      SystemNameLength : DWORD;  
  131.      SystemNameOffset : DWORD;  
  132.      end;  
  133.   
  134.      PPERF_DATA_BLOCK = ^TPERF_DATA_BLOCK;  
  135.   
  136.      TPERF_OBJECT_TYPE = record  
  137.      TotalByteLength : DWORD;  
  138.      DefinitionLength : DWORD;  
  139.      HeaderLength : DWORD;  
  140.      ObjectNameTitleIndex : DWORD;  
  141.      ObjectNameTitle : LPWSTR;  
  142.      ObjectHelpTitleIndex : DWORD;  
  143.      ObjectHelpTitle : LPWSTR;  
  144.      DetailLevel : DWORD;  
  145.      NumCounters : DWORD;  
  146.      DefaultCounter : Longint;  
  147.      NumInstances : Longint;  
  148.      CodePage : DWORD;  
  149.      PerfTime : TInt64;  
  150.      PerfFreq : TInt64;  
  151.      end;  
  152.   
  153.      PPERF_OBJECT_TYPE = ^TPERF_OBJECT_TYPE;  
  154.   
  155.      type  
  156.      TPERF_COUNTER_DEFINITION = record  
  157.          ByteLength : DWORD;  
  158.          CounterNameTitleIndex : DWORD;  
  159.          CounterNameTitle : LPWSTR;  
  160.          CounterHelpTitleIndex : DWORD;  
  161.          CounterHelpTitle : LPWSTR;  
  162.          DefaultScale : Longint;  
  163.          DetailLevel : DWORD;  
  164.          CounterType : DWORD;  
  165.          CounterSize : DWORD;  
  166.          CounterOffset : DWORD;  
  167.      end;  
  168.   
  169.      PPERF_COUNTER_DEFINITION = ^TPERF_COUNTER_DEFINITION;  
  170.   
  171.      TPERF_COUNTER_BLOCK = record  
  172.          ByteLength : DWORD;  
  173.      end;  
  174.   
  175.      PPERF_COUNTER_BLOCK = ^TPERF_COUNTER_BLOCK;  
  176.   
  177.      TPERF_INSTANCE_DEFINITION = record  
  178.          ByteLength : DWORD;  
  179.          ParentObjectTitleIndex : DWORD;  
  180.          ParentObjectInstance : DWORD;  
  181.          UniqueID : Longint;  
  182.          NameOffset : DWORD;  
  183.          NameLength : DWORD;  
  184.      end;  
  185.   
  186.      PPERF_INSTANCE_DEFINITION = ^TPERF_INSTANCE_DEFINITION;  
  187.   
  188.      {$ifdef ver130}  
  189.      {$L-}         // The L+ causes internal error in Delphi 5 compiler  
  190.      {$O-}         // The O+ causes internal error in Delphi 5 compiler  
  191.      {$Y-}         // The Y+ causes internal error in Delphi 5 compiler  
  192.      {$endif}  
  193.   
  194. {$ifndef ver110}  
  195.      type  
  196.      TInt64F = TInt64;  
  197.      {$else}  
  198.      type  
  199.      TInt64F = Extended;  
  200. {$endif}  
  201.   
  202. {$ifdef ver110}  
  203. function FInt64(Value: TInt64): TInt64F;  
  204. function Int64D(Value: DWORD): TInt64;  
  205. {$else}  
  206. type  
  207.      FInt64 = TInt64F;  
  208.      Int64D = TInt64;  
  209. {$endif}  
  210.   
  211. {$ifdef ver110}  
  212. function FInt64(Value: TInt64): TInt64F;  
  213. Var  
  214.      V: TInt64;  
  215. begin  
  216.      if (Value.HighPart and $80000000) = 0 then // positive value  
  217.      begin  
  218.      result:=Value.HighPart;  
  219.      result:=result*$10000*$10000;  
  220.      result:=result+Value.LowPart;  
  221.      end  
  222.      else  
  223.      begin  
  224.      V.HighPart:=Value.HighPart xor $FFFFFFFF;  
  225.      V.LowPart:=Value.LowPart xor $FFFFFFFF;  
  226.      result:= -1 - FInt64(V);  
  227.      end;  
  228. end;  
  229.   
  230. function Int64D(Value: DWORD): TInt64;  
  231. begin  
  232.      Result.LowPart:=Value;  
  233.      Result.HighPart := 0; // positive only  
  234. end;  
  235. {$endif}  
  236.   
  237. Const  
  238.      Processor_IDX_Str = '238';  
  239.      Processor_IDX = 238;  
  240.      CPUUsageIDX = 6;  
  241.   
  242. type  
  243.      AInt64F = array[0..$FFFF] of TInt64F;  
  244.      PAInt64F = ^AInt64F;  
  245.   
  246. Var  
  247.      _PerfData : PPERF_DATA_BLOCK;  
  248.      _BufferSize: Integer;  
  249.      _POT : PPERF_OBJECT_TYPE;  
  250.      _PCD: PPerf_Counter_Definition;  
  251.      _ProcessorsCount: Integer;  
  252.      _Counters: PAInt64F;  
  253.      _PrevCounters: PAInt64F;  
  254.      _SysTime: TInt64F;  
  255.      _PrevSysTime: TInt64F;  
  256.      _IsWinNT: Boolean;  
  257.   
  258.      _W9xCollecting: Boolean;  
  259.      _W9xCpuUsage: DWORD;  
  260.      _W9xCpuKey: HKEY;  
  261.   
  262. procedure GetMemoryTotalSize(Var iPhysicsMemoryTotalSize,  
  263.          iVirtualMemoryTotalSize,  
  264.          iPageFileMemoryTotalSize : DWORD);  
  265. iPhysicsMemoryTotalSize 物理内存总容量 
  266. iVirtualMemoryTotalSize 虚拟内存总容量 
  267. iPageFileMemoryTotalSize 交换内存(页面)总容量 
  268. }  
  269. Var  
  270.      msMemory : TMemoryStatus;  
  271. begin  
  272.      msMemory.dwLength := SizeOf(msMemory);  
  273.      GlobalMemoryStatus(msMemory);  
  274.      iPhysicsMemoryTotalSize := msMemory.dwTotalPhys;  
  275.      iVirtualMemoryTotalSize := msMemory.dwTotalVirtual;  
  276.      iPageFileMemoryTotalSize := msMemory.dwTotalPageFile;  
  277. end;  
  278.   
  279. procedure GetMemoryCurrentSize(Var iPhysicsMemoryCurrentSize,  
  280.          iVirtualMemoryCurrentSize,  
  281.          iPageFileMemoryCurrentSize : DWORD);  
  282. iPhysicsMemoryCurrentSize 物理内存可用容量 
  283. iVirtualMemoryCurrentSize 虚拟内存可用容量 
  284. iPageFileMemoryCurrentSize 交换内存(页面)可用容量 
  285. }  
  286. Var  
  287.      msMemory : TMemoryStatus;  
  288. begin  
  289.      msMemory.dwLength := SizeOf(msMemory);  
  290.      GlobalMemoryStatus(msMemory);  
  291.      iPhysicsMemoryCurrentSize := msMemory.dwAvailPhys;  
  292.      iVirtualMemoryCurrentSize := msMemory.dwAvailVirtual;  
  293.      iPageFileMemoryCurrentSize := msMemory.dwAvailPageFile;  
  294. end;  
  295.   
  296. function GetMemoryUsage : Double;  
  297. 返回内存当前使用率 总的是100%,传回的是0-100%间的使用率,可以自己做转换。 
  298. }  
  299. Var  
  300.      msMemory : TMemoryStatus;  
  301. begin  
  302.      try  
  303.      msMemory.dwLength := SizeOf(msMemory);  
  304.      GlobalMemoryStatus(msMemory);  
  305.      Result := msMemory.dwMemoryLoad;  
  306.      except  
  307.      Result := 0;  
  308.      end;  
  309. end;  
  310.   
  311. function GetCPUCount: Integer;  
  312. 获取CPU数量 
  313. }  
  314. begin  
  315.      if _IsWinNT then  
  316.      begin  
  317.      if _ProcessorsCount < 0 then  
  318.          CollectCPUData;  
  319.      Result:=_ProcessorsCount;  
  320.      end  
  321.      else  
  322.      begin  
  323.      Result:=1;  
  324.      end;  
  325. end;  
  326.   
  327. procedure ReleaseCPUData;  
  328. Var  
  329.      H: HKEY;  
  330.      R: DWORD;  
  331.      DwDataSize, DwType: DWORD;  
  332. begin  
  333.      if _IsWinNT then Exit;  
  334.      if Not _W9xCollecting then Exit;  
  335.      _W9xCollecting := False;  
  336.      RegCloseKey(_W9xCpuKey);  
  337.      R := RegOpenKeyEx( HKEY_DYN_DATA, 'PerfStats/StopStat', 0, KEY_ALL_ACCESS, H);  
  338.      if R <> ERROR_SUCCESS then Exit;  
  339.      dwDataSize := Sizeof(DWORD);  
  340.      RegQueryValueEx(H,'KERNEL/CPUUsage', Nil, @DwType, PBYTE(@_W9xCpuUsage), @DwDataSize);  
  341.      RegCloseKey(H);  
  342. end;  
  343.   
  344. function GetCPUUsage(Index: Integer): Double;  
  345. 获取CPU当前使用率 
  346. }  
  347. begin  
  348.      if _IsWinNT then  
  349.      begin  
  350.      if _ProcessorsCount < 0 then CollectCPUData;  
  351.      if (Index >= _ProcessorsCount) Or (Index < 0) then  
  352.          Raise Exception.Create('CPU index out of bounds');  
  353.      if _PrevSysTime = _SysTime then  
  354.          Result := 0  
  355.      else  
  356.          Result := 1-(_Counters[index] - _PrevCounters[index])/(_SysTime-_PrevSysTime);  
  357.      end  
  358.      else  
  359.      begin  
  360.      if Index <> 0 then  
  361.          Raise Exception.Create('CPU index out of bounds');  
  362.      if Not _W9xCollecting then  
  363.          CollectCPUData;  
  364.      Result := _W9xCpuUsage/100;  
  365.      end;  
  366. end;  
  367.   
  368. Var  
  369.      VI: TOSVERSIONINFO;  
  370.   
  371. procedure CollectCPUData;  
  372. Var  
  373.      BS, i : Integer;  
  374.      _PCB_Instance : PPERF_COUNTER_BLOCK;  
  375.      _PID_Instance : PPERF_INSTANCE_DEFINITION;  
  376.      ST : TFileTime;  
  377.      H : HKEY;  
  378.      R : DWORD;  
  379.      DwDataSize, dwType: DWORD;  
  380. begin  
  381.      if _IsWinNT then  
  382.      begin  
  383.      BS:=_BufferSize;  
  384.      while RegQueryValueEx( HKEY_PERFORMANCE_DATA, Processor_IDX_Str, nil, nil,  
  385.          PByte(_PerfData), @BS ) = ERROR_MORE_DATA do  
  386.      begin  
  387.          INC(_BufferSize,$1000);  
  388.          BS:=_BufferSize;  
  389.          ReallocMem( _PerfData, _BufferSize );  
  390.      end;  
  391.   
  392.      _POT := PPERF_OBJECT_TYPE(DWORD(_PerfData) + _PerfData.HeaderLength);  
  393.      for i := 1 to _PerfData.NumObjectTypes do  
  394.      begin  
  395.          if _POT.ObjectNameTitleIndex = Processor_IDX then Break;  
  396.          _POT := PPERF_OBJECT_TYPE(DWORD(_POT) + _POT.TotalByteLength);  
  397.      end;  
  398.   
  399.      if _POT.ObjectNameTitleIndex <> Processor_IDX then  
  400.          Raise Exception.Create('Unable to locate the "Processor" performance object');  
  401.   
  402.      if _ProcessorsCount < 0 then  
  403.      begin  
  404.          _ProcessorsCount:=_POT.NumInstances;  
  405.          GetMem(_Counters,_ProcessorsCount*SizeOf(TInt64));  
  406.          GetMem(_PrevCounters,_ProcessorsCount*SizeOf(TInt64));  
  407.      end;  
  408.   
  409.      _PCD := PPERF_Counter_DEFINITION(DWORD(_POT) + _POT.HeaderLength);  
  410.      for i := 1 to _POT.NumCounters do  
  411.      begin  
  412.          if _PCD.CounterNameTitleIndex = CPUUsageIDX then Break;  
  413.          _PCD := PPERF_COUNTER_DEFINITION(DWORD(_PCD) + _PCD.ByteLength);  
  414.      end;  
  415.   
  416.      if _PCD.CounterNameTitleIndex <> CPUUsageIDX then  
  417.          Raise Exception.Create('Unable to locate the "% of CPU usage" performance counter');  
  418.   
  419.      _PID_Instance := PPERF_INSTANCE_DEFINITION(DWORD(_POT) + _POT.DefinitionLength);  
  420.      for i := 0 to _ProcessorsCount-1 do  
  421.      begin  
  422.          _PCB_Instance := PPERF_COUNTER_BLOCK(DWORD(_PID_Instance) + _PID_Instance.ByteLength);  
  423.          _PrevCounters[i]:=_Counters[i];  
  424.          _Counters[i]:=FInt64(PInt64(DWORD(_PCB_Instance) + _PCD.CounterOffset)^);  
  425.          _PID_Instance := PPERF_INSTANCE_DEFINITION(DWORD(_PCB_Instance) + _PCB_Instance.ByteLength);  
  426.      end;  
  427.   
  428.      _PrevSysTime:=_SysTime;  
  429.      SystemTimeToFileTime(_PerfData.SystemTime, ST);  
  430.      _SysTime:=FInt64(TInt64(ST));  
  431.      end  
  432.      else  
  433.      begin  
  434.      if Not _W9xCollecting then  
  435.      begin  
  436.          R:=RegOpenKeyEx( HKEY_DYN_DATA, 'PerfStats/StartStat', 0, KEY_ALL_ACCESS, H );  
  437.          if R <> ERROR_SUCCESS then  
  438.          Raise Exception.Create('Unable to start performance monitoring');  
  439.          dwDataSize:=sizeof(DWORD);  
  440.          RegQueryValueEx( H, 'KERNEL/CPUUsage', nil, @dwType, PBYTE(@_W9xCpuUsage), @dwDataSize );  
  441.          RegCloseKey(H);  
  442.          R:=RegOpenKeyEx( HKEY_DYN_DATA, 'PerfStats/StatData', 0,KEY_READ, _W9xCpuKey );  
  443.          if R <> ERROR_SUCCESS then  
  444.          Raise Exception.Create('Unable to read performance data');  
  445.          _W9xCollecting:=True;  
  446.      end;  
  447.   
  448.      dwDataSize:=sizeof(DWORD);  
  449.      RegQueryValueEx( _W9xCpuKey, 'KERNEL/CPUUsage', nil,@dwType, PBYTE(@_W9xCpuUsage), @dwDataSize );  
  450.      end;  
  451. end;  
  452.   
  453. function GetCPUVendor : TVendor; assembler; register;  
  454. asm  
  455.      PUSH     EBX                                         {Save affected register}  
  456.      PUSH     EDI  
  457.      MOV     EDI,EAX                         {@Result (TVendor)}  
  458.      MOV     EAX,0  
  459.      DW     $A20F                                 {CPUID Command}  
  460.      MOV     EAX,EBX  
  461.      XCHG                 EBX,ECX     {save ECX result}  
  462.      MOV                         ECX,4  
  463. @1:  
  464.      STOSB  
  465.      SHR     EAX,8  
  466.      LOOP     @1  
  467.      MOV     EAX,EDX  
  468.      MOV                         ECX,4  
  469. @2:  
  470.      STOSB  
  471.      SHR     EAX,8  
  472.      LOOP     @2  
  473.      MOV     EAX,EBX  
  474.      MOV                         ECX,4  
  475. @3:  
  476.      STOSB  
  477.      SHR     EAX,8  
  478.      LOOP     @3  
  479.      POP     EDI                                         {Restore registers}  
  480.      POP     EBX  
  481. end;  
  482.   
  483. initialization  
  484.      _ProcessorsCount:= -1;  
  485.      _BufferSize:= $2000;  
  486.      _PerfData := AllocMem(_BufferSize);  
  487.      VI.dwOSVersionInfoSize := SizeOf(VI);  
  488.      if Not GetVersionEx(VI) then  
  489.      Raise Exception.Create('Can''t get the Windows version');  
  490.      _IsWinNT := VI.dwPlatformId = VER_PLATFORM_WIN32_NT;  
  491.   
  492. finalization  
  493.      ReleaseCPUData;  
  494.      FreeMem(_PerfData);  
  495.       
  496. end.  

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多