0

I often launch "background scripts" from my PHP CLI scripts. That is, a cmd.exe window starting minimized (grouped).

However, I sometimes want to programmatically "bring it to the front", for example when it has been running for a long time and finally finishes. I'm uninterested in seeing it all the time -- only when it's finished. So I need to be able to run some kind of shell_exec() command from the PHP CLI script to bring its window to the front on demand.

Is this possible? I ask primarily for Windows, but since I'm trying to make everything I do platform-independent to the furthest possible extent, I would love to hear an answer which works for "the big three" (Windows, Mac, Linux).

1 Answer 1

0

Window management is very platform-dependent.

Related to that, the console window in most platforms doesn't actually belong to your PHP script – it is a separate program as far as the window management APIs care.

(Note also that on Windows, it is not a cmd.exe window – it is a "Windows console" window, drawn by either CSRSS on old systems or Conhost on modern systems. And as Conhost is a system-level component, it's possible you will be unable to control it at all.)

There are API libraries for portably creating and drawing own windows (e.g. SDL for games), but most of them do not include managing windows belonging to other programs. So no matter what, you'll end up using platform-specific tricks. (In fact on Linux with the new Wayland graphics system there is simply no way to manage windows belonging to other programs, so you better switch back to X11 if you need this.)

  • For Windows, something like NirCmd would work: it seems it has a win focus subcommand.

  • For Linux with X11, possibly wmctrl or xdotool.

(I would actually prefer PHP's FFI module for directly calling the system APIs, as then the script doesn't depend on any external tools, but it's certainly a lot more code than shell_exec'ing a prepared program, and unfortunately FFI will only become available in the next PHP release.)


That said, bringing windows to front unasked is usually poor user experience. Most window systems have a different feature – they allow a window to mark itself as "urgent" or "needing attention".

Again, I'm not sure if this is possible on Windows consoles at all, but on Linux and macOS it might be as simple as outputting an ASCII "bell" character to the terminal: either just echo "\b"; or maybe a more reliable fwrite(STDERR, "\b"); fflush(STDERR);. The original purpose of ASCII BEL was to draw the operator's attention, and so most terminal emulators themselves translate it to an "needs attention" flag.

1
  • Nircmd is not very easy in this situation. I just went down that hole. You have to give the window class name, which would match multiple windows in a multiple-CLI-window situation and/or require you to fetch information about the current window. A simple "grab-focus.exe" / "bring-this-window-to-topmost-position.exe" type program would be awesome. It's such a simple thing I'm surprised one doesn't exist already and that people are having to homebrew a solution.
    – ClioCJS
    Commented Oct 17, 2022 at 14:50

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .