From 11c2d12cfcabdecfaf00077ba3b1ef7cc01a081c Mon Sep 17 00:00:00 2001 From: Zackery Spytz Date: Thu, 18 Jun 2020 23:51:36 -0600 Subject: [PATCH 1/3] bpo-40851: Don't set wShowWindow if startupinfo has STARTF_USESHOWWINDOW --- Lib/subprocess.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Lib/subprocess.py b/Lib/subprocess.py index a14fede00c391c..d38cc756ec479f 100644 --- a/Lib/subprocess.py +++ b/Lib/subprocess.py @@ -1688,8 +1688,9 @@ def _execute_child(self, args, executable, preexec_fn, close_fds, close_fds = False if shell: - startupinfo.dwFlags |= _winapi.STARTF_USESHOWWINDOW - startupinfo.wShowWindow = _winapi.SW_HIDE + if not startupinfo.dwFlags & _winapi.STARTF_USESHOWWINDOW: + startupinfo.dwFlags |= _winapi.STARTF_USESHOWWINDOW + startupinfo.wShowWindow = _winapi.SW_HIDE if not executable: # gh-101283: without a fully-qualified path, before Windows # checks the system directories, it first looks in the From 406227a1a8f16f379b783409839987dd69560f82 Mon Sep 17 00:00:00 2001 From: Zackery Spytz Date: Fri, 19 Jun 2020 00:15:13 -0600 Subject: [PATCH 2/3] News --- .../next/Windows/2020-06-19-00-14-52.bpo-40851.0-3EJP.rst | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 Misc/NEWS.d/next/Windows/2020-06-19-00-14-52.bpo-40851.0-3EJP.rst diff --git a/Misc/NEWS.d/next/Windows/2020-06-19-00-14-52.bpo-40851.0-3EJP.rst b/Misc/NEWS.d/next/Windows/2020-06-19-00-14-52.bpo-40851.0-3EJP.rst new file mode 100644 index 00000000000000..15bd647c73d53b --- /dev/null +++ b/Misc/NEWS.d/next/Windows/2020-06-19-00-14-52.bpo-40851.0-3EJP.rst @@ -0,0 +1,2 @@ +On Windows, :class:`subprocess.Popen` no longer sets ``wShowWindow`` if the +``startupinfo`` argument has the flag ``STARTF_USESHOWWINDOW``. From 377f67b64638d462f15aa8d777477e586f41101e Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Sun, 9 Aug 2026 21:32:54 +0300 Subject: [PATCH 3/3] Add a test and describe the NEWS entry in terms of user visible effects --- Lib/test/test_subprocess.py | 28 +++++++++++++++++++ .../2020-06-19-00-14-52.bpo-40851.0-3EJP.rst | 5 ++-- 2 files changed, 31 insertions(+), 2 deletions(-) diff --git a/Lib/test/test_subprocess.py b/Lib/test/test_subprocess.py index d1840e97d0f2f7..4cea07b3d2c774 100644 --- a/Lib/test/test_subprocess.py +++ b/Lib/test/test_subprocess.py @@ -3777,6 +3777,34 @@ def test_startupinfo_copy(self): self.assertEqual(startupinfo.wShowWindow, subprocess.SW_HIDE) self.assertEqual(startupinfo.lpAttributeList, {"handle_list": []}) + def test_startupinfo_shell_show_window(self): + # gh-85028: shell=True must not override wShowWindow set by the caller + import _winapi + SW_MAXIMIZE = 3 + used = [] + create_process = _winapi.CreateProcess + + def spy(*args): + # The startup info is the last argument of CreateProcess() + used.append(args[-1]) + return create_process(*args) + + startupinfo = subprocess.STARTUPINFO( + dwFlags=subprocess.STARTF_USESHOWWINDOW, + wShowWindow=SW_MAXIMIZE) + with mock.patch.object(_winapi, 'CreateProcess', spy): + rc = subprocess.call(ZERO_RETURN_CMD, shell=True, + startupinfo=startupinfo) + self.assertEqual(rc, 0) + rc = subprocess.call(ZERO_RETURN_CMD, shell=True) + self.assertEqual(rc, 0) + + requested, default = used + self.assertEqual(requested.wShowWindow, SW_MAXIMIZE) + # Without STARTF_USESHOWWINDOW the shell window is still hidden. + self.assertTrue(default.dwFlags & subprocess.STARTF_USESHOWWINDOW) + self.assertEqual(default.wShowWindow, subprocess.SW_HIDE) + # CREATE_NEW_CONSOLE creates a "popup" window. @support.requires_resource('gui') def test_creationflags(self): diff --git a/Misc/NEWS.d/next/Windows/2020-06-19-00-14-52.bpo-40851.0-3EJP.rst b/Misc/NEWS.d/next/Windows/2020-06-19-00-14-52.bpo-40851.0-3EJP.rst index 15bd647c73d53b..70f5efad398b03 100644 --- a/Misc/NEWS.d/next/Windows/2020-06-19-00-14-52.bpo-40851.0-3EJP.rst +++ b/Misc/NEWS.d/next/Windows/2020-06-19-00-14-52.bpo-40851.0-3EJP.rst @@ -1,2 +1,3 @@ -On Windows, :class:`subprocess.Popen` no longer sets ``wShowWindow`` if the -``startupinfo`` argument has the flag ``STARTF_USESHOWWINDOW``. +:class:`subprocess.Popen` with ``shell=True`` on Windows now honors +``wShowWindow`` of the *startupinfo* argument, so the console window of the +started program can be shown. Previously it was always hidden.