如何避免使用包含os.system调用的.pyw文件的控制台窗口?

twn*_*ale 12 python windows console windows-console pythonw

如果我将我的代码文件保存为.pyw,则不会出现控制台窗口 - 这就是我想要的 - 但如果代码包含调用os.system,我仍然会得到一个讨厌的控制台窗口.我认为这是由呼叫引起的os.system.有没有办法从我的.pyw脚本中执行其他文件而根本不提高控制台窗口?

Pio*_*ost 15

您应该使用subprocess.Popen类传递作为带有属性保持标志和属性保持标志startupinfosubprocess.STARTUPINFO类的参数值实例.这可以从读取线来推断866-868的源代码.可能还需要将flag作为参数值传递,因为您运行时不会打开控制台.dwFlagssubprocess.STARTF_USESHOWWINDOWwShowWindowsubprocess.SW_HIDEsubprocess.pysubprocess.CREATE_NEW_CONSOLEcreationflagspythonw.exe

当你使用shell=True它时,恰好正确地设置了上述所有内容,但这并不意味着它是一个合适的解决方案.我认为这不是因为它增加了运行命令解释器和解析参数的开销.另外,您应该记住,根据子进程模块的文档从外部输入构造命令字符串的情况下,强烈建议不要使用shell = True.

  • 使用“shell=True”在这里不是正确的做法,并且正确解决方案的(所谓的)复杂性不会改变这一点。 (2认同)
  • 我不敢相信这不是最高投票的答案.所有这些都是因为为了正确地做事,人们不会为编写3行代码而烦恼.+1 (2认同)
  • 您还可以添加一个示例吗? (2认同)

Fra*_*mas 13

Piotr描述的解决方案实际上并不像听起来那么复杂.下面是一个示例,其中a startupinfo传递给check_call调用以抑制控制台窗口:

startupinfo = subprocess.STARTUPINFO()
startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW

subprocess.check_call(cmd, startupinfo=startupinfo)
Run Code Online (Sandbox Code Playgroud)

由于方便功能call,check_call并将check_output它们转发**kwargsPopen构造函数,因此不需要Popen直接使用.

  • @ArtOfWarfare 1.它没有详细说明,因为它只有3个简单的附加行与`shell = True`比较``startupinfo = subprocess.STARTUPINFO(); startupinfo.dwFlags | = _subprocess.STARTF_USESHOWWINDOW; startupinfo.wShowWindow = _subprocess.SW_HIDE)`.2.它是Windows特定的,因此只应在Windows上应用.因此,谈论破坏其他系统*是没有意义的. (3认同)
  • @ArtOfWarfare这个问题是针对Windows的,因此它在其他操作系统上可能会失败也就不足为奇了.如果您想提供帮助,则应说明您在Mac OS上遇到的确切错误. (2认同)

小智 7

人们有点懒惰......我会感谢@Piotr Dobrogost@Frank S. Thomas的答案.

我带来了这个在Linux和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
Run Code Online (Sandbox Code Playgroud)

后来...

args = [exe, ...]
out = subprocess.check_output(args, startupinfo=startupinfo)
Run Code Online (Sandbox Code Playgroud)

大家好;)

另外:请注意,使用'call'的以下代码也可以在Python 2.7(在Windows上)上使用上面的'startupinfo'代码:

def run_command(cmd, sin, sout):
    print "Running cmd : %s"%(" ".join(cmd) )
    return subprocess.call( cmd, stdin=sin, stdout=sout, startupinfo=startupinfo)
Run Code Online (Sandbox Code Playgroud)


rob*_*nce 5

如果要避免启动控制台窗口,可以尝试将子进程模块(或其他)与参数一起使用.subprocess.Popensubprocess.callshell=True

  • 这里不需要`shell = True`.请参阅我的回答和问题[如何在Python(2.7)中消除衍生进程中的Windows控制台?](http://stackoverflow.com/q/3390762/95735) (2认同)