在Pythonw中使用Popen运行进程而不显示控制台

28

我有一个带GUI的程序,通过Popen调用运行外部程序:

p = subprocess.Popen("<commands>" , stdout=subprocess.PIPE , stderr=subprocess.PIPE , cwd=os.getcwd())
p.communicate()

但无论我做什么(我还尝试传递NUL作为文件句柄),都会弹出控制台。有没有办法在不让我调用的二进制文件释放控制台的情况下实现这一点?


这些命令通常是在控制台中运行的吗?你是否正在尝试运行另一个没有控制台的GUI程序? - Noctis Skytower
6个回答

37

来自 这里:

import subprocess

def launchWithoutConsole(command, args):
    """Launches 'command' windowless and waits until finished"""
    startupinfo = subprocess.STARTUPINFO()
    startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW
    return subprocess.Popen([command] + args, startupinfo=startupinfo).wait()

if __name__ == "__main__":
    # test with "pythonw.exe"
    launchWithoutConsole("d:\\bin\\gzip.exe", ["-d", "myfile.gz"])

请注意,有时禁止控制台会导致子进程调用失败并显示"Error 6: invalid handle"。一个快速解决方法是重定向stdin,具体操作可以参考这里:Python running as Windows Service: OSError: [WinError 6] The handle is invalid


很好。因为这不是显而易见的,让我指出startupinfo.wShowWindow = subprocess.SW_HIDE是_隐含的_(SW_HIDE(0)是默认值)。 - mklement0

8

只需执行 subprocess.Popen([command], shell=True)


什么是 pyw 文件?他需要运行一个外部应用程序。 - David Ferenczy Rogožan
这个运行得非常好。你不需要一个 .pyw 文件。 - vy32
1
令人惊讶的是,这个答案被低估了,因为它对我有用。+1。 - Alfredo Maussa

4
根据Python 2.7文档Python 3.7文档,您可以通过设置creationflags来影响Popen创建进程的方式。特别地,CREATE_NO_WINDOW标志对您很有用。
variable = subprocess.Popen(
   "CMD COMMAND", 
   stdout = subprocess.PIPE, creationflags = subprocess.CREATE_NO_WINDOW
)

3
你能解释一下为什么这样做可以解决问题吗?谢谢! - brasofilo
Python 2.7 中没有这个标记。 - Dan Niero
1
使用 "from subprocess import Popen,PIPE,CREATE_NO_WINDOW" 将避免在上面的示例中添加所有前缀。 (以防您想使代码更紧凑一些。) - Alexander Stohr
subprocess.CREATE_NO_WINDOW很优雅,但只适用于Python >= 3.7。 - undefined

1
这在win32api中很好地工作。其他解决方案对我来说都不起作用。
import win32api
chrome = "\"C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe\""
args = "https://stackoverflow.com"

win32api.WinExec(chrome + " " + args)

0

Python 中的 'subprocess' 属性 shell=True

可在 Windows 11 上运行

result = subprocess.run(['nslookup', '2.16.206.132'], shell=True, capture_output=True, text=True)
print(result.stdout)

该进程在不打开shell控制台的情况下执行。 这比使用shell=False要快得多... :)

结果在这里:

Server:  OpenWrt.lan
Address:  192.168.1.1

Name:    a2-16-206-132.deploy.static.akamaitechnologies.com
Address:  2.16.206.132

-1

你可能只需要执行 subprocess.Popen([command], shell=False)

这就是我使用的方式。这样可以避免设置标志等繁琐的步骤。 一旦命名为.pyw文件或使用pythonw运行,它就不应该打开控制台。


2
shell=False已经是默认设置,所以我不知道这个会修复什么问题:https://docs.python.org/2/library/subprocess.html#subprocess.Popen - totaam
3
shell = False不会改变任何东西,解决方法是使用带有.pyw文件的shell = True - notTypecast

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接