2016-12-01 73 views
2

我想獲得有可視窗口的進程的名稱。例如,如果我打開了Chrome瀏覽器,我希望獲得字符串「chrome.exe」,但是我只使用下面的代碼獲取init值「unknown」。如何獲取具有可見窗口的任何進程的名稱 - WinAPI?

我讀過它可能是一個訪問權限問題,你能否告訴我如何改變它們以獲取進程的名稱?

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,就像我說的。

編輯:我忘了說,我剛過濾可見的窗口,所以假設手柄是我需要的。

+0

您需要添加錯誤檢查,這樣就可以告訴哪個呼叫失敗。 –

+0

https://wj32.org/wp/2010/03/30/get-the-image-file-name-of-any-process-from-any-user-on-vista-and-above/ – RbMm

+0

好的,首先感謝您的答案。我添加了一些std :: cout << GetLastError,並且在EnumProcessModules中出現了錯誤299。 搜索了它,ERROR_PARTIAL_COPY 299(0x12B) 只有部分ReadProcessMemory或WriteProcessMemory請求已完成。 – Serusar

回答

-1

這個問題如何獲得進程名稱/路徑ID - 很多時候已經在這裏回答了。

如果你需要的名字只(而不是完整路徑) - 您可以使用CreateToolhelp32Snapshot/Process32First/Process32Next 比較PROCESSENTRY32.th32ProcessIDidProc並使用PROCESSENTRY32.szExeFile

替代和更有效的方式使用ZwQuerySystemInformationSystemProcessInformation信息class.compare SYSTEM_PROCESS_INFORMATION.UniqueProcessIdidProc並使用SYSTEM_PROCESS_INFORMATION.ImageName。真正的第一種方法是通過這種方法。

,如果你需要的不僅是名字,但完整路徑:

,如果你有SE_DEBUG_PRIVILEGE - 你需要啓用它,打開進程與PROCESS_QUERY_LIMITED_INFORMATION(遠景+)或PROCESS_QUERY_INFORMATION(XP/2003)並使用ZwQueryInformationProcessProcessImageFileName(返程在NT形式路徑)或GetProcessImageFileName內部調用它ZwQueryInformationProcess(,ProcessImageFileName,)

或從Vista開始 - 你可以再次使用ProcessImageFileNameWin32(返回Win32的路徑)或QueryFullProcessImageName唯一記載的薄殼過這樣

也從vista開始 - 最有效的方式查詢過程全路徑(在NT形式) - 使用ZwQuerySystemInformationSystemProcessIdInformation信息類。這種方式不要求任何特權和開放的過程

+2

Downvoted for recommendations ZwQueryInformationProcess –

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
+0

'PROCESS_QUERY_INFORMATION | PROCESS_VM_READ' - 這是錯誤。主要我們不需要'PROCESS_VM_READ'。並從vista開始,我們需要在'PROCESS_QUERY_INFORMATION'處使用'PROCESS_QUERY_LIMITED_INFORMATION'' – RbMm

+0

爲什麼不使用'GetModuleFileNameEx'而是使用'GetProcessImageFileName'_?對我來說,他們產生相同的結果唯一不同的是驅動器字母形式的路徑,而不是設備。 – Salvador

相關問題