我尝试获取所有已启动窗口的可执行文件名称,我的问题是:
我使用方法
UINT GetWindowModuleFileName(
HWND hwnd,
LPTSTR lpszFileName,
UINT cchFileNameMax);
我不明白为什么它不起作用。
我对一个窗口的数据是:
-HWND AND PROCESSID
错误是: 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
注意:test.exe是我的可执行文件的名称,但它不是Notepad ++的完整路径...而且这也是Mozilla Thunderbird的原因......我不明白为什么
我使用这样的功能:
char filenameBuffer[4000];
if (GetWindowModuleFileName(hWnd, filenameBuffer, 4000) > 0)
{
std::cout << "GetWindowModuleFileName(): " << filenameBuffer << std::endl;
}
感谢您的回复。
答案 0 :(得分:19)
GetWindowModuleFileName(...)
函数仅适用于当前流程中的窗口。1
您必须执行以下操作:
GetWindowThreadProcessId
检索窗口的过程。OpenProcess
打开包含PROCESS_QUERY_INFORMATION和PROCESS_VM_READ访问权限的流程。GetModuleFileNameEx
。如果您确实想要获取用于注册窗口的模块的名称(而不是进程可执行文件),则可以使用带有GWLP_HINSTANCE的GetWindowLongPtr
获取模块句柄。然后可以将模块句柄传递给前面提到的GetModuleFileNameEx
。
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);
答案 1 :(得分:3)
啊哈。我在底部阅读了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年,使用Process Status Helper 一组API(称为PSAPI,请参阅 Psapi.h包含文件),可用 Windows NT 4.0。 API等 GetModuleFileNameEx和 GetModuleBaseName提供等价物 功能。
请尝试使用GetModuleFileNameEx。
答案 2 :(得分:2)
http://support.microsoft.com/?id=228469
执行摘要是,GetWindowModuleFileName不适用于基于NT的Windows中其他进程中的窗口。
相反,一旦掌握了流程,就可以使用QueryFullProcessImageName。您可以使用OpenProcess获取流程句柄,一旦您拥有流程ID,就可以使用该句柄。您可以使用GetWindowThreadProcessId
从HWND获取进程ID答案 3 :(得分:1)
根据GetWindowModuleFileName
{{1}}您似乎正确调用它,如果您的可执行文件位于C的根目录中,它将返回正确的值:
GetWindowModuleFileName函数检索与指定窗口句柄关联的模块的完整路径和文件名。
你有什么期望回来的?
答案 4 :(得分:1)
这是一个如何获取创建窗口的可执行文件名称的示例,希望它可以为您提供一些想法:
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。