27

I have a program with a GUI that runs an external program through a Popen call:

p = subprocess.Popen("<commands>" , stdout=subprocess.PIPE , stderr=subprocess.PIPE , cwd=os.getcwd())
p.communicate()

But a console pops up, regardless of what I do (I've also tried passing it NUL for the file handle). Is there any way to do that without getting the binary I call to free its console?

sbirch
  • 871
  • 1
  • 10
  • 18
  • Are these commands that would normally be run in a console? Are you trying to run another GUI program that does not have a console? – Noctis Skytower Nov 28 '09 at 21:56

6 Answers6

37

From here:

import subprocess

def launchWithoutConsole(command, args):
    """Launches 'command' windowless and waits until finished"""
    startupinfo = subprocess.STARTUPINFO()
    startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW
    return subprocess.Popen([command] + args, startupinfo=startupinfo).wait()

if __name__ == "__main__":
    # test with "pythonw.exe"
    launchWithoutConsole("d:\\bin\\gzip.exe", ["-d", "myfile.gz"])

Note that sometimes suppressing the console makes subprocess calls fail with "Error 6: invalid handle". A quick fix is to redirect stdin, as explained here: Python running as Windows Service: OSError: [WinError 6] The handle is invalid

Jean-François Fabre
  • 137,073
  • 23
  • 153
  • 219
interjay
  • 107,303
  • 21
  • 270
  • 254
  • Nice. Because it isn't obvious, let me point out that `startupinfo.wShowWindow = subprocess.SW_HIDE` is _implied_ (`SW_HIDE` (`0`) is the default value). – mklement0 Mar 12 '22 at 19:32
6

just do subprocess.Popen([command], shell=True)

vy32
  • 28,461
  • 37
  • 122
  • 246
Liam
  • 6,009
  • 4
  • 39
  • 53
3

According to Python 2.7 documentation and Python 3.7 documentation, you can influence how Popen creates the process by setting creationflags. In particular, the CREATE_NO_WINDOW flag would be useful to you.

variable = subprocess.Popen(
   "CMD COMMAND", 
   stdout = subprocess.PIPE, creationflags = subprocess.CREATE_NO_WINDOW
)
Woody1193
  • 7,252
  • 5
  • 40
  • 90
ErnestoQ
  • 97
  • 1
  • 5
1

This works nicely in the win32api. The other solutions were not working for me.

import win32api
chrome = "\"C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe\""
args = "https://stackoverflow.com"

win32api.WinExec(chrome + " " + args)
0

The Python 'subprocess' Attribute shell=True

works on window 11

result = subprocess.run(['nslookup', '2.16.206.132'], shell=True, capture_output=True, text=True)
print(result.stdout)

The process is executed without open a shell-console. This runs much more faster as like with shell=False ... :)

The result is here:

Server:  OpenWrt.lan
Address:  192.168.1.1

Name:    a2-16-206-132.deploy.static.akamaitechnologies.com
Address:  2.16.206.132
udoline
  • 81
  • 1
  • 6
-1

You might be able to just do subprocess.Popen([command], shell=False).

That's what I use anyways. Saves you all the nonsense of setting flags and whatnot. Once named as a .pyw or run with pythonw it shouldn't open a console.

ThantiK
  • 1,582
  • 4
  • 17
  • 31
  • 2
    shell=False is already the default, so I don't see what this is going to fix: https://docs.python.org/2/library/subprocess.html#subprocess.Popen – totaam Mar 26 '16 at 04:52
  • 3
    `shell = False` will not change anything, the solution is to use `shell = True` with a `.pyw` file. – notTypecast Oct 13 '16 at 21:34