How to Hide Console Window in Python

Hiding the console while executing a script on Windows

The way I've done it on Windows 7 is by making a shortcut (or link) that runs my script with the pythonw.exe interpreter, which has no console, instead of the default python.exe.

Just follow these 3 steps:

  1. First create a normal shortcut to your script. One way to do this is to drag the icon for the script file shown in an Explorer window to where you want the shortcut to be (like the desktop) and hold down the Alt key when releasing the mouse button.
  2. Right-click on the just created shortcut and select Properties from the the menu that pops-up.
  3. A Properties dialog for the shortcut will appear. In it insert C:\python27\pythonw.exe and a space before the path to the your script file. if the path to your script has any spaces in it, it must now be enclosed in double quotes._ If you're using another version of Python, you'll also need to change the Python27 accordingly.

i.e. A target of D:\path with spaces in it to\myscript.py would need to be changed

to C:\Python27\pythonw.exe "D:\path with spaces in it to\myscript.py"

You can also change the shortcut's icon here if you wish.

Here's an example:

screenshot of filled in shortcut properties dialog

Update - simpler way: You can also change the extension of your script to .pyw which will cause it to be run with the pythonw.exe instead of the python.exe.

hide console with executing python script

pass -w or --windowed or --noconsole flag to hide console.

Try GUI pyinstaller by installing auto py to exe. It makes you more easier to compile your script.

pip install auto-py-to-exe

How to hide the console window while starting Tkinter applications but reopening it when the GUI button is pressed to run the python script?

Hiding an existing console window isn't a good idea in general. It's a shared resource, and if your application dies with the window hidden, it's basically rendering useless every other application that's attached to the console.

You can run your script via pythonw.exe, which doesn't automatically allocate or attach to a console. Then allocate your own console on demand, switch to full-screen mode (if supported), set the window title, and rebind sys.std* to the console device files "CONIN$" and "CONOUT$". You have sole ownership of this window, so you're entitled to hide it.

For example:

import os
import sys
import time
import ctypes
import platform

try:
import Tkinter as tk
except ImportError:
import tkinter as tk

from ctypes import wintypes

user32 = ctypes.WinDLL('user32', use_last_error=True)
kernel32 = ctypes.WinDLL('kernel32', use_last_error=True)

_windows_version = tuple(map(int, platform.version().split('.')))

kernel32.GetConsoleWindow.restype = wintypes.HWND
user32.SendMessageW.argtypes = (wintypes.HWND, wintypes.UINT,
wintypes.WPARAM, wintypes.LPARAM)
user32.ShowWindow.argtypes = (wintypes.HWND, ctypes.c_int)

SW_HIDE = 0
SW_MAXIMIZE = 3
SW_SHOW = 5

WM_SYSKEYDOWN = 0x0104
VK_RETURN = 0x0D

def toggle_fullscreen(hwnd=None):
if _windows_version < (10, 0, 14393):
return
if hwnd is None:
hwnd = kernel32.GetConsoleWindow()
lparm = (user32.MapVirtualKeyW(VK_RETURN, 0) << 16) | 0x20000001
user32.SendMessageW(hwnd, WM_SYSKEYDOWN, VK_RETURN, lparm)

def printf(s):
for c in s:
sys.stdout.write('%s' % c)
sys.stdout.flush()
time.sleep(0.15)

def input(s):
sys.stdout.write(s)
sys.stdout.flush()
return sys.stdin.readline().rstrip('\n')

def hello():
kernel32.SetConsoleTitleW(u"Hello, World!")
printf('Hello, World!')
input('\nPress enter to continue...')

class App(object):
allocated_console = None

def __init__(self):
if self.allocated_console is None:
# one-time set up for all instances
allocated = bool(kernel32.AllocConsole())
App.allocated_console = allocated
if allocated:
hwnd = kernel32.GetConsoleWindow()
user32.ShowWindow(hwnd, SW_HIDE)
toggle_fullscreen(hwnd)
self.root = root = tk.Tk()
nvar = tk.StringVar(root)
en = tk.Entry(textvariable=nvar)
en.pack()
btn = tk.Button(text="Shell", command=self.runshell)
btn.pack()

def mainloop(self):
self.root.mainloop()

def runshell(self):
hwnd = kernel32.GetConsoleWindow()
user32.ShowWindow(hwnd, SW_SHOW)
try:
old_title = ctypes.create_unicode_buffer(512)
n = kernel32.GetConsoleTitleW(old_title, 512)
if n > 512:
old_title = ctypes.create_unicode_buffer(n)
kernel32.GetConsoleTitleW(old_title, n)
old_stdin = sys.stdin
old_stderr = sys.stderr
old_stdout = sys.stdout
try:
with open('CONIN$', 'r') as sys.stdin,\
open('CONOUT$', 'w') as sys.stdout,\
open('CONOUT$', 'w', buffering=1) as sys.stderr:
self.root.destroy()
hello()
finally:
kernel32.SetConsoleTitleW(old_title)
sys.stderr = old_stderr
sys.stdout = old_stdout
sys.stdin = old_stdin
finally:
if self.allocated_console:
user32.ShowWindow(hwnd, SW_HIDE)

if __name__ == '__main__':
for i in range(3):
app = App()
app.mainloop()

pythonw.exe is typically associated with the .pyw file extension. You can also configure tools such as py2exe to create a non-console executable.


I had to write an input function since raw_input writes its prompt to the stderr FILE stream. I'd rather avoid rebinding C standard I/O from Python.

It toggles full-screen mode for an allocated console in Windows 10 by sending the key combination Alt+Enter to the console window using a WM_SYSKEYDOW message. Full-screen mode isn't supported in Windows Vista up to Windows 8. In that case you could maximize the window and resize the screen buffer.

Note that I'm only hiding the allocated console window. Avoid calling FreeConsole. The C runtime's conio API (e.g. kbhit, getch) caches a handle to "CONIN$", but it provides no dynamically exported and supported way to reset this cached handle. These CRT functions weren't designed to support cycling over multiple consoles. The assumption is that a process is attached to at most one console for its lifetime. At least in Windows 10 this cached handle also prevents the unused console host process from destroying its window and exiting until your process exits.

If the user closes the console while the application is attached, the console will kill the application. This cannot be prevented. At best you can set a control handler to be notified that process is about to be killed.

Another approach to check whether you can hide the console window would be to call GetConsoleProcessList to get the list of attached processes. You're entitled to hide the window if your process is the only one. If there are two processes attached, it seems reasonable to hide the window if the other one is the py[w].exe launcher that Python 3 installs. Checking the latter requires opening a handle to the process via OpenProcess to get the image name via GetModuleBaseName.



Related Topics



Leave a reply



Submit