如何在C++中获取进程名称

32

如何使用C ++在Windows中从PID获取进程名称?

6个回答

29

我猜测 OpenProcess 函数应该有帮助,假设 你的 进程具备必要的权限。获取进程句柄之后,你可以使用 GetModuleFileNameEx 函数来获取进程的完整路径(即 .exe 文件的路径)。

#include "stdafx.h"
#include "windows.h"
#include "tchar.h"
#include "stdio.h"
#include "psapi.h"
// Important: Must include psapi.lib in additional dependencies section
// In VS2005... Project > Project Properties > Configuration Properties > Linker > Input > Additional Dependencies

int _tmain(int argc, _TCHAR* argv[])
{
    HANDLE Handle = OpenProcess(
        PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,
        FALSE,
        8036 /* This is the PID, you can find one from windows task manager */
    );
    if (Handle) 
    {
        TCHAR Buffer[MAX_PATH];
        if (GetModuleFileNameEx(Handle, 0, Buffer, MAX_PATH))
        {
            // At this point, buffer contains the full path to the executable
        }
        else
        {
            // You better call GetLastError() here
        }
        CloseHandle(Handle);
    }
    return 0;
}

虽然OP并没有问,但知道如何首先获取PID是有趣的。 - Jaywalker
@Jaywalker 一个 WMI 调用和 Win32_Process 类会解决问题。 - ROAR
5
不必将psapi.lib包含在附加依赖项部分,你只需要使用#pragma comment(lib, "psapi.lib")即可。 - dlchambers
1
要从HWND获取进程ID,您可以使用DWORD processId; GetWindowThreadProcessId(hwnd, &processId); - Andreas Haferburg
我按照上述方法进行了操作,但它只适用于某些进程。一些进程(例如系统进程)不返回名称。有什么指针可以获取这些剩余的名称吗? - SneakyTactician
显示剩余3条评论

15

12

以上所有方法都需要加载psapi.dll (请参阅备注部分), 从效率的角度考虑,迭代进程快照以获取可执行文件名称不是一个应该考虑的选项。

根据MSDN的建议,最佳方法是使用QueryFullProcessImageName

std::string ProcessIdToName(DWORD processId)
{
    std::string ret;
    HANDLE handle = OpenProcess(
        PROCESS_QUERY_LIMITED_INFORMATION,
        FALSE,
        processId /* This is the PID, you can find one from windows task manager */
    );
    if (handle)
    {
        DWORD buffSize = 1024;
        CHAR buffer[1024];
        if (QueryFullProcessImageNameA(handle, 0, buffer, &buffSize))
        {
            ret = buffer;
        }
        else
        {
            printf("Error GetModuleBaseNameA : %lu", GetLastError());
        }
        CloseHandle(handle);
    }
    else
    {
        printf("Error OpenProcess : %lu", GetLastError());
    }
    return ret;
}

3
如果您想获取给定进程的可执行文件名称,请查看GetModuleFileName。该函数的详细信息可以在GetModuleFileName中找到。

GetModuleFileName不考虑PID。它只提供包含指定模块的文件的完全限定路径。 - Vikram.exe

1
尝试这个函数:

std::wstring GetProcName(DWORD aPid)
{ 
 PROCESSENTRY32 processInfo;
    processInfo.dwSize = sizeof(processInfo);
    HANDLE processesSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL);
    if (processesSnapshot == INVALID_HANDLE_VALUE)
    {
      std::wcout  << "can't get a process snapshot ";
      return 0;
    }

    for(BOOL bok =Process32First(processesSnapshot, &processInfo);bok;  bok = Process32Next(processesSnapshot, &processInfo))
    {
        if( aPid == processInfo.th32ProcessID)
        {
            std::wcout << "found running process: " << processInfo.szExeFile;
            CloseHandle(processesSnapshot);
            return processInfo.szExeFile;
        }

    }
    std::wcout << "no process with given pid" << aPid;
    CloseHandle(processesSnapshot);
    return std::wstring();
}

3
非常缓慢的解决方案。 - Ezh


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接