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

我写了一些如下语句:

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

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

如何阻止它弹出控制台?

【问题讨论】:

标签: python windows console subprocess


【解决方案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。显式传递它应该没有什么区别。
    猜你喜欢
    • 1970-01-01
    • 2015-05-20
    • 2022-11-17
    • 2014-09-27
    • 2011-08-31
    • 2023-03-09
    相关资源
    最近更新 更多