Как избежать окна консоли с файлом.pyw, содержащим системный вызов os.s?
Если я сохраню свои файлы кода как .pyw
, не появляется окно консоли - это то, что я хочу - но если код включает в себя вызов os.system
Я все еще получаю надоедливое окно консоли. Я полагаю, это вызвано звонком os.system
, Есть ли способ выполнить другие файлы из моего .pyw
скрипт без поднятия окна консоли вообще?
6 ответов
Вы можете попробовать использовать модуль подпроцесса (subprocess.Popen
, subprocess.call
или что угодно) с аргументом shell=True
если вы хотите избежать запуска консольного окна.
Решение, которое описывает Петр, на самом деле не так сложно, как может показаться. Вот пример, где startupinfo
передается check_call
вызов для подавления окна консоли:
startupinfo = subprocess.STARTUPINFO()
startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW
subprocess.check_call(cmd, startupinfo=startupinfo)
Поскольку функции удобства call
, check_call
, а также check_output
переслать их **kwargs
к Popen
конструктор, не требуется использовать Popen
непосредственно.
Вы должны использовать subprocess.Popen
прохождение класса как startupinfo
экземпляр значения параметра subprocess.STARTUPINFO
класс с dwFlags
атрибут холдинга subprocess.STARTF_USESHOWWINDOW
флаг и wShowWindow
атрибут холдинга subprocess.SW_HIDE
флаг. Это может быть выведено из чтения строк 866-868 subprocess.py
исходный код. Может быть необходимо также передать subprocess.CREATE_NEW_CONSOLE
пометить как значение creationflags
параметр при запуске pythonw.exe
который не открывает консоль.
Когда вы используете shell=True
бывает так, что все вышеперечисленное установлено правильно, но это не значит, что это правильное решение. Я бы сказал, что это не потому, что это увеличивает накладные расходы на запуск интерпретатора команд и анализ аргументов. Кроме того, следует помнить, что (...) использование shell=True настоятельно не рекомендуется в тех случаях, когда командная строка создается из внешнего ввода в соответствии с документацией модуля подпроцесса.
Люди немного ленивые... Я бы поблагодарил @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
Потом...
args = [exe, ...]
out = subprocess.check_output(args, startupinfo=startupinfo)
Спасибо ребята;)
Дополнительно: просто чтобы заметить, что следующий код, использующий 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)
Похоже, что os.popen не выводит окно консоли. Скрипт работает под 'pythonw'. Не уверен во всех случаях, но в моем случае это работает хорошо.
os.popen(command)
Подобно тому, что сказал @firsthand, я читал на форумах пользователей wxPython, что вы "заменяете" текущее работающее приложение, которое будет "command.com" или "CMD.exe", на pyw.exe или pythonw.exe когда вы используете что-то вроде следующего:
os.execl(sys.executable, *([sys.executable]+sys.argv))
см другой пост
Хотя я не знаю, как бы вы поступили в этом случае.
Я считаю, что одним из преимуществ этого подхода является то, что если вы запускаете свой скрипт несколько раз на панели задач ОС, не заполняясь значками CMD. С другой стороны, если у вас есть несколько CMD, свернутых на панели задач, и начинаете закрывать их, невозможно определить, какой CMD подходит к какому сценарию Pythonw.