C语言 从进程 id (win32) 中获取进程名称
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4102569/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
get process name from process id (win32)
提问by David Chen
I need to get a list of all processes on a windows system including names and PID.
EnumProcesscan obtain a list of pids, but how do I get the process name from the pid? I don't want to call OpenProcess on the process as that doesn't always work (like if the other process is run by a different user).
我需要获取 Windows 系统上所有进程的列表,包括名称和 PID。
EnumProcess可以获得 pid 列表,但如何从 pid 中获取进程名称?我不想在进程上调用 OpenProcess,因为这并不总是有效(就像另一个进程由不同的用户运行一样)。
回答by Oleg
You have different option which you can use to receive exe names of currently running processes (process names like you wrote). The best way depends a little from the programming language which you use and from other requirements. For example you can use WMI. One other more old way is the usage of Performance Counters(see also An Introduction To Performance Counters). To get the counters values you can just use registry query operations from the HKEY_PERFORMANCE_DATAbase key (see Retrieving Counter Data)
您可以使用不同的选项来接收当前正在运行的进程的 exe 名称(如您所写的进程名称)。最好的方法在一定程度上取决于您使用的编程语言和其他要求。例如,您可以使用 WMI。另一种更古老的方法是使用性能计数器(另请参阅性能计数器简介)。要获取计数器值,您只需使用HKEY_PERFORMANCE_DATA基本键中的注册表查询操作(请参阅检索计数器数据)
One more way which can be also good used is the NtQuerySystemInformationfunction with SystemProcessInformationas a parameter. EnumProcessand many other Windows API use the function internally. The struct SYSTEM_PROCESS_INFORMATIONdefined in the documentation of NtQuerySystemInformationhas many "undocumented" but since many many years well-known fields. If you search in the Internet for the definition of the structure you will fined full documentation. I wonder that the function hat status not full documented. The function was at least in NT 3.5 (probably also before) and can be good used now on Windows 7 32- or 64-bit. To be exact below you will find a small C test program which print all process ids with the corresponding exe names (not full exe path, just the file name):
另一种可以很好使用的方法是将NtQuerySystemInformation函数SystemProcessInformation作为参数。EnumProcess和许多其他 Windows API 在内部使用该函数。NtQuerySystemInformationSYSTEM_PROCESS_INFORMATION文档中定义的结构有许多“未记录”但多年来众所周知的字段。如果您在 Internet 上搜索结构的定义,您将无法获得完整的文档。我想知道功能帽状态没有完整记录。该功能至少在 NT 3.5 中(可能也是之前)并且现在可以在 32 位或 64 位 Windows 7 上很好地使用。确切地说,您将在下面找到一个小的 C 测试程序,它使用相应的 exe 名称(不是完整的 exe 路径,只是文件名)打印所有进程 ID:
#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;
}
回答by Cyclonecode
You can get the process identifier and namefor all running processes using the ToolHelpAPI.
The following code will display the pidand namefor each process.
您可以name使用ToolHelpAPI获取进程标识符和所有正在运行的进程。
以下代码将显示每个进程的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);
}
}
回答by Luke
CreateToolhelp32Snapshot() will give you the process name (but not the path); other than that, you will have to call OpenProcess(). If your code is running in an administrative context you could enable the SE_DEBUG_NAME privilege to get access to processes running under other contexts.
CreateToolhelp32Snapshot() 将为您提供进程名称(但不是路径);除此之外,您将不得不调用 OpenProcess()。如果您的代码在管理上下文中运行,您可以启用 SE_DEBUG_NAME 权限以访问在其他上下文中运行的进程。

