使用 os.system() 或 subprocess.call() 时如何隐藏控制台?

Posted

技术标签:

【中文标题】使用 os.system() 或 subprocess.call() 时如何隐藏控制台?【英文标题】:How do I hide the console when I use os.system() or subprocess.call()? 【发布时间】:2011-10-23 18:57:02 【问题描述】:

我写了一些如下语句:

os.system(cmd) #do something
subprocess.call('taskkill /F /IM exename.exe')

两者都会弹出一个控制台。

如何阻止它弹出控制台?

【问题讨论】:

尝试改用spawnfamily。 相关:Running a process in pythonw with Popen without a console 【参考方案1】:

只需添加: subprocess.call('powershell.exe taskkill /F /IM exename.exe', shell=True)

【讨论】:

【参考方案2】:

尝试将扩展名从 .py 更改为 .pyw

它基本上只是一个 Python 用户界面文件。所以它会打开一个没有命令行的新窗口。检查此链接(fileext.com/file-extension/PYW)

【讨论】:

嗨,请提供一些额外的叙述来解释这如何回答问题。谢谢。 它基本上只是一个 Python 用户界面文件。所以它会打开一个没有命令行的新窗口。检查此链接 (filext.com/file-extension/PYW) 请编辑实际答案以包含此有用信息,谢谢。 这仍然没有回答问题,即在已经运行的 Python 应用程序中使用 subprocess() 调用(无论是否在控制台窗口中运行)。【参考方案3】:

进程STARTUPINFO可以隐藏控制台窗口:

si = subprocess.STARTUPINFO()
si.dwFlags |= subprocess.STARTF_USESHOWWINDOW
#si.wShowWindow = subprocess.SW_HIDE # default
subprocess.call('taskkill /F /IM exename.exe', startupinfo=si)

或者设置创建标志来禁止创建窗口:

CREATE_NO_WINDOW = 0x08000000
subprocess.call('taskkill /F /IM exename.exe', creationflags=CREATE_NO_WINDOW)

以上仍然是一个控制台进程,它具有有效的控制台 I/O 句柄(通过在 GetStdHandle 返回的句柄上调用 GetFileType 来验证)。它只是没有窗口,也没有继承父控制台(如果有的话)。

您可以通过强制孩子完全没有控制台来更进一步:

DETACHED_PROCESS = 0x00000008
subprocess.call('taskkill /F /IM exename.exe', creationflags=DETACHED_PROCESS)

在这种情况下,孩子的标准句柄(即GetStdHandle)为 0,但您可以将它们设置为打开的磁盘文件或管道,例如 subprocess.DEVNULL (3.3) 或 subprocess.PIPE

【讨论】:

creationflags=CREATE_NO_WINDOW 似乎不太便携 @Cyan,在什么意义上CREATE_NO_WINDOW 不可移植?这是一个 Windows 问题,从 3.1 到 Windows 10 的所有 Windows NT 版本都应该支持这些标志。 Python 3.7 现在有subprocess.CREATE_NO_WINDOW @Harmon758,我知道。正在添加优先级创建标志,我建议我们不妨添加一些其他标志,包括控制台标志CREATE_NO_WINDOWDETACHED_PROCESS 以及另外两个与控制台无关的标志——CREATE_BREAKAWAY_FROM_JOBCREATE_DEFAULT_ERROR_MODE. @eryksun 很抱歉,我并不是要暗示你还不知道它的存在。我还没有看到这里提到它,所以我想将信息提供给遇到这个问题的任何人,因为这个答案具有很高的知名度。【参考方案4】:

shell=True 参数添加到子进程调用中。

subprocess.call('taskkill /F /IM exename.exe', shell=True)

或者,如果您不需要等待,请使用subprocess.Popen 而不是subprocess.call

subprocess.Popen('taskkill /F /IM exename.exe', shell=True)

【讨论】:

当然,startupinfo 技术有效,但这个更短(但请在评论中说明您使用shell=True 的原因,否则可能不会那么明显)。 嗯,由于某种原因,我的可执行文件在使用 shell=True 时没有运行。但是在使用 startupinfo 时它运行得很好。 @arifwn:请发布一个新问题。 +1 为简洁起见。这种方式有子进程configure STARTUPINFO for you。请注意,通过cmd /c 运行只能与受信任的命令一起使用。在这种情况下没关系。 不是一个好的解决方案。 shell=True 做的比你想要的多,如果用户可以操纵输入,就会引发安全问题。【参考方案5】:

试试subprocess.Popen(["function","option1","option2"],shell=False)

【讨论】:

对不起,我想调用的东西不能被 subprocess.Popen 运行,因为引发了“无效的 win32 应用程序”异常。但是 os.system 可以在没有任何警告的情况下运行它。 呃,这不是子进程的问题;我可以在 Windows 7 上运行它,本机 (Python 2.7.2) 以及 Cygwin (Python 2.6.5) 下,没有警告。 对我不起作用,控制台仍然弹出。 shell 参数也默认为 False。显式传递它应该没有什么区别。

以上是关于使用 os.system() 或 subprocess.call() 时如何隐藏控制台?的主要内容,如果未能解决你的问题,请参考以下文章

Python:产生具有几个要求的子进程

subprocess in python3.5

使用 os.system() 或 subprocess.call() 时如何隐藏控制台?

python 的os.system问题?

如何将os.system()输出存储在python中的变量或列表中[重复]

(Python/Linux) 通过 python 或 os.system 命令播放无延迟的 wav 文件