Как я могу получить имя любого процесса, имеющего видимое окно — WinAPI?

Я пытаюсь получить название процессов, которые имеют видимое окно. Например, если у меня открыт Chrome, я хотел бы получить строку «chrome.exe», но я получаю только значение инициализации «unknown», используя приведенный ниже код.

Я читал вокруг, это может быть проблема с правами доступа, можете ли вы предложить мне, как изменить их, чтобы получить название процессов?

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);

Он отлично работает для некоторых процессов, но не для многих других, таких как Chrome, как я уже сказал.

РЕДАКТИРОВАТЬ: я забыл сказать, я только что отфильтровал видимые окна, так что предположим, что мне еще нужны ручки.

2

Решение

использование GetProcessImageNamr API вместо этого:

#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;
}
  • не использовать GetModuleFileNameEx но использовать GetProcessImageFileName
0

Другие решения

этот вопрос как получить имя процесса / путь по идентификатору — Здесь уже много раз отвечали.

если вам нужно только имя (но не полный путь) — вы можете использовать CreateToolhelp32Snapshot / Process32First / Process32Next
сравнить PROCESSENTRY32.th32ProcessID с вашим idProc и использовать PROCESSENTRY32.szExeFile,

альтернативный и более эффективный способ использования ZwQuerySystemInformation с SystemProcessInformation информация class.compare SYSTEM_PROCESS_INFORMATION.UniqueProcessId с вашим idProc и использовать SYSTEM_PROCESS_INFORMATION.ImageName, действительно первый способ это оболочка над этим методом.

если вам нужно не только имя, но и полный путь:

если у вас есть SE_DEBUG_PRIVILEGE — вам нужно включить его, открыть процесс с PROCESS_QUERY_LIMITED_INFORMATION (Vista +) или PROCESS_QUERY_INFORMATION (XP / 2003) и использовать ZwQueryInformationProcess с ProcessImageFileName (обратный путь в NT-форме) или GetProcessImageFileName (внутренне это называют ZwQueryInformationProcess(,ProcessImageFileName,))

или начать с перспективы — вы можете использовать ProcessImageFileNameWin32 (вернуть win32-путь) или QueryFullProcessImageName (опять только документированная тонкая оболочка над этим способом)

также начинайте с перспективы — наиболее эффективный способ обработки запросов полного пути (в форме NT) — используйте ZwQuerySystemInformation с SystemProcessIdInformation информационный класс. этот способ не требует никаких привилегий и открытого процесса

-1