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 :)

123iamking
  • 2,387
  • 4
  • 36
  • 56
  • What does a search of [MSDN](http://msdn.microsoft.com) tell you about the existence of functions starting with `FindWindow`? – Ken White Dec 23 '16 at 00:53
  • 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 process**es*** and about *enumerating*. – Some programmer dude Dec 23 '16 at 00:55
  • [Here is a post](http://stackoverflow.com/q/6806911/62576) that shows you how to do this using the WinAPI. It's Delphi code, but the API calls used work in C++ as well. – Ken White Dec 23 '16 at 00:59
  • @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. – 123iamking Dec 23 '16 at 01:10
  • *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? – Ken White Dec 23 '16 at 01:18
  • You are ignoring the fact, that [FindWindow](https://msdn.microsoft.com/en-us/library/windows/desktop/ms633499.aspx) 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](https://msdn.microsoft.com/en-us/library/windows/desktop/ms633522.aspx), and call `GetModuleFileNameEx` to find its primary module. – IInspectable Dec 23 '16 at 01:25
  • 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 `EnumThreadWindows` – RbMm Dec 23 '16 at 01:44
  • 2
    @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. – Remy Lebeau Dec 23 '16 at 03:13
  • @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 goal – RbMm Dec 23 '16 at 12:26
  • @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. – IInspectable Dec 24 '16 at 11:14
  • @IInspectable - 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 thread – RbMm Dec 24 '16 at 14:31
  • @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. – IInspectable Dec 24 '16 at 14:41
  • @IInspectable - and how global CBT or AppInit_DLLs related to in which thread will bu run GUI ? – RbMm Dec 24 '16 at 14:49
  • @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. – IInspectable Dec 24 '16 at 14:56
  • @IInspectable - 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 enough – RbMm Dec 24 '16 at 14:59
  • @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. – IInspectable Dec 24 '16 at 15:02
  • @IInspectable - firefox create self gui in first thread in process - in any environment. – RbMm Dec 24 '16 at 15:08
  • @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? – IInspectable Dec 24 '16 at 15:12
  • @IInspectable - 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 ? – RbMm Dec 24 '16 at 15:15
  • @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? – IInspectable Dec 24 '16 at 15:16
  • @IInspectable - yes, we right in all – RbMm Dec 24 '16 at 15:18

1 Answers1

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.

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770