简体   繁体   English

如何获取窗口的可执行文件名

[英]How to get the Executable name of a window

I try to get the name of executable name of all of my launched windows and my problem is that:我尝试获取所有已启动窗口的可执行文件名称,我的问题是:

I use the method我用方法

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

And I don't understand why it doesn't work.而且我不明白为什么它不起作用。

Data which I have about a window are:我拥有的关于窗口的数据是:
-HWND AND PROCESSID -HWND 和进程 ID

The error is: eg:错误是:例如:

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

Note: test.exe is the name of my executable file, but it is not the fullpath of Notepad++... and it make this for Mozilla Thunderbird too... I don't understand why注意:test.exe 是我的可执行文件的名称,但它不是 Notepad++ 的完整路径......而且它也为 Mozilla Thunderbird 制作了这个......我不明白为什么

I use the function like this:我使用这样的功能:

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

Thank you for your response.谢谢您的答复。

The GetWindowModuleFileName function works for windows in the current process only. GetWindowModuleFileName函数仅适用于当前进程中的窗口。

You have to do the following:您必须执行以下操作:

  1. Retrieve the window's process with GetWindowThreadProcessId .使用GetWindowThreadProcessId检索窗口的进程。
  2. Open the process with PROCESS_QUERY_INFORMATION and PROCESS_VM_READ access rights using OpenProcess .使用OpenProcess打开具有PROCESS_QUERY_INFORMATIONPROCESS_VM_READ访问权限的进程。
  3. Use GetModuleFileNameEx on the process handle.在进程句柄上使用GetModuleFileNameEx

If you really want to obtain the name of the module with which the window is registered (as opposed to the process executable), you can obtain the module handle with GetWindowLongPtr with GWLP_HINSTANCE .如果您确实想获取注册窗口的模块的名称(而不是进程可执行文件),您可以使用GetWindowLongPtrGWLP_HINSTANCE获取模块句柄。 The module handle can then be passed to the aforementioned GetModuleFileNameEx .然后可以将模块句柄传递给前面提到的GetModuleFileNameEx

Example:例子:

TCHAR buffer[MAX_PATH] = {0};
DWORD dwProcId = 0; 

GetWindowThreadProcessId(hWnd, &dwProcId);   

HANDLE hProc = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ , FALSE, dwProcId);    
GetModuleFileName((HMODULE)hProc, buffer, MAX_PATH);
CloseHandle(hProc);

Aaah.啊。 I read the MSDN page at the bottom.我阅读了底部的 MSDN 页面。

From http://support.microsoft.com/?id=228469 ( archive.org link ):来自http://support.microsoft.com/?id=228469(archive.org 链接):

GetWindowModuleFileName and GetModuleFileName correctly retrieve information about windows and modules in the calling process. GetWindowModuleFileName 和 GetModuleFileName 在调用进程中正确检索有关窗口和模块的信息。 In Windows 95 and 98, they return information about windows and modules in other processes.在 Windows 95 和 98 中,它们返回有关其他进程中的窗口和模块的信息。 However, in Windows NT 4.0 and Windows 2000, since module handles are no longer shared by all processes as they were on Windows 95 and 98, these APIs do not return information about windows and modules in other processes.但是,在 Windows NT 4.0 和 Windows 2000 中,由于模块句柄不再像在 Windows 95 和 98 上那样由所有进程共享,因此这些 API 不会返回有关其他进程中的窗口和模块的信息。

To get more information on Windows 2000, use the Process Status Helper set of APIs (known as PSAPI, see Psapi.h include file), available since Windows NT 4.0.要获得有关 Windows 2000 的更多信息,请使用自 Windows NT 4.0 起可用的进程状态帮助程序 API 集(称为 PSAPI,请参阅 Psapi.h 包含文件)。 APIs such as GetModuleFileNameEx and GetModuleBaseName offer equivalent functionality. GetModuleFileNameEx 和 GetModuleBaseName 等 API 提供了等效的功能。

Try using GetModuleFileNameEx instead.尝试改用GetModuleFileNameEx

http://support.microsoft.com/?id=228469 ( archive.org link ) http://support.microsoft.com/?id=228469(archive.org 链接

The executive summary is, GetWindowModuleFileName() doesn't work for windows in other processes in NT-based Windows.执行摘要是, GetWindowModuleFileName()不适用于基于 NT 的 Windows 中其他进程中的窗口。

Instead, you can use QueryFullProcessImageName() once you have a handle to the process.相反,一旦您拥有进程的句柄,就可以使用QueryFullProcessImageName() You can get a handle to the process with OpenProcess() , which you can use once you have a process id.您可以使用OpenProcess()获取进程的句柄,一旦有了进程 ID,就可以使用它。 You can get the process id from the HWND by using GetWindowThreadProcessId()您可以使用GetWindowThreadProcessId()从 HWND 获取进程 ID

This is an example of how get the name of executable that creates window, hope it can give you some ideas about:这是一个如何获取创建窗口的可执行文件名称的示例,希望它能给您一些想法:

    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;
                    }
                }
            }
        }
    }

To use GetModuleFileNameEx() you probably will need to set linker settings to link library psapi.要使用 GetModuleFileNameEx(),您可能需要将链接器设置设置为链接库 psapi。 Also include psapi.h.还包括 psapi.h。

Well according to the MSDN page for GetWindowModuleFileName you appear to be calling it correctly, and if your executable is located in the the root of C: it is returning the correct value:好吧,根据GetWindowModuleFileNameMSDN 页面,您似乎正确调用了它,并且如果您的可执行文件位于 C: 的根目录中,它将返回正确的值:

The GetWindowModuleFileName function retrieves the full path and file name of the module associated with the specified window handle. GetWindowModuleFileName 函数检索与指定窗口句柄关联的模块的完整路径和文件名。

What are you expecting to get back?你期待什么回来?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM