我需要获取Windows系统上所有进程的列表,包括名称和PID .EnumProcess可以获取pid列表,但是如何从pid中获取进程名称?我不总是工作(就好像其他进程是由不同的用户运行) .
Ý您可以使用ToolHelp API获取所有正在运行的进程的进程标识符和 name .以下代码将显示每个进程的 pid 和 name .
name
pid
void showProcessInformation() { HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); if(hSnapshot) { PROCESSENTRY32 pe32; pe32.dwSize = sizeof(PROCESSENTRY32); if(Process32First(hSnapshot, &pe32)) { do { printf("pid %d %s\n", pe32.th32ProcessID, pe32.szExeFile); } while(Process32Next(hSnapshot, &pe32)); } CloseHandle(hSnapshot); } }
您有不同的选项可用于接收当前正在运行的进程的exe名称(如您所写的进程名称) . 最好的方法取决于您使用的编程语言和其他要求 . 例如,您可以使用WMI . 另一个更古老的方法是使用Performance Counters(另见An Introduction To Performance Counters) . 要获取计数器值,您只需使用 HKEY_PERFORMANCE_DATA 基本键中的注册表查询操作(请参阅Retrieving Counter Data)
HKEY_PERFORMANCE_DATA
还可以使用的另一种方法是NtQuerySystemInformation函数,其中 SystemProcessInformation 作为参数 . EnumProcess 和许多其他Windows API在内部使用该功能 . NtQuerySystemInformation文档中定义的struct SYSTEM_PROCESS_INFORMATION 有很多"undocumented"但是多年以来众所周知的领域 . 如果您在Internet上搜索结构的定义,则将对完整文档进行罚款 . 我不知道功能帽状态没有完整记录 . 该功能至少在NT 3.5中(可能也在之前),现在可以很好地用于Windows 7 32位或64位 . 确切地说,你会发现一个小的C测试程序,它打印所有进程id与相应的exe名称(不是完整的exe路径,只是文件名):
SystemProcessInformation
EnumProcess
SYSTEM_PROCESS_INFORMATION
#include <Windows.h> // one can also use Winternl.h if needed //#include <Winternl.h> // for UNICODE_STRING and SYSTEM_INFORMATION_CLASS #include <stdio.h> #include <tchar.h> #define STATUS_SUCCESS ((NTSTATUS)0x00000000L) #define STATUS_INFO_LENGTH_MISMATCH ((NTSTATUS)0xC0000004L) typedef enum _SYSTEM_INFORMATION_CLASS { SystemProcessInformation = 5 } SYSTEM_INFORMATION_CLASS; typedef struct _UNICODE_STRING { USHORT Length; USHORT MaximumLength; PWSTR Buffer; } UNICODE_STRING; typedef LONG KPRIORITY; // Thread priority typedef struct _SYSTEM_PROCESS_INFORMATION_DETAILD { ULONG NextEntryOffset; ULONG NumberOfThreads; LARGE_INTEGER SpareLi1; LARGE_INTEGER SpareLi2; LARGE_INTEGER SpareLi3; LARGE_INTEGER CreateTime; LARGE_INTEGER UserTime; LARGE_INTEGER KernelTime; UNICODE_STRING ImageName; KPRIORITY BasePriority; HANDLE UniqueProcessId; ULONG InheritedFromUniqueProcessId; ULONG HandleCount; BYTE Reserved4[4]; PVOID Reserved5[11]; SIZE_T PeakPagefileUsage; SIZE_T PrivatePageCount; LARGE_INTEGER Reserved6[6]; } SYSTEM_PROCESS_INFORMATION_DETAILD, *PSYSTEM_PROCESS_INFORMATION_DETAILD; typedef NTSTATUS (WINAPI *PFN_NT_QUERY_SYSTEM_INFORMATION)( IN SYSTEM_INFORMATION_CLASS SystemInformationClass, IN OUT PVOID SystemInformation, IN ULONG SystemInformationLength, OUT OPTIONAL PULONG ReturnLength ); int main() { size_t bufferSize = 102400; PSYSTEM_PROCESS_INFORMATION_DETAILD pspid= (PSYSTEM_PROCESS_INFORMATION_DETAILD) malloc (bufferSize); ULONG ReturnLength; PFN_NT_QUERY_SYSTEM_INFORMATION pfnNtQuerySystemInformation = (PFN_NT_QUERY_SYSTEM_INFORMATION) GetProcAddress (GetModuleHandle(TEXT("ntdll.dll")), "NtQuerySystemInformation"); NTSTATUS status; while (TRUE) { status = pfnNtQuerySystemInformation (SystemProcessInformation, (PVOID)pspid, bufferSize, &ReturnLength); if (status == STATUS_SUCCESS) break; else if (status != STATUS_INFO_LENGTH_MISMATCH) { // 0xC0000004L _tprintf (TEXT("ERROR 0x%X\n"), status); return 1; // error } bufferSize *= 2; pspid = (PSYSTEM_PROCESS_INFORMATION_DETAILD) realloc ((PVOID)pspid, bufferSize); } for (;; pspid=(PSYSTEM_PROCESS_INFORMATION_DETAILD)(pspid->NextEntryOffset + (PBYTE)pspid)) { _tprintf (TEXT("ProcessId: %d, ImageFileName: %ls\n"), pspid->UniqueProcessId, (pspid->ImageName.Length && pspid->ImageName.Buffer)? pspid->ImageName.Buffer: L""); if (pspid->NextEntryOffset == 0) break; } return 0; }
CreateToolhelp32Snapshot()将为您提供进程名称(但不是路径);除此之外,您将不得不调用OpenProcess() . 如果您的代码在管理上下文中运行,则可以启用SE_DEBUG_NAME权限以访问在其他上下文下运行的进程 .
3 回答
Ý您可以使用ToolHelp API获取所有正在运行的进程的进程标识符和
name
.以下代码将显示每个进程的
pid
和name
.您有不同的选项可用于接收当前正在运行的进程的exe名称(如您所写的进程名称) . 最好的方法取决于您使用的编程语言和其他要求 . 例如,您可以使用WMI . 另一个更古老的方法是使用Performance Counters(另见An Introduction To Performance Counters) . 要获取计数器值,您只需使用
HKEY_PERFORMANCE_DATA
基本键中的注册表查询操作(请参阅Retrieving Counter Data)还可以使用的另一种方法是NtQuerySystemInformation函数,其中
SystemProcessInformation
作为参数 .EnumProcess
和许多其他Windows API在内部使用该功能 . NtQuerySystemInformation文档中定义的structSYSTEM_PROCESS_INFORMATION
有很多"undocumented"但是多年以来众所周知的领域 . 如果您在Internet上搜索结构的定义,则将对完整文档进行罚款 . 我不知道功能帽状态没有完整记录 . 该功能至少在NT 3.5中(可能也在之前),现在可以很好地用于Windows 7 32位或64位 . 确切地说,你会发现一个小的C测试程序,它打印所有进程id与相应的exe名称(不是完整的exe路径,只是文件名):CreateToolhelp32Snapshot()将为您提供进程名称(但不是路径);除此之外,您将不得不调用OpenProcess() . 如果您的代码在管理上下文中运行,则可以启用SE_DEBUG_NAME权限以访问在其他上下文下运行的进程 .