'Getting process description with given process-id

I've got a program that enumerates all processes with the Toolhelp API. With my Sysinternals Process Explorer I also can see a description of all processes. Is this description coming from the executable ? How do I get its name ?

That's my current code to enumerate the processes:

#include <Windows.h>
#include <TlHelp32.h>
#include <iostream>
#include <vector>
#include <system_error>
#include <memory>

using namespace std;

vector<PROCESSENTRY32W> getAllProcesses();

int main()
{
    for( PROCESSENTRY32W &pe : getAllProcesses() )
        wcout << pe.szExeFile << endl;
}

using XHANDLE = unique_ptr<void, decltype([]( HANDLE h ) { h && h != INVALID_HANDLE_VALUE && CloseHandle( h ); })>;

vector<PROCESSENTRY32W> getAllProcesses()
{
    auto throwSysErr = []() { throw system_error( (int)GetLastError(), system_category(), "error enumerating processes" ); };
    vector<PROCESSENTRY32W> processes;
    XHANDLE xhSnapshot( CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 ) );
    if( xhSnapshot.get() == INVALID_HANDLE_VALUE )
        throwSysErr();;
    PROCESSENTRY32W pe;
    pe.dwSize = sizeof pe;
    if( !Process32FirstW( xhSnapshot.get(), &pe ) )
        throwSysErr();
    for( ; ; )
    {
        processes.emplace_back( pe );
        pe.dwSize = sizeof pe;
        if( !Process32NextW( xhSnapshot.get(), &pe ) )
            if( GetLastError() == ERROR_NO_MORE_FILES )
                break;
            else
                throwSysErr();
    }
    return processes;
}


Solution 1:[1]

@RemyLebeau 's way with code implement which is adapted from VerQueryValueA document sample. And as OpenProcess states,

If the specified process is the System Idle Process (0x00000000), the function fails and the last error code is ERROR_INVALID_PARAMETER. If the specified process is the System process or one of the Client Server Run-Time Subsystem (CSRSS) processes, this function fails and the last error code is ERROR_ACCESS_DENIED because their access restrictions prevent user-level code from opening them.

int main()
{
    TCHAR szFile[MAX_PATH] = {};
    DWORD dwSize = MAX_PATH;

    for (PROCESSENTRY32W& pe : getAllProcesses())
    {
        wcout << pe.szExeFile << endl;

        HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION,
            FALSE, pe.th32ProcessID);
        if (hProcess == NULL)
        {
            //ErrorExit(TEXT("OpenProcess"));
        }
        else
        {
            memset(szFile, 0, MAX_PATH);
            dwSize = MAX_PATH;
            QueryFullProcessImageName(hProcess,0, szFile,&dwSize);
            DWORD s = GetFileVersionInfoSize(szFile,NULL);
            if (s != 0)
            {
                LPVOID lpData = HeapAlloc(GetProcessHeap(), 0, s);
                GetFileVersionInfo(szFile,0,s, lpData);

                HRESULT hr;
                UINT cbTranslate;
                struct LANGANDCODEPAGE {
                    WORD wLanguage;
                    WORD wCodePage;
                } *lpTranslate;

                // Read the list of languages and code pages.

                VerQueryValue(lpData,
                    TEXT("\\VarFileInfo\\Translation"),
                    (LPVOID*)&lpTranslate,
                    &cbTranslate);

                // Read the file description for each language and code page.
                LPVOID lpBuffer;
                UINT dwBytes;
                for (int i = 0; i < (cbTranslate / sizeof(struct LANGANDCODEPAGE)); i++)
                {
                    TCHAR SubBlock[255] = {};
                    hr = StringCchPrintf(SubBlock, 50,
                        TEXT("\\StringFileInfo\\%04x%04x\\FileDescription"),
                        lpTranslate[i].wLanguage,
                        lpTranslate[i].wCodePage);
                    if (FAILED(hr))
                    {
                        // TODO: write error handler.
                    }

                    // Retrieve file description for language and code page "i". 
                    VerQueryValue(lpData,
                        SubBlock,
                        &lpBuffer,
                        &dwBytes);

                    wcout << (TCHAR*)(lpBuffer) << endl;
                }
                HeapFree(GetProcessHeap(), 0, lpData);
            }
            //GetProcessImageFileName(hProcess, szFile, dwSize);
        }

    }
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 YangXiaoPo - MSFT