How to avoid console window with .pyw file containing os.system call?

后端 未结 6 1068
既然无缘
既然无缘 2020-11-29 08:59

If I save my code files as .pyw, no console window appears - which is what I want - but if the code includes a call to os.system, I still get a pes

相关标签:
6条回答
  • 2020-11-29 09:11

    Similar to what @firsthand said, I've read on the wxPython-user forums that you "replace" the current running application, that would be "command.com" or "CMD.exe", with pyw.exe or pythonw.exe when you use something like the following:

    os.execl(sys.executable, *([sys.executable]+sys.argv))
    

    see another post

    Although I do not know how you would pipe io in this case.

    I believe one benefit of this approach is if you run your script multiple times your OS taskbar with not fill up with CMD icons. The other way if you have several CMD minimized in the taskbar and start closing them, it is impossible to tell which CMD goes with which pythonw script.

    0 讨论(0)
  • 2020-11-29 09:20

    You should use subprocess.Popen class passing as startupinfo parameter's value instance of subprocess.STARTUPINFO class with dwFlags attribute holding subprocess.STARTF_USESHOWWINDOW flag and wShowWindow attribute holding subprocess.SW_HIDE flag. This can be inferred from reading lines 866-868 of subprocess.py source code. It might be necessary to also pass subprocess.CREATE_NEW_CONSOLE flag as a value of creationflags parameter as you run under pythonw.exe which does not open a console.

    When you use shell=True it just happens that all of the above is set correctly but that doesn't mean it's a proper solution. I would argue it's not because it adds overhead of running command interpreter and parsing arguments. In addition you should keep in mind that (...) the use of shell=True is strongly discouraged in cases where the command string is constructed from external input according to documentation of subprocess module.

    0 讨论(0)
  • 2020-11-29 09:23

    You could try using the subprocess module (subprocess.Popen, subprocess.call or whatever) with the argument shell=True if you want to avoid starting a console window.

    0 讨论(0)
  • 2020-11-29 09:27

    The solution that Piotr describes is actually not as complicated as it may sound. Here is an example where a startupinfo is passed to a check_call invocation to suppress the console window:

    startupinfo = subprocess.STARTUPINFO()
    startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW
    
    subprocess.check_call(cmd, startupinfo=startupinfo)
    

    Since the convenience functions call, check_call, and check_output forward their **kwargs to the Popen constructor, it is not required to use Popen directly.

    0 讨论(0)
  • 2020-11-29 09:32

    People are a bit lazy... I would thx @Piotr Dobrogost and @Frank S. Thomas for their answers.

    I came with this code who is runinng on Linux and Windows:

    import platform
    import subprocess
    startupinfo = None
    if platform.system() == 'Windows':
        import _subprocess  # @bug with python 2.7 ?
        startupinfo = subprocess.STARTUPINFO()
        startupinfo.dwFlags |= _subprocess.STARTF_USESHOWWINDOW
        startupinfo.wShowWindow = _subprocess.SW_HIDE
    

    Later...

    args = [exe, ...]
    out = subprocess.check_output(args, startupinfo=startupinfo)
    

    Thx guys ;)

    Additionally: just to note that the following code using 'call' also works on Python 2.7 (on Windows) with the 'startupinfo' code above:

    def run_command(cmd, sin, sout):
        print "Running cmd : %s"%(" ".join(cmd) )
        return subprocess.call( cmd, stdin=sin, stdout=sout, startupinfo=startupinfo)
    
    0 讨论(0)
  • 2020-11-29 09:32

    It seems that 'os.popen' doesn't produce console window. Script is running under 'pythonw'. Not sure about all cases but in my case it works well.

    os.popen(command)
    
    0 讨论(0)
提交回复
热议问题