开发者

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

The error is: e.g:

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.开发者_如何学Pythonexe 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

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.

You have to do the following:

  1. Retrieve the window's process with GetWindowThreadProcessId.
  2. Open the process with PROCESS_QUERY_INFORMATION and PROCESS_VM_READ access rights using OpenProcess.
  3. Use GetModuleFileNameEx on the process handle.

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. The module handle can then be passed to the aforementioned 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.

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

GetWindowModuleFileName and GetModuleFileName correctly retrieve information about windows and modules in the calling process. In Windows 95 and 98, they return information about windows and modules in other processes. 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.

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. APIs such as GetModuleFileNameEx and GetModuleBaseName offer equivalent functionality.

Try using GetModuleFileNameEx instead.


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

The executive summary is, GetWindowModuleFileName() doesn't work for windows in other processes in NT-based Windows.

Instead, you can use QueryFullProcessImageName() once you have a handle to the process. You can get a handle to the process with OpenProcess(), which you can use once you have a process id. You can get the process id from the HWND by using GetWindowThreadProcessId()


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. Also include psapi.h.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜