This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

Title: Subprocesses created with DETACHED_PROCESS can pop up a console window
Type: behavior Stage:
Components: Windows Versions: Python 3.8
Status: open Resolution:
Dependencies: Superseder:
Assigned To: Nosy List: Bernat Gabor, eryksun, paul.moore, steve.dower, tim.golden, zach.ware
Priority: normal Keywords:

Created on 2020-08-23 12:54 by paul.moore, last changed 2022-04-11 14:59 by admin.

Messages (5)
msg375811 - (view) Author: Paul Moore (paul.moore) * (Python committer) Date: 2020-08-23 12:54
The following code pops up an extra console window when run on Windows 10, Python 3.8:

    from subprocess import DETACHED_PROCESS, Popen
    p = Popen(["py", "-c", "from time import sleep; sleep(5)"], creationflags=DETACHED_PROCESS)

Adding CREATE_NO_WINDOW doesn't help, nor does adding a STARTUPINFO with SW_HIDE.

The problem occurs whether the Python interpreter is started via the py.exe wrapper or the actual python.exe. However, changing the process being run from "py" to sys.executable makes the problem go away. I've seen similar issues when using sys.executable, but the script is being called from a virtualenv.

I can't find any set of options for Popen that reliably avoids showing a console window when invoked like this.
msg375812 - (view) Author: Paul Moore (paul.moore) * (Python committer) Date: 2020-08-23 13:00
Originally discovered in - see that issue for more context.
msg375814 - (view) Author: Eryk Sun (eryksun) * (Python triager) Date: 2020-08-23 14:14
Creating the py.exe process with creationflags=DETACHED_PROCESS sets a special ConsoleHandle value in its ProcessParameters that makes the base API skip allocating a console session at process startup. However, the launcher itself spawns python.exe normally, without the DETACHED_PROCESS flag. So the base API in the python.exe process allocates a new console session that creates a window.

Using creationflags=CREATE_NO_WINDOW resolves the problem. This flag makes the base API in the py.exe process allocate a new console session that doesn't create a window. The child python.exe process inherits this windowless console session. Note that CREATE_NO_WINDOW is ignored if combined with CREATE_NEW_CONSOLE or DETACHED_PROCESS, since the combination makes no sense.

You can also use creationflags=CREATE_NEW_CONSOLE with startupinfo=STARTUPINFO(dwFlags=STARTF_USESHOWWINDOW), in which case py.exe allocates a console session with a hidden window. This option is useful if a console application should be able to show the console window later on via ShowWindow(GetConsoleWindow(), SW_SHOW). With CREATE_NO_WINDOW, in contrast, there is no window to show.

It should work if creationflags=DETACHED_PROCESS is combined with startupinfo=STARTUPINFO(dwFlags=STARTF_USESHOWWINDOW) because the launcher is supposed to clone its startup information to the child python.exe process, including dwFlags. But there's a bug in run_child in PC/launcher.c. It sets si.dwFlags to STARTF_USESTDHANDLES instead of using a bitwise OR to set the flag value.
msg375816 - (view) Author: Paul Moore (paul.moore) * (Python committer) Date: 2020-08-23 14:42
Confirmed, CREATE_NO_WINDOW works - in my test I used it *with* DETACHED_PROCESS.

Is it not a bug that the launcher doesn't respect the value of DETACHED_PROCESS when calling the Python interpreter, though? If nothing else, it means that there are differences between running Python via the launcher and not doing so (which are also evident as differences between a virtual environment and a non-virtual interpreter, as the venv machinery uses the launcher internally).
msg375817 - (view) Author: Eryk Sun (eryksun) * (Python triager) Date: 2020-08-23 15:06
I suppose that, in addition to fixing the bug with si.dwFlags, code could be added to use DETACHED_PROCESS if GetConsoleCP() returns 0 (i.e. the launcher isn't attached to a console).
Date User Action Args
2022-04-11 14:59:35adminsetgithub: 85785
2020-08-23 15:06:02eryksunsetmessages: + msg375817
2020-08-23 14:42:15paul.mooresetmessages: + msg375816
2020-08-23 14:14:32eryksunsetnosy: + eryksun
messages: + msg375814
2020-08-23 13:26:15Bernat Gaborsetnosy: + Bernat Gabor
2020-08-23 13:00:22paul.mooresetmessages: + msg375812
2020-08-23 12:54:10paul.moorecreate