Я пытаюсь получить название процессов, которые имеют видимое окно. Например, если у меня открыт 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, как я уже сказал.
РЕДАКТИРОВАТЬ: я забыл сказать, я только что отфильтровал видимые окна, так что предположим, что мне еще нужны ручки.
использование 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
этот вопрос как получить имя процесса / путь по идентификатору — Здесь уже много раз отвечали.
если вам нужно только имя (но не полный путь) — вы можете использовать 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
информационный класс. этот способ не требует никаких привилегий и открытого процесса