使用 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')
两者都会弹出一个控制台。
如何阻止它弹出控制台?
【问题讨论】:
尝试改用spawn
family。
相关: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_WINDOW
和DETACHED_PROCESS
以及另外两个与控制台无关的标志——CREATE_BREAKAWAY_FROM_JOB
和CREATE_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() 时如何隐藏控制台?的主要内容,如果未能解决你的问题,请参考以下文章
使用 os.system() 或 subprocess.call() 时如何隐藏控制台?