简体   繁体   中英

How can I get the name of any process having a visible window - WinAPI?

I'm trying to get the name of processes which have a visible window. For example, if I have Chrome opened, I would like to get the string "chrome.exe", but I only get the init value "unknown" using the code below.

I read around it could be an access rights problem, can you suggest me how to change them in order to get the name of processes?

DWORD idProc = 0;       //pointer to the process which created the window
DWORD idThread = GetWindowThreadProcessId(Wnd->get_handle(), &idProc);
Wnd->set_pid(idThread); //Wnd is an object of a class i created, to collect processes info
// Get a handle to the process.
TCHAR szProcessName[DEFAULT_BUFLEN] = TEXT("<unknown>");
HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION |
    PROCESS_VM_READ,
    FALSE, idProc);

if (hProcess!=NULL) {
    HMODULE hMod;
    DWORD cbNeeded;
    if (EnumProcessModules(hProcess, &hMod, sizeof(hMod),
        &cbNeeded))
    {
        GetModuleBaseName(hProcess, hMod, szProcessName,        
            sizeof(szProcessName) / sizeof(TCHAR));
    }
}
Wnd->set_processname(szProcessName);                            
CloseHandle(hProcess);

It works fine for some processes, but it doesn't for many others like Chrome, as I said.

EDIT: I forgot to say, I've just filtered visible windows, so suppose handles are what I need yet.

use GetProcessImageNamr API instead:

#include <iostream>
using namespace std;
#include <windows.h>
#include <Psapi.h>
#pragma comment(lib, "Psapi.lib")


int main()
{

    DWORD dwProcessId;
    DWORD dwThreadId ;

    while(1)
    {
        Sleep(2000);
        HWND hForg = GetForegroundWindow(); // to get the foreground windows' handle window
        dwThreadId = GetWindowThreadProcessId(hForg, &dwProcessId); // getting the window's process ID

        DWORD dwDesiredAccess =
            PROCESS_QUERY_INFORMATION | PROCESS_VM_READ;
        bool bInheritHandle = false;
        HANDLE hProcess = OpenProcess(dwDesiredAccess,
                                bInheritHandle, dwProcessId);
        if(INVALID_HANDLE_VALUE == hProcess)
            cout << "Failed to open process!" << endl;

        HINSTANCE hMod = (HINSTANCE)GetWindowLongPtr(hForg, GWLP_HINSTANCE);
        if(!hMod)
            cout << "Null Module!" << endl;
        char szModFileName[MAX_PATH] = "";  

    //  never use this cause it won't get you what you want
    //  GetModuleFileNameEx(hProcess, hMod, szModFileName, MAX_PATH);

    //  use this
        GetProcessImageFileName(hProcess, szModFileName, MAX_PATH);

        CloseHandle(hProcess);

        char szWindowName[MAX_PATH] = "";
        GetWindowText(hForg, szWindowName, MAX_PATH);
        cout << "Window Name: " << szWindowName << endl;
        cout << "Created by: " << szModFileName << endl << endl;

    }


    cout << endl << endl << endl;
    return 0;
}
  • don't use GetModuleFileNameEx but use GetProcessImageFileName

this question how get process name/path by ID - is many time already answered here.

if you need name only (but not full path) - you can use CreateToolhelp32Snapshot / Process32First / Process32Next compare PROCESSENTRY32.th32ProcessID with your idProc and use PROCESSENTRY32.szExeFile .

alternate and more effective way use ZwQuerySystemInformation with SystemProcessInformation info class.compare SYSTEM_PROCESS_INFORMATION.UniqueProcessId with your idProc and use SYSTEM_PROCESS_INFORMATION.ImageName . really first way is shell over this method.

if you need not only name, but full path :

if you have SE_DEBUG_PRIVILEGE - you need enable it, open process with PROCESS_QUERY_LIMITED_INFORMATION (vista+) or PROCESS_QUERY_INFORMATION (xp/2003) and use ZwQueryInformationProcess with ProcessImageFileName (return path in NT form) or GetProcessImageFileName ( internally it call ZwQueryInformationProcess(,ProcessImageFileName,) )

or begin from vista - you can use ProcessImageFileNameWin32 (return win32-path) or QueryFullProcessImageName ( again only documented thin shell over this way )

also begin from vista - most effective way query process full path (in NT form) - use ZwQuerySystemInformation with SystemProcessIdInformation info class. this way not require any privileges and open process

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM