The primary goal of this report is to verify that on Windows, running pythonw.exe or GUI-subsystem scripts does not open a Console or Terminal window. This is the fundamental contract of the GUI subsystem: GUI applications should launch silently without flashing a console window, even briefly.
Python Launch Lab systematically tests every common way to start a Python process on Windows — the standard python.exe / pythonw.exe interpreters, the uv tool runner (uv run, uvx, uvw), virtual-environment entry-point wrappers generated by pip or uv, and the custom pyshim-win GUI-subsystem shim — and records whether each launcher creates a console window, a GUI window, or neither.
The key questions this report answers:
conhost.exe) for the process? Console (CUI) executables do this by default; GUI executables should not.CUI (console) or GUI (graphical) in its Portable Executable header? This determines the Windows loader’s default behaviour.Rows highlighted in orange indicate anomalies — cases where observed behaviour differs from what the PE subsystem and scenario type predict (e.g. a GUI-subsystem launcher unexpectedly allocating a console window). Expand an anomaly row to see a detailed explanation of what went wrong and why.
Related upstream issues & background:
uv run --script GUI scripts open a console windowCREATE_NO_WINDOWThe custom uv fork builds tested in this report include targeted fixes for two long-standing Windows GUI launcher issues. The sections below summarise the root causes and the corresponding pull-request fixes.
pythonw.exe venv launcher using console instead of GUI subsystemProblem: When uv created a virtual environment, the pythonw.exe wrapper inside .venv/Scripts/ was stamped with the CUI (console) PE subsystem instead of GUI. This caused Windows to allocate a visible console window every time pythonw.exe was invoked from the venv — defeating the entire purpose of the “windowless” interpreter.
Root cause: The trampoline executable that uv embeds as the venv pythonw.exe was compiled with the default console subsystem. The PE header’s IMAGE_OPTIONAL_HEADER.Subsystem field was set to IMAGE_SUBSYSTEM_WINDOWS_CUI (3) instead of IMAGE_SUBSYSTEM_WINDOWS_GUI (2).
Fix: The build configuration for the pythonw.exe trampoline was updated so that its PE subsystem is GUI. With this change, .venv/Scripts/pythonw.exe launches without creating a console window, matching the behaviour of CPython’s own pythonw.exe.
CREATE_NO_WINDOW in trampoline for GUI launchersProblem: Even after ensuring a GUI-subsystem PE header, entry-point scripts installed via pip install or uv pip install with gui_scripts still flashed a console window on startup. The Rust-based trampoline used by uv to launch these scripts spawned the Python interpreter as a child process without the CREATE_NO_WINDOW creation flag.
Root cause: The trampoline called CreateProcessW with dwCreationFlags = 0. On Windows, when a GUI-subsystem process spawns a CUI child (such as python.exe), the default behaviour is to allocate a new console for that child. Without CREATE_NO_WINDOW (0x08000000), the child inherits a freshly-created console window, causing the visible flash.
Fix: The trampoline’s CreateProcessW call was updated to pass CREATE_NO_WINDOW in dwCreationFlags when the launcher is a GUI-subsystem executable. This tells Windows to run the child process without allocating or displaying a console, eliminating the flash entirely.
This report includes results from multiple uv builds run side by side. The table below identifies each version tested and where it came from. Use the uv Version column filter in the results table to compare behaviour across builds.
| uv Version | Source | Version Hash | Scenarios |
|---|---|---|---|
uv 0.10.12 (00d72dac7 2026-03-19 x86_64-pc-windows-msvc) |
Official release (astral-sh/uv) | d2fe205b6d |
20 |
uv 0.10.9 (a941e51c8 2026-03-15) |
Custom build (joelvaneenwyk/uv fork) | 25a90a6db0 |
20 |
The results indicate that most launch scenarios behave as expected, with correct handling of `python.exe` and `pythonw.exe` across various configurations. However, three key anomalies are observed, all related to `venv` entry points. For the `venv-pythonw-script-py` scenario, the PE subsystem is incorrectly marked as "CUI" instead of "GUI," causing an unexpected console window to appearβthis suggests an issue where the `pythonw.exe` wrapper inside `venv-direct` is a Console Subsystem (CUI) rather than a Windows GUI Subsystem executable. This aligns with the problem addressed by PR #2 in the joelvaneenwyk/uv custom fork, which fixed incorrect `pythonw.exe` PE subsystem flags for virtual environments. The anomaly persists in the official `uv` release (`uv 0.10.9` and `uv 0.10.12`), while the fork's improved PE subsystem handling likely resolves it.
Two additional anomalies occur in the `venv-dual-gui-entrypoint` and `venv-gui-entrypoint` scenarios in the official `uv` builds. In those cases, the GUI entry-point execution results in an `Exit Code` of `1` instead of the expected `0`, and although a visible window appears as expected, it seems the executable fails to run properly. This behavior points to a regression introduced in the official `uv` builds when dealing with GUI executables. PR #3 in the custom fork addresses related issues by implementing the `CREATE_NO_WINDOW` flag for GUI subsystem launchers, potentially resolving the console subsystem issues. Therefore, the anomalies in `venv-pythonw-script-py` and GUI entry-point failures are likely resolved in the joelvaneenwyk/uv fork but remain unfixed in the official release.
| Scenario β | Status β | Platform β | uv Version β | Launcher β | Command Line β | Exit Code β | PE Subsystem β | Console Window β | Application Window β | stdout β | stderr β |
|---|---|---|---|---|---|---|---|---|---|---|---|
| python-script-py | β OK | win32 | uv 0.10.12 (00d72dac7 2026-03-19 x86_64-pc-windows-msvc) | python | python fixtures/raw_py/hello.py | 0 | CUI | Yes | No | Yes | No |
| python-script-pyw | β OK | win32 | uv 0.10.12 (00d72dac7 2026-03-19 x86_64-pc-windows-msvc) | python | python fixtures/raw_pyw/hello.pyw | 0 | CUI | Yes | No | No | No |
| pythonw-script-py | β OK | win32 | uv 0.10.12 (00d72dac7 2026-03-19 x86_64-pc-windows-msvc) | pythonw | pythonw fixtures/raw_py/hello.py | 0 | GUI | No | No | Yes | No |
| pythonw-script-pyw | β OK | win32 | uv 0.10.12 (00d72dac7 2026-03-19 x86_64-pc-windows-msvc) | pythonw | pythonw fixtures/raw_pyw/hello.pyw | 0 | GUI | No | No | No | No |
| shim-python-script-py | β OK | win32 | uv 0.10.12 (00d72dac7 2026-03-19 x86_64-pc-windows-msvc) | pyshim-win | D:\a\py-launch-lab\py-launch-lab\crates\pyshim-win\target\release\pyshim-win.exe --hide-console -- python fixtures/raw_py/hello.py | 0 | GUI | No | No | Yes | No |
| shim-uv-run-script-py | β OK | win32 | uv 0.10.12 (00d72dac7 2026-03-19 x86_64-pc-windows-msvc) | pyshim-win | D:\a\py-launch-lab\py-launch-lab\crates\pyshim-win\target\release\pyshim-win.exe --hide-console -- uv run fixtures/raw_py/hello.py | 0 | GUI | No | No | Yes | No |
| uv-run-gui-script | β OK | win32 | uv 0.10.12 (00d72dac7 2026-03-19 x86_64-pc-windows-msvc) | uv | uv run --gui-script fixtures/raw_py/hello.py | 0 | CUI | Yes | No | Yes | No |
| uv-run-script-py | β OK | win32 | uv 0.10.12 (00d72dac7 2026-03-19 x86_64-pc-windows-msvc) | uv | uv run fixtures/raw_py/hello.py | 0 | CUI | Yes | No | Yes | No |
| uv-run-script-pyw | β OK | win32 | uv 0.10.12 (00d72dac7 2026-03-19 x86_64-pc-windows-msvc) | uv | uv run fixtures/raw_pyw/hello.pyw | 0 | CUI | Yes | No | No | No |
| uv-tool-install-console | β OK | win32 | uv 0.10.12 (00d72dac7 2026-03-19 x86_64-pc-windows-msvc) | uv | uv tool install --editable fixtures/pkg_console | 0 | CUI | Yes | No | No | Yes |
| uv-tool-install-gui | β OK | win32 | uv 0.10.12 (00d72dac7 2026-03-19 x86_64-pc-windows-msvc) | uv | uv tool install --editable fixtures/pkg_gui | 0 | CUI | Yes | No | No | Yes |
| uv-tool-run-pkg-console | β OK | win32 | uv 0.10.12 (00d72dac7 2026-03-19 x86_64-pc-windows-msvc) | uv | uv tool run --from fixtures/pkg_console lab-console | 0 | CUI | Yes | No | Yes | No |
| uvw-run-script-py | β OK | win32 | uv 0.10.12 (00d72dac7 2026-03-19 x86_64-pc-windows-msvc) | uvw | uvw run fixtures/raw_py/hello.py | 0 | GUI | No | No | Yes | No |
| uvx-pkg-console | β OK | win32 | uv 0.10.12 (00d72dac7 2026-03-19 x86_64-pc-windows-msvc) | uvx | uvx --from fixtures/pkg_console lab-console | 0 | CUI | Yes | No | Yes | Yes |
| venv-console-entrypoint | β OK | win32 | uv 0.10.12 (00d72dac7 2026-03-19 x86_64-pc-windows-msvc) | venv-direct | D:\a\py-launch-lab\py-launch-lab\.cache\matrix_venv_d2fe205b6d\Scripts\lab-console.exe | 0 | CUI | Yes | No | Yes | No |
| venv-dual-console-entrypoint | β OK | win32 | uv 0.10.12 (00d72dac7 2026-03-19 x86_64-pc-windows-msvc) | venv-direct | D:\a\py-launch-lab\py-launch-lab\.cache\matrix_venv_d2fe205b6d\Scripts\lab-dual-console.exe | 0 | CUI | Yes | No | Yes | No |
| venv-dual-gui-entrypoint | β 1 anomaly | win32 | uv 0.10.12 (00d72dac7 2026-03-19 x86_64-pc-windows-msvc) | venv-direct | D:\a\py-launch-lab\py-launch-lab\.cache\matrix_venv_d2fe205b6d\Scripts\lab-dual-gui.exe | 1 | GUI | No | No | No | Yes |
β Unexpected behaviour detected:
Exit Code
Expected: 0 β
Actual: 1
Dual-mode package GUI entry-point. The GUI wrapper should NOT create a console window. See KNOWN_DEVIATIONS for current tooling bugs that violate this.
π More details β
| |||||||||||
| venv-gui-entrypoint | β 1 anomaly | win32 | uv 0.10.12 (00d72dac7 2026-03-19 x86_64-pc-windows-msvc) | venv-direct | D:\a\py-launch-lab\py-launch-lab\.cache\matrix_venv_d2fe205b6d\Scripts\lab-window-gui.exe | 1 | GUI | No | Yes | No | Yes |
β Unexpected behaviour detected:
Exit Code
Expected: 0 β
Actual: 1
GUI entry-point wrapper in a venv (pip/uv-generated .exe with GUI subsystem). The wrapper itself is GUI, so Windows should NOT auto-allocate a console for it. The wrapper internally launches the venv's pythonw.exe which should also be a GUI binary. See KNOWN_DEVIATIONS for current tooling bugs that violate this.
π More details β
| |||||||||||
| venv-python-script-py | β OK | win32 | uv 0.10.12 (00d72dac7 2026-03-19 x86_64-pc-windows-msvc) | venv-direct | D:\a\py-launch-lab\py-launch-lab\.cache\matrix_venv_d2fe205b6d\Scripts\python.exe D:\a\py-launch-lab\py-launch-lab\fixtures\raw_py\hello.py | 0 | CUI | Yes | No | Yes | No |
| venv-pythonw-script-py | β 2 anomalies | win32 | uv 0.10.12 (00d72dac7 2026-03-19 x86_64-pc-windows-msvc) | venv-direct | D:\a\py-launch-lab\py-launch-lab\.cache\matrix_venv_d2fe205b6d\Scripts\pythonw.exe D:\a\py-launch-lab\py-launch-lab\fixtures\raw_py\hello.py | 0 | CUI | Yes | No | Yes | No |
β Unexpected behaviour detected:
PE Subsystem
Expected: GUI β
Actual: CUI
Running hello.py via the venv pythonw.exe. On Windows the venv pythonw.exe SHOULD be a GUI-subsystem binary (no console window). This is the ideal behaviour β pythonw.exe must be a true GUI PE binary so that no console window is allocated when it launches. See KNOWN_DEVIATIONS for current tooling bugs that violate this.
π More details β
Console Window
Expected: No β
Actual: Yes
Running hello.py via the venv pythonw.exe. On Windows the venv pythonw.exe SHOULD be a GUI-subsystem binary (no console window). This is the ideal behaviour β pythonw.exe must be a true GUI PE binary so that no console window is allocated when it launches. See KNOWN_DEVIATIONS for current tooling bugs that violate this.
π More details β
| |||||||||||
| python-script-py | β OK | win32 | uv 0.10.9 (a941e51c8 2026-03-15) | python | python fixtures/raw_py/hello.py | 0 | CUI | Yes | No | Yes | No |
| python-script-pyw | β OK | win32 | uv 0.10.9 (a941e51c8 2026-03-15) | python | python fixtures/raw_pyw/hello.pyw | 0 | CUI | Yes | No | No | No |
| pythonw-script-py | β OK | win32 | uv 0.10.9 (a941e51c8 2026-03-15) | pythonw | pythonw fixtures/raw_py/hello.py | 0 | GUI | No | No | Yes | No |
| pythonw-script-pyw | β OK | win32 | uv 0.10.9 (a941e51c8 2026-03-15) | pythonw | pythonw fixtures/raw_pyw/hello.pyw | 0 | GUI | No | No | No | No |
| shim-python-script-py | β OK | win32 | uv 0.10.9 (a941e51c8 2026-03-15) | pyshim-win | D:\a\py-launch-lab\py-launch-lab\crates\pyshim-win\target\release\pyshim-win.exe --hide-console -- python fixtures/raw_py/hello.py | 0 | GUI | No | No | Yes | No |
| shim-uv-run-script-py | β OK | win32 | uv 0.10.9 (a941e51c8 2026-03-15) | pyshim-win | D:\a\py-launch-lab\py-launch-lab\crates\pyshim-win\target\release\pyshim-win.exe --hide-console -- uv run fixtures/raw_py/hello.py | 0 | GUI | No | No | Yes | No |
| uv-run-gui-script | β OK | win32 | uv 0.10.9 (a941e51c8 2026-03-15) | uv | C:\custom-uv-bin\uv.exe run --gui-script fixtures/raw_py/hello.py | 0 | CUI | Yes | No | Yes | No |
| uv-run-script-py | β OK | win32 | uv 0.10.9 (a941e51c8 2026-03-15) | uv | C:\custom-uv-bin\uv.exe run fixtures/raw_py/hello.py | 0 | CUI | Yes | No | Yes | No |
| uv-run-script-pyw | β OK | win32 | uv 0.10.9 (a941e51c8 2026-03-15) | uv | C:\custom-uv-bin\uv.exe run fixtures/raw_pyw/hello.pyw | 0 | CUI | Yes | No | No | No |
| uv-tool-install-console | β OK | win32 | uv 0.10.9 (a941e51c8 2026-03-15) | uv | C:\custom-uv-bin\uv.exe tool install --editable fixtures/pkg_console | 0 | CUI | Yes | No | No | Yes |
| uv-tool-install-gui | β OK | win32 | uv 0.10.9 (a941e51c8 2026-03-15) | uv | C:\custom-uv-bin\uv.exe tool install --editable fixtures/pkg_gui | 0 | CUI | Yes | No | No | Yes |
| uv-tool-run-pkg-console | β OK | win32 | uv 0.10.9 (a941e51c8 2026-03-15) | uv | C:\custom-uv-bin\uv.exe tool run --from fixtures/pkg_console lab-console | 0 | CUI | Yes | No | Yes | No |
| uvw-run-script-py | β OK | win32 | uv 0.10.9 (a941e51c8 2026-03-15) | uvw | C:\custom-uv-bin\uvw.exe run fixtures/raw_py/hello.py | 0 | GUI | No | No | Yes | No |
| uvx-pkg-console | β OK | win32 | uv 0.10.9 (a941e51c8 2026-03-15) | uvx | uvx --from fixtures/pkg_console lab-console | 0 | CUI | Yes | No | Yes | Yes |
| venv-console-entrypoint | β OK | win32 | uv 0.10.9 (a941e51c8 2026-03-15) | venv-direct | D:\a\py-launch-lab\py-launch-lab\.cache\matrix_venv_25a90a6db0\Scripts\lab-console.exe | 0 | CUI | Yes | No | Yes | No |
| venv-dual-console-entrypoint | β OK | win32 | uv 0.10.9 (a941e51c8 2026-03-15) | venv-direct | D:\a\py-launch-lab\py-launch-lab\.cache\matrix_venv_25a90a6db0\Scripts\lab-dual-console.exe | 0 | CUI | Yes | No | Yes | No |
| venv-dual-gui-entrypoint | β OK | win32 | uv 0.10.9 (a941e51c8 2026-03-15) | venv-direct | D:\a\py-launch-lab\py-launch-lab\.cache\matrix_venv_25a90a6db0\Scripts\lab-dual-gui.exe | 0 | GUI | No | No | No | No |
| venv-gui-entrypoint | β OK | win32 | uv 0.10.9 (a941e51c8 2026-03-15) | venv-direct | D:\a\py-launch-lab\py-launch-lab\.cache\matrix_venv_25a90a6db0\Scripts\lab-window-gui.exe | 0 | GUI | No | Yes | No | No |
| venv-python-script-py | β OK | win32 | uv 0.10.9 (a941e51c8 2026-03-15) | venv-direct | D:\a\py-launch-lab\py-launch-lab\.cache\matrix_venv_25a90a6db0\Scripts\python.exe D:\a\py-launch-lab\py-launch-lab\fixtures\raw_py\hello.py | 0 | CUI | Yes | No | Yes | No |
| venv-pythonw-script-py | β OK | win32 | uv 0.10.9 (a941e51c8 2026-03-15) | venv-direct | D:\a\py-launch-lab\py-launch-lab\.cache\matrix_venv_25a90a6db0\Scripts\pythonw.exe D:\a\py-launch-lab\py-launch-lab\fixtures\raw_py\hello.py | 0 | GUI | No | No | Yes | No |