我正在尝试获取具有可见窗口的进程的名称。例如,如果我打开了 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。
编辑:我忘了说,我刚刚过滤了可见窗口,所以假设句柄是我所需要的。
最佳答案
这个问题如何通过 ID 获取进程名称/路径 - 这里已经回答了很多次。
如果您只需要名称(而不是完整路径)- 您可以使用 CreateToolhelp32Snapshot
/Process32First
/Process32Next
将 PROCESSENTRY32.th32ProcessID
与您的 idProc
进行比较并使用 PROCESSENTRY32.szExeFile
。
另一种更有效的方法是使用 ZwQuerySystemInformation
和 SystemProcessInformation
info class.compare SYSTEM_PROCESS_INFORMATION.UniqueProcessId
和你的 idProc
并使用 SYSTEM_PROCESS_INFORMATION.ImageName
。真正的第一种方法是对该方法进行 shell。
如果您不仅需要名称,还需要完整路径:
如果您有 SE_DEBUG_PRIVILEGE
- 您需要启用它,使用 PROCESS_QUERY_LIMITED_INFORMATION
(vista+) 或 PROCESS_QUERY_INFORMATION
(xp/2003) 打开进程并使用ZwQueryInformationProcess
与 ProcessImageFileName
(NT 形式的返回路径)或 GetProcessImageFileName
(在内部调用 ZwQueryInformationProcess(,ProcessImageFileName,)
)
或从 vista 开始 - 您可以使用 ProcessImageFileNameWin32
(返回 win32 路径)或 QueryFullProcessImageName
(再次仅通过这种方式记录薄壳 )
同样从 vista 开始 - 查询进程完整路径的最有效方式(以 NT 形式) - 使用 ZwQuerySystemInformation
和 SystemProcessIdInformation
信息类。这种方式不需要任何权限和开放进程
关于c++ - 如何获取具有可见窗口的任何进程的名称 - WinAPI?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40919455/