如何获得具有可见窗口的任何进程的名称 - WinAPI?

时间:2016-12-01 20:05:26

标签: c++ windows winapi access-rights

我正在尝试获取具有可见窗口的进程的名称。例如,如果我打开了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 个答案:

答案 0 :(得分:0)

改为使用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

答案 1 :(得分:-1)

这个问题如何通过ID获取流程名称/路径 - 很多时候已在这里得到解答。

如果您只需要名称(但不是完整路径) - 您可以使用CreateToolhelp32Snapshot / Process32First / Process32NextPROCESSENTRY32.th32ProcessIDidProc进行比较,然后使用PROCESSENTRY32.szExeFile

使用ZwQuerySystemInformation SystemProcessInformationSYSTEM_PROCESS_INFORMATION.UniqueProcessId idProc SYSTEM_PROCESS_INFORMATION.ImageName与您的SE_DEBUG_PRIVILEGE一起使用PROCESS_QUERY_LIMITED_INFORMATION,并使用PROCESS_QUERY_INFORMATION。真的第一种方法就是使用这种方法。

如果您不仅需要名称,还需要完整路径:

如果您有ZwQueryInformationProcess - 您需要启用它,使用ProcessImageFileName(vista +)或GetProcessImageFileName(xp / 2003)打开流程,并使用ZwQueryInformationProcess(,ProcessImageFileName,) {{1} (以NT格式返回路径)或ProcessImageFileNameWin32在内部调用QueryFullProcessImageName

或从vista开始 - 您可以使用ZwQuerySystemInformation(返回win32路径)或SystemProcessIdInformation再次仅通过此方式记录薄壳

也从vista开始 - 最有效的查询过程完整路径(以NT形式) - 使用day1.txt day2.txt .... day10.txt day11.txt day1.txt day10.txt day11.txt day2.txt day3.txt 信息类。这种方式不需要任何权限和开放流程