首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >从进程id获取进程名称(win32)

从进程id获取进程名称(win32)
EN

Stack Overflow用户
提问于 2010-11-05 08:14:12
回答 3查看 38.7K关注 0票数 21

我需要获得windows系统上所有进程的列表,包括名称和PID。

EnumProcess可以获取pid列表,但是如何从pid获取进程名呢?我不想在进程上调用OpenProcess,因为这并不总是有效的(比如另一个进程是由不同的用户运行的)。

EN

回答 3

Stack Overflow用户

发布于 2011-12-04 02:03:38

您可以使用ToolHelp接口获取所有运行的进程的进程标识符和name

下面的代码将显示每个进程的pidname

代码语言:javascript
运行
复制
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);
    }
}
票数 18
EN

Stack Overflow用户

发布于 2010-11-06 06:48:15

您可以使用不同的选项来接收当前正在运行的进程的exe名称(进程名称与您编写的进程名称相同)。最好的方法取决于您使用的编程语言和其他需求。例如,您可以使用WMI。另一种更古老的方法是使用Performance Counters (另请参阅An Introduction To Performance Counters)。要获取计数器值,只需使用HKEY_PERFORMANCE_DATA基键中的注册表查询操作(请参见Retrieving Counter Data

另一种方法也可以很好地使用,那就是使用SystemProcessInformation作为参数的NtQuerySystemInformation函数。EnumProcess和许多其他Windows API在内部使用该函数。在NtQuerySystemInformation的文档中定义的结构SYSTEM_PROCESS_INFORMATION有许多“未记录的”,但由于很多很多年来众所周知的领域。如果你在互联网上搜索结构的定义,你将被罚款完整的文档。我想知道hat状态的功能是否没有完整的文档。该函数至少在NT3.5中(可能也在以前),现在可以在Windows7 32位或64位上很好地使用。准确地说,在下面你会找到一个小的C测试程序,它打印所有进程ids和相应的exe名称(不是完整的exe路径,只是文件名):

代码语言:javascript
运行
复制
#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;
}
票数 17
EN

Stack Overflow用户

发布于 2010-11-05 19:33:00

CreateToolhelp32Snapshot()将为您提供进程名称(而不是路径);除此之外,您必须调用OpenProcess()。如果您的代码在管理上下文中运行,则可以启用SE_DEBUG_NAME权限来访问在其他上下文中运行的进程。

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4102569

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档