从进程ID获取进程名称(win32)
我需要获取Windows系统上所有进程的列表,包括名称和PID。
EnumProcess可以获得pid列表,但是如何从pid获取进程名称?我不想在流程上调用OpenProcess,因为这并不总是有效(例如,如果另一个流程由不同的用户运行)。从进程ID获取进程名称(win32)
CreateToolhelp32Snapshot()会给你进程名称(但不是路径);除此之外,你将不得不打电话给OpenProcess()。如果您的代码在管理环境中运行,则可以启用SE_DEBUG_NAME特权来访问在其他环境下运行的进程。
您有不同的选项,您可以使用它来接收当前正在运行的进程(进程名称,如您所写的)的exe名称。最好的方式取决于您使用的编程语言和其他需求。例如,您可以使用WMI。另一种更老的方式是使用Performance Counters(另请参阅An Introduction To Performance Counters)。要获取计数器值你可以使用注册表查询操作从HKEY_PERFORMANCE_DATA
基本密钥(见Retrieving Counter Data)
另一种方式可以是还不错采用的是NtQuerySystemInformation函数SystemProcessInformation
作为参数。 EnumProcess
和许多其他Windows API在内部使用该函数。在NtQuerySystemInformation文档中定义的结构SYSTEM_PROCESS_INFORMATION
有许多“无证”,但自许多年以来众所周知的领域。如果你在互联网上搜索结构的定义,你将被罚款完整的文件。我不知道功能帽状态没有完整记录。该功能至少在NT 3.5(可能还在之前),现在可以很好地用于Windows 7 32位或64位。要确切下面你会发现一个小的C性能测试,其打印所有进程ID与相应的exe文件名(不完整的exe路径,只是文件名):
#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;
}
,你可以得到的进程标识符和name
所有正在运行的进程使用ToolHelp API。
以下代码将显示每个进程的pid
和name
。
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);
}
}
您只需要使用: pe32.dwSize = sizeof(PROCESSENTRY32);在调用Process32First() – hB0 2012-02-13 13:59:20
@ hB0之前 - 错过了那个=) – Cyclonecode 2012-02-13 16:01:06
这真的很酷,比'NtQuerySystemInformation'技术快得多。有没有什么方法可以通过这种技术获得PID创建时间? – Noitidart 2016-01-10 13:03:10
我不认为你可以在Vista之后的Windows版本上可靠地做到这一点。你正在使用哪个版本? – 2010-11-05 00:20:13
你可以使用WMI来做这个 – 2010-11-05 00:56:22
你是什么意思的进程名称--EXE名称? – 2010-11-05 12:15:28