1

I am starting a program using subprocess like:

import subprocess
subprocess.call('myprogram.exe')

I am having a machine with several monitors and want to know if it is possible to force it on a specific monitor under windows 10 using Python?

Kev1n91
  • 3,553
  • 8
  • 46
  • 96
  • No, because there is no way for *any* method to open a process on a specific monitor. See [Launch an application and send it to second monitor?](//stackoverflow.com/q/3750113) for work-arounds. – Martijn Pieters May 14 '18 at 08:57
  • The linked question does not specify the language, I wanted to know if it possible using Python - however, the accepted answer uses a C++ API – Kev1n91 May 14 '18 at 09:06
  • The linked question does specify the language, it's C#, and the API used is the Windows APIs. You can use the same APIs from Python, with the `ctypes` module. The point is that *you can't do what you want with `subprocess`*, you need to do this after the process has started and then move the window using the windows APIs. – Martijn Pieters May 14 '18 at 09:11
  • @MartijnPieters, that's not strictly true, but in practice it's usually true. The default monitor and window position can be passed in `STARTUPINFO`. But most programs will ignore this and instead create their windows in the locations remembered from the previous time the program ran. – Eryk Sun May 14 '18 at 22:22
  • The most documented way is via [`ShellExecuteEx`](https://msdn.microsoft.com/en-us/library/bb759784), which allows passing a monitor handle (e.g. determined from `EnumDisplayMonitors`) in the `hMonitor` field when `fMask` contains `SEE_MASK_HMONITOR`. – Eryk Sun May 14 '18 at 22:24
  • Usually the shell API just calls base `CreateProcess` for this, but how to pass a monitor handle in [`STARTUPINFO`](https://msdn.microsoft.com/en-us/library/ms686331) is only partly documented. It gets passed in `hStdOutput`, and `dwFlags` should contain the undocumented flag value `STARTF_HASSHELLDATA` (0x00000400). If this can work at all with the program (unlikely as that is), then in Python you can use `si = subprocess.STARTUPINFO()`; set `si.dwFlags = 0x400` and set `si.hStdOutput` to the monitor handle. Then pass this to `subprocess.Popen` as `startupinfo=si`. – Eryk Sun May 14 '18 at 22:28
  • @eryksun: interesting, there is *very little information* on that, certainly outside of your comments. A google on `STARTF_HASSHELLDATA process window` gives 10 results, none of them remotely helpful on this subject. – Martijn Pieters May 15 '18 at 11:21
  • @MartijnPieters, this functionality is well-documented and known for `ShellExecuteEx`. I discovered the 0x400 flag value from inspecting the `STARTUPINFO` that `ShellExecuteEx` passes to `CreateProcess`. The site [Undocumented CreateProcess](https://web.archive.org/web/20171015190332/http://www.catch22.net/tuts/undocumented-createprocess) explains in more detail. The author calls the flag `STARTF_MONITOR`. Probably a better name, would be `STARTF_HASHMONITOR`. – Eryk Sun May 15 '18 at 22:17
  • Note that both `STARTF_ HASHMONITOR` (or whatever name you prefer) and `STARTF_USEHOTKEY` (documented to use `hStdInput`) cannot be used with `STARTF_USESTDHANDLES`. This means that these two features are incompatible with explicit standard-handle inheritance. They only work with implicit standard-handle inheritance (i.e. inherited directly from the parent's `ProcessParameters`, not via `STARTUPINFO`), as is enabled by default for console applications only. – Eryk Sun May 15 '18 at 22:19
  • @eryksun: sounds like you could answer the duplicate post with some great insights. – Martijn Pieters May 16 '18 at 10:08

0 Answers0