How to find window handle from exe file's name
Asked Answered
H

1

6

Imagine I have Firefox and I open Firefox Start Page, then I should have a Window with the title: "Mozilla Firefox Start Page - Mozilla Firefox".

I can find window handle with the code below

HWND hwnd = ::FindWindow(0, _T("Mozilla Firefox Start Page - Mozilla Firefox"));

But what I want is find window handle from the window's exe file's name like this

HWND hwnd = FindWindowFromExe(_T("firefox.exe"));//How to make this function?

Does windows Api has a function like FindWindowFromExe()? If it doesn't, what is the best way to Find window from its exe?

Thanks for reading :)

Hounding answered 23/12, 2016 at 0:50 Comment(21)
What does a search of MSDN tell you about the existence of functions starting with FindWindow?Thermostatics
It should be possible to enumerate all open windows from a running process, with enough privileges. But getting just a single window from an "exe file" is not possible. (Case in point: What if the process have multiple windows open? Also, you do know a program can be loaded multiple times?) This comment also contains a couple of hints: About running processes and about enumerating.Freetown
Here is a post that shows you how to do this using the WinAPI. It's Delphi code, but the API calls used work in C++ as well.Thermostatics
@Some programmer dude : There is nothing to worry about multiple windows can be opened with an exe file - because there can be multiple windows with the same title name, for example: "Untitled - Notepad", and I have tested to get the windows handle with ::FindWindow(0, _T("Untitled - Notepad")); , and it get the top-level window. Anyway, I have read about the ideal get all windows process and compare name, but I wonder if window api support get from exe name.Hounding
it get the top level window. No, it doesn't. It gets whichever one it happens to find first, which may or may not have been the first one opened. Have you looked at the post I linked, which shows you how to get a window handle from an executable name?Thermostatics
You are ignoring the fact, that FindWindow takes two arguments. The first one is the window class. That should be sufficient to identify the window you are looking for. Firefox uses "MozillaWindowClass" as its class name. If you want to be extra sure, you can then call GetWindowThreadProcessId, and call GetModuleFileNameEx to find its primary module.Indiscretion
no such api. you can get the list of all running processes/threads in system. found process in this list by name. for all it's threads - call EnumThreadWindowsRoselani
@RbMm: There is usually fewer windows running than process threads, so it would usually be faster and less overhead to enumerate the running windows directly and resolve their process names, than to enumerate all processes and all of their threads and all of their windows.Chanteuse
@RemyLebeau - really we not need call EnumThreadWindows for all threads in system, but only in target process (filtered by name). so already - " fewer windows running in single process" not true. also may be enough enumerate windows only for first thread in process - this is depended from final OP goalRoselani
@RbMm: You cannot make any assumptions about which threads in a process host a GUI. There can be multiple threads that do, and there really is nothing special about the primary thread. In fact, it may already be gone by the time your code runs.Indiscretion
@Indiscretion - yes, this is true. but here depended from final OP goal. this is some util ? in this case need enumerate all threads in process. or here search for some known app window ? most known app create self main gui in first threadRoselani
@RbMm: Even if you do know the application, there's no way for you to control the environment. It may run on a system, that has a global CBT hook installed, thereby injecting modules that create threads, or - God forbid - has an AppInit_DLLs registry key. At the end of the day, you cannot make any assumptions.Indiscretion
@Indiscretion - and how global CBT or AppInit_DLLs related to in which thread will bu run GUI ?Roselani
@RbMm: An injected thread can create windows just as well. It may do the right thing and create a message-only window, that won't be discovered by EnumThreadWindows(I think). But it may also decide to create a hidden top-level window. This is common for injected threads, because they may need to know, when the user logs off.Indiscretion
@Indiscretion - yes, true. how I and say at begin - in general case we need enumerate windows for all threads in process (but not in all threads in system). but - what is final OP goal ? for what him this functional at all ? for what he search ? depended from this answer - in some case (say he interesting in firefox for example only top window) - first thread is enoughRoselani
@RbMm: No, it isn't. And I have tried my best to explain, why being clever isn't going to produce a sufficiently stable solution. You just re-iterated your first comment, which I already exposed as being a suggestion to rely on the unreliable. Just in case you have missed it: You do not control the environment in which the known firefox.exe runs.Indiscretion
@Indiscretion - firefox create self gui in first thread in process - in any environment.Roselani
@RbMm: Yes, maybe. Maybe it does today. But the latest nightly build may just decide to change this. Why are you trying to be clever, without any conceivable benefit? What is the advantage of writing code, that you know can fail, either in the future (or with a previous release even), or on a system with an unexpected environment?Indiscretion
@Indiscretion - yes, may be all. but again - I say at begin - in general case we need enumerate windows for all threads in process. but can you say - what is OP final goal ? for what him FindWindowFromExe() function ?Roselani
@RbMm: The OP's final goal is to have code, that works reliably. The OP's final goal is not to have some clever implementation, that sometimes fails, without providing any benefit over a solution that will always work. Can we stop this now?Indiscretion
@Indiscretion - yes, we right in allRoselani
C
14

There is no single API function to find a window by its owning process's file name. You will have to search for it manually.

You can use EnumWindows() to enumerate all top-level windows, or use FindWindow()/FindWindowEx() to find/enumerate specific types of windows.

For each window, you can either:

or

  • use GetWindowModuleFileName() to query the window for the full path and filename of the module that created it (assuming the intended window is created by an actual EXE and not a DLL used by an EXE).

Once you have the window's filename, you can then compare that to your target filename.

Chanteuse answered 23/12, 2016 at 3:5 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.