4

So, I have a python script that run a Tkinter GUI which have a button widget that call executable that is written in C. But, everytime I click that button, a console that running that C executable pop up and then close after it's done running. I call the executable using

import subprocess    
subprocess.call[args]

How to hide that pop up? Because I'm using GUI and it's kinda not nice if console pop up nowhere.

fahadh4ilyas
  • 450
  • 2
  • 13
  • There's no such thing as a "C executable". If you mean an executable originally written in C and now compiled, the fact it was written in C is rather irrelevant to the question at hand. – Federico klez Culloca Aug 14 '17 at 08:45
  • I guess this is on windows? Then it's a limitation of win32 ... applications are either marked `gui` or `console` and for the latter, a new console is attached by default if there isn't already one. You could call [`CreateProcess()`](https://msdn.microsoft.com/en-us/library/windows/desktop/ms682425(v=vs.85).aspx) yourself, passing a `DETACHED_PROCESS` creation flag to avoid it. –  Aug 14 '17 at 08:47
  • @FedericoklezCulloca Oh, I don't know the name for that *.exe file. So, I named it C executable. But yes, that's what I mean, executable that written in C which is compiled. – fahadh4ilyas Aug 14 '17 at 08:47
  • @fahadh4ilyas If my assumption is correct -- add a windows or winapi tag. I don't know how to call `CreateProcess()` from python, but someone else might know. And btw, it indeed doesn't matter which language was used to compile a "native" executable. –  Aug 14 '17 at 08:49
  • 1
    Related if not a duplicate to: https://stackoverflow.com/q/7006238/694576 – alk Aug 14 '17 at 08:51
  • @alk looks like an exact duplicate to me and has a good answer... –  Aug 14 '17 at 08:58
  • @alk at least if OP *indeed* talks about windows ... no clarification so far –  Aug 14 '17 at 08:59
  • @FelixPalmen in a comment OP says they're trying to start a "*.exe file", so I guess yes, it's about Windows – Federico klez Culloca Aug 14 '17 at 09:21

1 Answers1

3

Use startupinfo parameter of subprocess.Popen() class.

startupinfo = subprocess.STARTUPINFO()
startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW
startupinfo.wShowWindow = subprocess.SW_HIDE
subprocess.Popen(command, startupinfo=startupinfo)

If you wish to pass arguments to the process you should pass it as an array to popen:

subprocess.Popen(['program.exe','arg1','arg2'], startupinfo=startupinfo)

Edit:
As Felix pointed out in the comments, in case that you want the child to don't have console at all you should use the DETACHED_PROCESS flag and subprocess.call.

As described in this MSDN page:

DETACHED_PROCESS 0x00000008 - For console processes, the new process does not inherit its parent's console (the default). The new process can call the AllocConsole function at a later time to create a console. For more information, see Creation of a Console. This value cannot be used with CREATE_NEW_CONSOLE.

DETACHED_PROCESS = 0x00000008
subprocess.call('program.exe', creationflags=DETACHED_PROCESS)
Megabeets
  • 1,378
  • 11
  • 19
  • Ok, this will **hide** the console window. Chances are the called program doesn't even **need** a console, in that case, using the `DETACHED_PROCESS` flag would be better. –  Aug 14 '17 at 08:57
  • 1
    Oh, nevermind. I use same variable for showing pop up that's why it's not working. But, now it's working perfectly. Thank you. – fahadh4ilyas Aug 14 '17 at 09:06
  • Sure, no problem :) – Megabeets Aug 14 '17 at 09:10
  • When creating a detached process, generally it's most reliable to set a standard handle to `NUL` (i.e. `subprocess.DEVNULL`) if it isn't set to a pipe. If you leave the standard handle unset, some programs may crash because they assume it's always defined for a console application. – Eryk Sun Aug 14 '17 at 11:37