31

How do I get the process name from a PID using C++ in Windows?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Muhammad
  • 311
  • 1
  • 3
  • 3

6 Answers6

28

I guess the OpenProcess function should help, given that your process possesses the necessary rights. Once you obtain a handle to the process, you can use the GetModuleFileNameEx function to obtain full path (path to the .exe file) of the process.

#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;
}
Salman A
  • 262,204
  • 82
  • 430
  • 521
  • It would be interesting to know how to get a PID in the first place, though this is not asked by the OP. – Jaywalker Dec 31 '10 at 13:06
  • @Jaywalker A wmi call and the win32_process class will do the trick – ROAR Dec 31 '10 at 13:26
  • @Jaywalker: You can use EnumProcesses (http://msdn.microsoft.com/en-us/library/ms682629.aspx) – Salman A Dec 31 '10 at 14:19
  • 5
    Instead of including psapi.lib in additional dependencies section you can just do a #pragma comment(lib, "psapi.lib") – dlchambers Dec 16 '12 at 02:33
  • 1
    To get the process id from a HWND you can use `DWORD processId; GetWindowThreadProcessId(hwnd, &processId);`. – Andreas Haferburg Sep 17 '13 at 16:53
  • I used the method as described above, and it only works on some processes. Some processes (Such as system ones) don't return a name. Any pointers on how to get those remaining names? – SneakyTactician Aug 01 '17 at 15:31
  • I use the following line to get the name of current program: GetModuleFileNameEx((HANDLE)-1, 0, Buffer, BUFSIZE); – user5280911 Jun 12 '18 at 10:01
  • It looks like (at least on the win11) it is enough to use just PROCESS_QUERY_LIMITED_INFORMATION access right, without PROCESS_VM_READ. So, there would be less chance to get the "access denied" error. – user2134488 Aug 19 '23 at 17:11
15

You can obtain the process name by using the WIN32 API GetModuleBaseName after having the process handle. You can get the process handle by using OpenProcess.

To get the executable name you can also use GetProcessImageFileName.

Brian R. Bondy
  • 339,232
  • 124
  • 596
  • 636
12

All the above methods require psapi.dll to be loaded (Read the remarks section) and iterating through process snapshot is an option one should not even consider for getting a name of the executable file from an efficiency standpoint.

The best approach, even according to MSDN recommendation, is to use 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;
}
T.s. Arun
  • 317
  • 5
  • 17
3

If you are trying to get the executable image name of a given process, take a look at GetModuleFileName.

Nicolas Repiquet
  • 9,097
  • 2
  • 31
  • 53
  • GetModuleFileName doesn't take PID in consideration. It just gives the fully-qualified path for the file that contains the specified module. – Vikram.exe Dec 31 '10 at 12:54
1

Try this function :

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();
}
1

Check out the enumprocess functions in the tool help library:

http://msdn.microsoft.com/en-us/library/ms682629(v=vs.85).aspx

Good example @ http://msdn.microsoft.com/en-us/library/ms682623(v=vs.85).aspx

amirpc
  • 1,638
  • 3
  • 19
  • 24