2010-03-07 45 views
11

我試圖讓我的所有推出的Windows可執行名稱的名字和我的問題是:如何獲得一個窗口的可執行文件名

我使用的方法

UINT GetWindowModuleFileName(  
HWND hwnd, 
LPTSTR lpszFileName, 
UINT cchFileNameMax); 

我不明白爲什麼它不起作用。

數據,我有一個窗口,分別是:
-HWND及的ProcessID

的錯誤是: 如:

HWND: 00170628 
ProcessId: 2336   
WindowTitle: C:\test.cpp - Notepad++ 
GetWindowModuleFileName(): C:\test.exe 

HWND: 00172138 
ProcessId: 2543   
WindowTitle: Firefox 
GetWindowModuleFileName(): C:\test.exe 

HWND: 00120358 
ProcessId: 2436   
WindowTitle: Mozilla Thunderbird 
GetWindowModuleFileName(): C:\test.exe 

注:test.exe的是我的可執行文件的名稱,但它不是記事本+ +的完整路徑...它也使Mozilla Thunderbird ...我不明白爲什麼

我使用這樣的功能:

char filenameBuffer[4000]; 
if (GetWindowModuleFileName(hWnd, filenameBuffer, 4000) > 0) 
{ 
    std::cout << "GetWindowModuleFileName(): " << filenameBuffer << std::endl; 
} 

謝謝你的迴應。

回答

16

該函數僅適用於當前進程中的窗口。 1您必須執行以下操作。

  1. 使用GetWindowThreadProcessId檢索窗口的過程。
  2. 使用OpenProcess以PROCESS_QUERY_INFORMATION和PROCESS_VM_READ訪問權限打開進程。
  3. 在進程句柄上使用GetModuleFileNameEx

如果你真的想獲得與該窗口登記(而不是過程可執行文件)模塊的名稱,你可以用GetWindowLongPtr與GWLP_HINSTANCE獲取模塊句柄。模塊手柄然後可以傳遞給前述的GetModuleFileNameEx

+0

@avakar:謝謝你的工作 – Jaguar 2010-03-07 19:51:01

+1

http://msdn.microsoft.com/en-us/library/windows/desktop/dd318087%28v=vs.85%29.aspx – 2013-09-17 07:40:26

+0

@MartinBa,請注意,它帶來了依賴oleacc.dll,但。 – avakar 2013-09-17 08:04:00

1

那麼根據你似乎是正確地調用它,如果你的可執行文件位於C的根MSDN pageGetWindowModuleFileName:它返回正確的值:

的GetWindowModuleFileName函數檢索與指定的窗口句柄關聯的模塊的完整路徑和文件名。

你期待什麼回來?

+0

@ChrisF:看看我的例子,我添加了三個記事本,firefox和thunderbird程序...和我的可執行文件名爲text.exe這些程序? 它是黑暗的力量? – Jaguar 2010-03-07 19:35:40

+0

@Jaguar - 我不確定發生了什麼事。 MSDN頁面意味着您可以爲任何窗口句柄調用此函數,但它確實顯示它只返回正在運行的程序的模塊名稱。 – ChrisF 2010-03-07 19:38:09

+0

@Ninefingers:沒錯,我嘗試獲取firefox.exe,正如你可以在我的例如我的HWND上看到的那樣打印出好的WindowTitle,但GetWindowModuleFileName函數不會這樣做! – Jaguar 2010-03-07 19:41:50

3

Aaah。我閱讀底部的MSDN頁面。

http://support.microsoft.com/?id=228469

GetWindowModuleFileName和 GetModuleFileName正確檢索 信息AB ... GetWindowModuleFileName和 GetModuleFileName正確檢索窗口和模塊 調用進程 信息。在Windows 95 和98中,他們返回有關 窗口和其他 進程中的模塊的信息。但是,在Windows NT 4.0 和Windows 2000,因爲模塊處理 不再由所有進程 共享,因爲他們是在Windows 95和98, 這些API不返回有關其他 工藝窗口和模塊的信息 。

爲了獲得更多的信息,在Windows 2000 ,使用進程狀態助手 組API(稱爲PSAPI,請參閱 Psapi.h包括文件),可用自 的Windows NT 4.0。 API如 GetModuleFileNameEx和 GetModuleBaseName報價相當於 功能。

嘗試使用GetModuleFileNameEx代替。

+0

@Ninefingers:謝謝你的幫助! – Jaguar 2010-03-07 19:52:05

1

這是如何獲得創建窗口可執行名稱的例子得到的HWND進程ID,希望它可以給你一些想法:

while(true) 
    { 
    Sleep(250);//reduce cpu usage 
    CHAR __name[MAX_PATH];//name buffer 
    HWND hwnd;//window handle 
    DWORD pid;//process pid 
    hwnd=FindWindow(NULL,NULL);//find any window 
    PROCESSENTRY32 entry;//process structure containing info about processes 
    entry.dwSize=sizeof(PROCESSENTRY32); 
    HANDLE snapshot=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);//get processes 
    if(hwnd!=0) 
    { 
     GetWindowThreadProcessId(hwnd,&pid);//get found window pid 
    } 
    if (Process32First(snapshot,&entry)==TRUE)//start listing processes 
    { 
     while (Process32Next(snapshot,&entry)==TRUE) 
     { 
      if (stricmp(entry.szExeFile,"explorer.exe")==0) 
      { 
       if(pid!=entry.th32ProcessID)//if found window pid is explorers one, skip it 
       { 
        HANDLE hProcess=OpenProcess(PROCESS_ALL_ACCESS,FALSE,pid);//open processusing PROCESS_ALL_ACCESS to get handle 
        if(hProcess!=NULL) 
        { 
         GetModuleFileNameEx(hProcess,NULL,__name,MAX_PATH);//get executable path 
         cout<<"Found: "<<__name<<endl; 
        } 
       } 
      } 
     } 
    } 

要使用GetModuleFileNameEx ()你可能需要設置鏈接器設置來鏈接庫psapi。還包括psapi.h。

+0

+ 1到'CreateToolhelp32Snapshot',這是我發現的唯一方法,它實際上很容易地爲所有活動進程返回exe文件名,這與通常需要額外訪問權的'OpenProcess'不同。 – Salvador 2017-02-19 23:39:10

相關問題