如何获取程序的CPU和内存的使用率?(100分)

  • 主题发起人 主题发起人 叶子黄了
  • 开始时间 开始时间

叶子黄了

Unregistered / Unconfirmed
GUEST, unregistred user!
我自己写的一个程序,需要显示这个程序的CPU和内存的使用率
最好有详细代码
 
http://www.tomore.com/down_file.php?id=30188
CPU
 
这个是VB代码,我看不懂
 
http://www.swissdelphicenter.ch/torry/showcode.php?id=969
How to get the CPU usage in percent

const

SystemBasicInformation = 0;

SystemPerformanceInformation = 2;

SystemTimeInformation = 3;

type

TPDWord = ^DWORD;

TSystem_Basic_Information = packed record

dwUnknown1: DWORD;

uKeMaximumIncrement: ULONG;

uPageSize: ULONG;

uMmNumberOfPhysicalPages: ULONG;

uMmLowestPhysicalPage: ULONG;

uMmHighestPhysicalPage: ULONG;

uAllocationGranularity: ULONG;

pLowestUserAddress: Pointer;

pMmHighestUserAddress: Pointer;

uKeActiveProcessors: ULONG;

bKeNumberProcessors: byte;

bUnknown2: byte;

wUnknown3: word;

end;

type

TSystem_Performance_Information = packed record

liIdleTime: LARGE_INTEGER; {LARGE_INTEGER}

dwSpare: array[0..75] of DWORD;

end;

type

TSystem_Time_Information = packed record

liKeBootTime: LARGE_INTEGER;

liKeSystemTime: LARGE_INTEGER;

liExpTimeZoneBias: LARGE_INTEGER;

uCurrentTimeZoneId: ULONG;

dwReserved: DWORD;

end;

var

NtQuerySystemInformation: function(infoClass: DWORD;

buffer: Pointer;

bufSize: DWORD;

returnSize: TPDword): DWORD; stdcall = nil;

 

liOldIdleTime: LARGE_INTEGER = ();

liOldSystemTime: LARGE_INTEGER = ();

function Li2Double(x: LARGE_INTEGER): Double;

begin

Result := x.HighPart * 4.294967296E9 + x.LowPart

end;

procedure GetCPUUsage;

var

SysBaseInfo: TSystem_Basic_Information;

SysPerfInfo: TSystem_Performance_Information;

SysTimeInfo: TSystem_Time_Information;

status: Longint; {long}

dbSystemTime: Double;

dbIdleTime: Double;

bLoopAborted : boolean;

begin

if @NtQuerySystemInformation = nil then

NtQuerySystemInformation := GetProcAddress(GetModuleHandle('ntdll.dll'),

'NtQuerySystemInformation');

// get number of processors in the system

status := NtQuerySystemInformation(SystemBasicInformation, @SysBaseInfo, SizeOf(SysBaseInfo), nil);

if status <> 0 then Exit;

// Show some information

with SysBaseInfo do

begin

ShowMessage(

Format('uKeMaximumIncrement: %d'#13'uPageSize: %d'#13+

'uMmNumberOfPhysicalPages: %d'+#13+'uMmLowestPhysicalPage: %d'+#13+

'uMmHighestPhysicalPage: %d'+#13+'uAllocationGranularity: %d'#13+

'uKeActiveProcessors: %d'#13'bKeNumberProcessors: %d',

[uKeMaximumIncrement, uPageSize, uMmNumberOfPhysicalPages,

uMmLowestPhysicalPage, uMmHighestPhysicalPage, uAllocationGranularity,

uKeActiveProcessors, bKeNumberProcessors]));

end;

 

bLoopAborted := False;

while not bLoopAborted do

begin

// get new system time

status := NtQuerySystemInformation(SystemTimeInformation, @SysTimeInfo, SizeOf(SysTimeInfo), 0);

if status <> 0 then Exit;

// get new CPU's idle time

status := NtQuerySystemInformation(SystemPerformanceInformation, @SysPerfInfo, SizeOf(SysPerfInfo), nil);

if status <> 0 then Exit;

// if it's a first call - skip it

if (liOldIdleTime.QuadPart <> 0) then

begin

// CurrentValue = NewValue - OldValue

dbIdleTime := Li2Double(SysPerfInfo.liIdleTime) - Li2Double(liOldIdleTime);

dbSystemTime := Li2Double(SysTimeInfo.liKeSystemTime) - Li2Double(liOldSystemTime);

// CurrentCpuIdle = IdleTime / SystemTime

dbIdleTime := dbIdleTime / dbSystemTime;

// CurrentCpuUsage% = 100 - (CurrentCpuIdle * 100) / NumberOfProcessors

dbIdleTime := 100.0 - dbIdleTime * 100.0 / SysBaseInfo.bKeNumberProcessors + 0.5;

// Show Percentage

Form1.Label1.Caption := FormatFloat('CPU Usage: 0.0 %',dbIdleTime);

Application.ProcessMessages;

// Abort if user pressed ESC or Application is terminated

bLoopAborted := (GetKeyState(VK_ESCAPE) and 128 = 128) or Application.Terminated;

end;

// store new CPU's idle and system time

liOldIdleTime := SysPerfInfo.liIdleTime;

liOldSystemTime := SysTimeInfo.liKeSystemTime;

// wait one second

Sleep(1000);

end;

end;

 

procedure TForm1.Button1Click(Sender: TObject);

begin

GetCPUUsage

end;
 
几个基本的例子,由此可演化得到许多硬件信息。
结果放在Memo1中。

procedure TForm1.Button1Click(Sender: TObject);

var

systeminfo: SYSTEM_INFO;

memory: MEMORYSTATUS;

sector,byte,cluster,free: DWORD;

freespace,totalspace: longint;

CDtype: UINT;

name: CHAR;

drvname: string;

volname,filesysname: PCHAR;

sno,maxl,fileflag: DWORD;

begin

Memo1.Lines.Clear();

//获得CPU型号

GetSystemInfo(systeminfo);

Memo1.Lines.Add('您的CPU类型是:' + inttostr(systeminfo.dwProcessorType));

//获得内存状态

memory.dwLength := sizeof(memory); //初始化

GlobalMemoryStatus(memory);

Memo1.Lines.Add('您的物理内存是(' + inttostr(integer(memory.dwTotalPhys div 1024 div 1024)) + 'MB)。');

Memo1.Lines.Add('其中可用内存是(' + inttostr(integer(memory.dwTotalPhys div 1024)) + 'KB)。');

//获得C盘可用空间

GetDiskFreeSpace('C:', LPDWORD(@sector)^, LPDWORD(@byte)^, LPDWORD(@free)^, LPDWORD(@cluster)^); //获得返回参数

totalspace := cluster * byte * sector div 1024 div 1024; //计算总容量

freespace := free * byte * sector div 1024 div 1024; //计算可用空间

Memo1.Lines.Add('C盘总空间(' + inttostr(integer(totalspace)) + 'MB)。');

Memo1.Lines.Add('C盘可用空间(' + inttostr(integer(freespace)) + 'MB)。');

//检测CD-ROM,是否有光盘

GetMem(volname, 255);

GetMem(filesysname, 100);

for name :='C' to 'Z' do//循环检测A~Z

begin

drvname := name + ':';

CDtype := GetDriveType(PCHAR(@drvname[1])); //获得磁盘类型

if (CDtype = DRIVE_CDROM) then

begin

Memo1.Lines.Add('您的光驱盘符为[' + drvname + ']');

volname^ := Chr(0);

filesysname^ := Chr(0);

if ( not (GetVolumeInformation(PCHAR(@drvname[1]), volname, 250, LPDWORD(@sno), LPDWORD(@maxl)^, LPDWORD(@fileflag)^, filesysname,100))) then

Memo1.Lines.Add(drvname + '驱中没有发现光盘') //如果返回值为假

else //如果返回值为真

begin

Memo1.Lines.Add (drvname + '驱中光盘卷标为: [' + String(volname) + ']');

Memo1.Lines.Add (drvname + '驱中光盘序号为: [' + inttostr(sno) + ']');

end;

end;

end;

FreeMem(volname);

FreeMem(filesysname)

end;

均来自 超级猛料2003
 
上面那个好像是可以显示CPU的占有
但是显示的是整个CPU的占用情况
我要的是,我的程序在CPU中占用率,就是在任务管理器看到某个进程的CPU占用情况
不是整个CPU的占用率
 
话题1360311的标题是: 检测某个程序占用的内存(急) (0分)
分类:Windows API gztoms (2002-10-11 15:43:00)
各位大虾:
有谁知道用什么API函数能检测出某一程序占用的内存,
相当于在“任务管理器”里的“进程”叶中所看到的一样。
多谢了!!!

kcahcn (2002-10-10 7:49:00)
任务管理器调用 NtQuerySystemInformation 。还可以用NtQueryInformationProcess.
两者都是本机API(Native API) .
也可以用GetProcessMemoryInfo 包含在PsAPI.
GetPMem(PID:DWORD);
var
pmc: PPROCESS_MEMORY_COUNTERS;
cb: Integer;
phandle:Thandle;
begin
phandle:=OpenProcess(PROCESS_ALL_ACCESS,false,PID);
cb := sizeof(_PROCESS_MEMORY_COUNTERS);
GetMem(pmc, cb);
pmc^.cb := cb;
if GetProcessMemoryInfo(phandle, pmc, cb) then
ShowMessage(IntToStr(pmc^.WorkingSetSize))
else
ShowMessage('错误');
end;

gztoms (2002-10-05 17:46:00)
请问kcahcn:
参数PID是要传递什么?

duducat (2002-10-05 19:00:00)
pid 进程ID

kcahcn (2002-10-06 1:11:00)
Thanks duducat .PID -> 进程ID

下面是个用NtQueryInformationProcess的例子 : [ NT ,2K,XP ]
// 参考: Windows NT/2000 本机API (Gary Nebbett)
// Tested using Delphi 6.0, 7.0 On WinXP
type
PVM_Counters=^TVM_Counters;
TVM_Counters=record
PeakVirtualSize:ULONG;
VirtualSize:ULONG;
PagedFaultCount:ULONG;
PeakWorkingSetSize:ULONG;
WorkingSetSize:ULONG;
QuotaPeakPagedPoolUsage:ULONG;
QuotaPagedPoolUsage:ULONG;
QuotaPeakNonPagedPoolUsage:ULONG;
QuotaNonPagedPoolUsage:ULONG;
PagefileUsage:ULONG;
PeakPagefileUsage:ULONG;
end;
const ProcessVMCounters =3;
...
function NtQueryInformationProcess
(
ProcessHandle: Thandle;
PrcInfoClass:DWORD ;
PrcInfo:Pointer ;
PrcInfoLength:ULONG;
returnlength: TPDword
):
DWORD; stdcall ;external 'ntdll.dll' name 'NtQueryInformationProcess';
// 可以用动态调用(隐式装入)
....
// Our Function here:
function GetPrcVMCounters(PID:DWORD):TStringList;
var
status:DWORD;
retlen:DWORD;
VM_Info:TVM_Counters;
hProcess:THandle;
begin
result:=TStringList.Create;
hProcess :=OpenProcess(PROCESS_QUERY_INFORMATION,FALSE,PID);
status:=NtQueryInformationProcess
(
hProcess,
ProcessVMCounters,
@VM_Info,
sizeof(TVM_Counters),
@retlen
);
if(status<>0) then
begin
ShowMessage('NtQueryInformationProcess 失败');
exit;
end;
with result do
begin
Add('进程虚拟地址空间的最大数值 : '+IntToStr(VM_Info.PeakVirtualSize)+' Byte');
Add('进程的虚拟地址空间的大小 : '+IntToStr(VM_Info.VirtualSize)+' Byte');
Add('进程分页错误数目 : '+IntToStr(VM_Info.PagedFaultCount)+' Byte');
Add('进程的工作集列表的最大值 : '+IntToStr(VM_Info.PeakWorkingSetSize)+' Byte');
Add('进程的工作集列表的大小 : '+IntToStr(VM_Info.WorkingSetSize)+' Byte'); // <--- 就是这个 [:D]
Add('填充到进程的分页池的峰值的最大值 : '+IntToStr(VM_Info.QuotaPeakPagedPoolUsage)+' Byte');
Add('填充到进程的分页池的峰值大小 : '+IntToStr(VM_Info.QuotaPagedPoolUsage)+' Byte');
Add('填充到进程的非分页池的峰值的最大值 : '+IntToStr(VM_Info.QuotaNonPagedPoolUsage)+' Byte');
Add('填充到进程的分页池的峰值大小 : '+IntToStr(VM_Info.QuotaNonPagedPoolUsage)+' Byte');
Add('进程多使用的页文件页的最大值 : '+IntToStr(VM_Info.PeakPagefileUsage)+' Byte');
end;
end;
// ----
procedure TForm1.Button2Click(Sender: TObject);
begin
Memo1.Lines:=GetPrcVMCounters(256);
end;

-------------------------
CIONO1

duducat (2002-10-08 8:27:00)
to kcahcn
TPDword=PWORD;

为什么以上方法对PID=0的Idle Process进程占有的物理内存显示不正确??:))
2000下面应该为16K,XP下面是24K,以上方法中GetProcessMemoryInfo显示的是变化的,
数值根本不对,NtQueryInformationProcess则显示的为0!

duducat (2002-10-08 8:32:00)
另外进程CPU占用率也是一个有点技术含量的问题,不知道各位大侠解决没有?

duducat (2002-10-08 8:40:00)
最后9X下面物理内存的使用也是个头痛的问题,嘻嘻……
好像据我所知就TaskInfo2002解决的比较圆满(收费),
prcview(显示不正确)和processwalker则根本没有解决……(免费)
我想这是收费与免费的小小区别吧!
……
题外话,国产的进程管理器俺真是搞不懂,什么技术含量的问题都没有涉及
和解决,就要注册和收注册费了,真是丢中国人的脸……
严重了!!!!!!见谅!

yyk518 (2002-10-08 8:47:00)
做这些东西还有意义吗?技术含量再高,高得过M$吗?[:D]

duducat (2002-10-08 9:17:00)
to yyk518
那你永远做MS的最“忠实”用户好了:))好乖亚……
学计算机干吗??对你有意义嘛?
因为你和你的子孙学几百年都不会超过MS的技术高峰的


yyk518 (2002-10-09 8:54:00)
呵呵,这么大火气干嘛呢?
你不也在做MS的忠实用户吗?!你要做的什么破软件不也是要在WINDOWS下运行,舔MS的
屁股吗?有种开发一套DUDUCAT OS出来看看啊!瞎牛B!![:D]

duducat (2002-10-09 12:12:00)
白痴……只知道MS……

duducat (2002-10-09 12:43:00)
干吗让我开发os??笑死人了……
我又不是搞电脑的,也不需要靠它来赚钱谋生……
终于知道中国的IT业技术水平为什么这么低,原来是有一些猪头加奴隶充实在当中……
另外,我是人不是牛,人为什么要和牛作比较了,弱智……
做人不知道廉耻,就猪狗不如了……
什么都不知道,还这么神气……佩服佩服呀
哈哈哈哈哈哈哈!!!
天下真是无其不有……哈哈哈哈哈哈

to kcahcn
要讨论技术问题的,以后再跟你联系吧!

yyk518 (2002-10-09 16:19:00)
哦?你不是牛?可我怎么看你都比牛还牛啊!也许,是牛的后代也说不定,哈哈哈
你既然不是搞电脑的,又在这里瞎起什么哄!
知道MS没什么不好吧?!还“中国的IT”呢,谈到IT,不知道MS行吗?蠢猪!!!
呀,别生气啊!竟把猪比作了你(猪听见了可要生气了)
>>什么都不知道,还这么神气
究竟是谁神气了?初出茅庐就不知天高地厚,连MS都不放在眼里了!如果中国人真的能
做出超越MS的软件,我当然非常高兴!但问题是,我们与MS的差距还很大,所以我们必需
好好向人家学习,多做些有益的事!不要两眼向天的走路,那样,你迟早会摔死的!

duducat (2002-10-09 17:01:00)
做人不知道廉耻,就猪狗不如了……
什么都不知道,还这么神气……佩服佩服呀
哈哈哈哈哈哈哈!!!
天下真是无其不有……哈哈哈哈哈哈


duducat (2002-10-09 18:11:00)
教教你吧……人不可有傲气,但不能无傲骨……能者为师
不过你属牛的,跟你说了也不懂,反正是对牛弹琴……
一副奴才像!不过MS好喜欢你的啦,觉得你好哟好可爱哟,呆会买糖给你吃!
(旁白:然后高呼打倒unix,Linux,Java……他们牛个屁呀,能玩服务器,能跨平台嘛?……
嘻嘻,都不如我的MS牛牛牛牛牛(省略5万字)……没有想到太高兴,碰了石头,最后“扑哧”
摔了个狗啃屎……5555555道:“MS,MS,……救救我!!他们说你坏话了,
我要你打他们的小屁股……”然后奋力举起MS掉在粪坑黑乎乎糖,
叫道:“MS的糖是世界最香的糖啦……”, 咬了起来。没想到却是个屁,
还得意的叫道,“MS的屁也是最世界最最香的”……)
当然领导也很喜欢你这种牛了,帮着擦擦皮鞋,拍拍马屁,
赏你个吃“世界上最香的屁”吃吃……哈哈哈哈哈
干吗学电脑了,这又不会那也不会编,又要冒充IT人士,这到没有什么!(人各有所长)
可恶的是还专门打击比那些比你懂得多的人,心理寻思(他会那么多有啥用?
能比XX强嘛?能牛过XX吗?再厉害也不过是个中国人罢了……嘻嘻,
到最后还不如我嘴皮子1/100功效了……)
…………
俺心地善良,以后谁做了大领导一定推荐你这头牛去去拎拎皮鞋哟,呵呵!
编程就免了(即没有创意,又不肯向别人学习……)
哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈
…………
to 其他各位,对不起了,浪费你们的时间了……
非技术问题,到此为止!

kcahcn (2002-10-10 8:06:00)
对于 system process “系统进程“要先设置SeDebugPrivilege才能用OpenProcess。
飞到这儿: http://support.microsoft.com/default.aspx?scid=kb;en-us;Q131065
用这个方法 对 System Idle Process好像也没有用!!!
TaskManager,Pview 调用的是NtQuerySystemInformation所以没出现这个问题。
我用了那个函数(服务)果然没问题。可以得到System Idle Process所占的内存 (20kb WinXP)。
更多资料关于NtQuerySystemInformation请参考"Windows Nt/2000 本机API"。
关于CPU的占用率可以用GetProcessTimes 。(用Native API 也可以)
http://groups.google.com/groups?hl=en&lr=&ie=UTF-8&oe=UTF-8&selm=3816527f.149304919%40nntp.cts.com

看 : http://groups.google.com/groups?q=GetProcessTimes+CPU&ie=UTF-8&oe=UTF-8&hl=en&btnG=Google+Search
-----
CIONO1

yyk518 (2002-10-10 8:32:00)
TO duducat:
呵呵,没想到我随意说说,竟把这头笨牛给惹疯了,前言不搭后语,牛B哄哄地拉了一大堆
牛屎,哈哈哈,我看你不但瞎牛还很蠢,是即有牛的基因又有猪的血统,莫不是猪牛杂交
货?[:D][:D][:D]

duducat (2002-10-10 12:37:00)
垃圾就是垃圾,呵呵,从里到外都是的……
……
to kcahcn
thanx!我说这些问题去年其实已经解决了……只是想讨论一下还有没有别的更好方法!
小日本的Processwalker(免费)
http://www001.upp.so-net.ne.jp/yamashita/
中还实现了其他很多有用的功能,如:进程拥有的特权之类。这些没有实现得了
所以找你的……
交个朋友吧,有空来我这里玩……,呵呵
代我向你妹妹问好……:)

duducat (2002-10-10 21:21:00)
to gztoms
把分加给kcahcnkcahcn,他比我大方……

to kcahcn 再见了……希望以后还有机会跟你联系!我已经把它翻译成Delphi……
我用的不是这个函数!不过我现在有点喜欢NTQuerySystemInformation了!虽然它
存在不稳定因素:P

#include <windows.h>
#include <stdio.h>
#include <stdlib.h>

#ifndef STATUS_INFO_LENGTH_MISMATCH
#define STATUS_INFO_LENGTH_MISMATCH ((DWORD )0xC0000004L)
#endif

typedef struct
{
FILETIME ftCreationTime;
DWORD dwUnknown1;
DWORD dwStartAddress;
DWORD dwOwningPID;
DWORD dwThreadID;
DWORD dwCurrentPriority;
DWORD dwBasePriority;
DWORD dwContextSwitches;
DWORD dwThreadState;
DWORD dwWaitReason;
DWORD dwUnknown2[5];
} THREADINFO, *PTHREADINFO;

#pragma warning( disable:4200 ) // Zero sized array
typedef struct
{
DWORD dwRelativeOffset; //相对偏移量
DWORD dwThreadCount; //线程数目
DWORD dwUnknown1[6];
FILETIME pfCreateTime;
DWORD dwUnknown2[5];
WCHAR* pszProcessName; //不带路径的名称
DWORD dwBasePriority; //优先级
DWORD dwProcessID; //进程ID
DWORD dwParentProcessID; //父进程ID
DWORD dwHandleCount; //句柄数目
DWORD dwUnknown3;
DWORD dwUnknown4;
DWORD dwVirtualBytesPeak;
DWORD dwTotalVirtualBytes;
DWORD dwPageFaults;
DWORD dwWorkingSetPeak;
DWORD dwTotalWorkingSet; //占用物理内存大小
DWORD dwPeakPagedPoolUsagePages;
DWORD dwTotalPagedPoolUsagePages;
DWORD dwPeakNonPagedPoolUsagePages;
DWORD dwTotalNonPagedPoolUsagePages;
DWORD dwPageFileBytesPeak;
DWORD dwPrivateBytes;
DWORD dwPageFileBytes;
DWORD dwUnknown7[4];
THREADINFO ti[0];
} _PROCESSINFO, *PPROCESSINFO;
#pragma warning( default:4200 )

DWORD (__stdcall *NtQuerySystemInformation )(ULONG,PVOID,ULONG,ULONG);

void ShowPI(void)
{
PBYTE pbyInfo = NULL;
PPROCESSINFO pProcessInfo;
DWORD dwSize = 0x4000;
WCHAR *pname;

if (!NtQuerySystemInformation)
NtQuerySystemInformation=(DWORD (__stdcall*)(ULONG,PVOID,ULONG,ULONG))

GetProcAddress(GetModuleHandle("ntdll.dll"),"NtQuerySystemInformation");

pbyInfo=(PBYTE) malloc(dwSize);

if (pbyInfo)
{
for(;;)
{
memset(pbyInfo,0,dwSize);


if(NtQuerySystemInformation(5,pbyInfo,dwSize,0)!=STATUS_INFO_LENGTH_MISMATCH
)
break;

dwSize += 0x1000;

pbyInfo=(PBYTE) realloc(pbyInfo,dwSize);
}

pProcessInfo = ( PPROCESSINFO ) pbyInfo;

for(;;)
{
pname=pProcessInfo->pszProcessName;

if (!pname)
pname=(L"Idle");

printf("%-40ls %-12lu %12luK/n",
pname,
pProcessInfo->dwProcessID,
pProcessInfo->dwTotalWorkingSet/1024ul
);

if ( pProcessInfo->dwRelativeOffset == 0 )
break;


pProcessInfo=(PPROCESSINFO)((PBYTE)pProcessInfo+pProcessInfo->dwRelativeOffset);
}

free( pbyInfo );
}
}

int main(void)
{
ShowPI();
getchar();
return 0;
}


duducat (2002-10-10 21:28:00)
to gztoms
9X的自己研究吧……实在不知道,明年再联系!
to kcahcn
人生无常,唯朋友最值得珍惜……

kcahcn (2002-10-10 22:17:00)
to duducat : Thanks alot;
我会把我写的代码(经过改进后)发到你的邮箱。(还要一段时间)
NativeAPI有很多东西可以研究。很多人在研究。多多看看Nebbett写的那本书。
有什么冬冬告诉我。[:D]
to gztoms :我不是为了积分而回答。我不需要积分。Knowledge is free .

CIONO1

gztoms (2002-10-11 15:43:00)
谢谢kcahcn,duducat
 
下载一个控件:
MiTeC System Information Component Suite 10.2.0
里面直接有这样的控件得到硬件的各种信息,像EVEREST一样,当然也包括CPU和内存的占用率。
 
happycyp
你提供的源码不对
没有CPU占用的信息
 
weiliu
那个控件下载了
不知道哪个是CPU占用率
他的Demo中有个CPU TIME 好像不是的
 
这个控件里不是有个process viewer的DEMO吗?
 
是的

但是这个东西不行,刷新一次进程列表,CPU都是100%在运行大约要10几秒的时间

系统自带的任务管理器一点也不费资源的
 
控件有个process viewer
 
接受答案了.
 
后退
顶部