问题
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.
回答1:
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
回答2:
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 useGetProcessImageFileName
来源:https://stackoverflow.com/questions/40919455/how-can-i-get-the-name-of-any-process-having-a-visible-window-winapi