网上资料显示,有这么三种方法可以用来获取系统运行进程信息:
方法 | 平台 | 备注 |
PSAPI | Windows NT,Windows2000,Windows XP | 获取进程,驱动器,模块,内存和工作集信息 |
性能计数器 | Windows NT,Windows2000,Windows XP | 提供除进程清单以外的关于进程的更多信息,可在远程机器上使用。 |
TOOLHELP32 | Windows 9x,Windows2000,Windows XP | 获取进程,线程,模块和堆信息 |
此前使用的Snapshot就是属于TOOLHELP32的(http://blog.csdn.net/betabin/article/details/7478140)。
PSAPI全称为进程状态API,MSDN有介绍http://msdn.microsoft.com/en-us/library/windows/desktop/ms684884(v=vs.85).aspx。
该方法,使用过后,感觉与TOOLHELP32的大致相同,也比较简洁方便。但是在获取驱动、内存等方面,由于PSAPI有很多方法支持,相比而言,会更加简单实用。
主要通过EnumProcess函数来获取所有运行进程的ID,然后再分别通过EnumProcessModules、EnumDeviceDrives等函数,获得相应的计数器或者指针信息。
下面就简单贴出MSDN的几段实例(原程序在Win7下无法编译通过,需要添加Psapi.lib库,既是#pragma comment(lib, "Psapi.lib"))。
(四段代码……有点懒了,呵呵)
/* #include <windows.h> #include <stdio.h> #include <tchar.h> #include <psapi.h> #pragma comment(lib, "Psapi.lib") // To ensure correct resolution of symbols, add Psapi.lib to TARGETLIBS // and compile with -DPSAPI_VERSION=1 void PrintProcessNameAndID( DWORD processID ) { TCHAR szProcessName[MAX_PATH] = TEXT("<unknown>"); // Get a handle to the process. HANDLE hProcess = OpenProcess( PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, processID ); // Get the process name. if (NULL != hProcess ) { HMODULE hMod; DWORD cbNeeded; if ( EnumProcessModules( hProcess, &hMod, sizeof(hMod), &cbNeeded) ) { GetModuleBaseName( hProcess, hMod, szProcessName, sizeof(szProcessName)/sizeof(TCHAR) ); } } // Print the process name and identifier. _tprintf( TEXT("%s (PID: %u)\n"), szProcessName, processID ); // Release the handle to the process. CloseHandle( hProcess ); } int main( void ) { // Get the list of process identifiers. DWORD aProcesses[1024], cbNeeded, cProcesses; unsigned int i; if ( !EnumProcesses( aProcesses, sizeof(aProcesses), &cbNeeded ) ) { return 1; } // Calculate how many process identifiers were returned. cProcesses = cbNeeded / sizeof(DWORD); // Print the name and process identifier for each process. for ( i = 0; i < cProcesses; i++ ) { if( aProcesses[i] != 0 ) { PrintProcessNameAndID( aProcesses[i] ); } } return 0; } */ /* #include <windows.h> #include <Psapi.h> #include <tchar.h> #include <stdio.h> #pragma comment(lib, "Psapi.lib") // To ensure correct resolution of symbols, add Psapi.lib to TARGETLIBS // and compile with -DPSAPI_VERSION=1 #define ARRAY_SIZE 1024 int main( void ) { LPVOID drivers[ARRAY_SIZE]; DWORD cbNeeded; int cDrivers, i; if( EnumDeviceDrivers(drivers, sizeof(drivers), &cbNeeded) && cbNeeded < sizeof(drivers)) { TCHAR szDriver[ARRAY_SIZE]; cDrivers = cbNeeded / sizeof(drivers[0]); _tprintf(TEXT("There are %d drivers:\n"), cDrivers); for (i=0; i < cDrivers; i++ ) { if(GetDeviceDriverBaseName(drivers[i], szDriver, sizeof(szDriver) / sizeof(szDriver[0]))) { _tprintf(TEXT("%d: %s\n"), i+1, szDriver); } } } else { _tprintf(TEXT("EnumDeviceDrivers failed; array size needed is %d\n"), cbNeeded / sizeof(LPVOID)); return 1; } return 0; } */ /* #include <windows.h> #include <stdio.h> #include <psapi.h> #pragma comment (lib, "Psapi.lib") // To ensure correct resolution of symbols, add Psapi.lib to TARGETLIBS // and compile with -DPSAPI_VERSION=1 void PrintMemoryInfo( DWORD processID ) { HANDLE hProcess; PROCESS_MEMORY_COUNTERS pmc; // Print the process identifier. printf( "\nProcess ID: %u\n", processID ); // Print information about the memory usage of the process. hProcess = OpenProcess( PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, processID ); if (NULL == hProcess) return; if ( GetProcessMemoryInfo( hProcess, &pmc, sizeof(pmc)) ) { printf( "\tPageFaultCount: 0x%08X\n", pmc.PageFaultCount ); printf( "\tPeakWorkingSetSize: 0x%08X\n", pmc.PeakWorkingSetSize ); printf( "\tWorkingSetSize: 0x%08X\n", pmc.WorkingSetSize ); printf( "\tQuotaPeakPagedPoolUsage: 0x%08X\n", pmc.QuotaPeakPagedPoolUsage ); printf( "\tQuotaPagedPoolUsage: 0x%08X\n", pmc.QuotaPagedPoolUsage ); printf( "\tQuotaPeakNonPagedPoolUsage: 0x%08X\n", pmc.QuotaPeakNonPagedPoolUsage ); printf( "\tQuotaNonPagedPoolUsage: 0x%08X\n", pmc.QuotaNonPagedPoolUsage ); printf( "\tPagefileUsage: 0x%08X\n", pmc.PagefileUsage ); printf( "\tPeakPagefileUsage: 0x%08X\n", pmc.PeakPagefileUsage ); } CloseHandle( hProcess ); } int main( void ) { // Get the list of process identifiers. DWORD aProcesses[1024], cbNeeded, cProcesses; unsigned int i; if ( !EnumProcesses( aProcesses, sizeof(aProcesses), &cbNeeded ) ) { return 1; } // Calculate how many process identifiers were returned. cProcesses = cbNeeded / sizeof(DWORD); // Print the memory usage for each process for ( i = 0; i < cProcesses; i++ ) { PrintMemoryInfo( aProcesses[i] ); } return 0; } */ #include <windows.h> #include <tchar.h> #include <stdio.h> #include <psapi.h> #pragma comment (lib, "Psapi.lib") // To ensure correct resolution of symbols, add Psapi.lib to TARGETLIBS // and compile with -DPSAPI_VERSION=1 int PrintModules( DWORD processID ) { HMODULE hMods[1024]; HANDLE hProcess; DWORD cbNeeded; unsigned int i; // Print the process identifier. printf( "\nProcess ID: %u\n", processID ); // Get a handle to the process. hProcess = OpenProcess( PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, processID ); if (NULL == hProcess) return 1; // Get a list of all the modules in this process. if( EnumProcessModules(hProcess, hMods, sizeof(hMods), &cbNeeded)) { for ( i = 0; i < (cbNeeded / sizeof(HMODULE)); i++ ) { TCHAR szModName[MAX_PATH]; // Get the full path to the module's file. if ( GetModuleFileNameEx( hProcess, hMods[i], szModName, sizeof(szModName) / sizeof(TCHAR))) { // Print the module name and handle value. _tprintf( TEXT("\t%s (0x%08X)\n"), szModName, hMods[i] ); } } } // Release the handle to the process. CloseHandle( hProcess ); return 0; } int main( void ) { DWORD aProcesses[1024]; DWORD cbNeeded; DWORD cProcesses; unsigned int i; // Get the list of process identifiers. if ( !EnumProcesses( aProcesses, sizeof(aProcesses), &cbNeeded ) ) return 1; // Calculate how many process identifiers were returned. cProcesses = cbNeeded / sizeof(DWORD); // Print the names of the modules for each process. for ( i = 0; i < cProcesses; i++ ) { PrintModules( aProcesses[i] ); } return 0; }