.pyw и pythonw не работают под Windows 7

Запуск простого Python-файла.py или.pyw приводит к python.exe чтобы показать в диспетчере задач.

python myApp.py
python myApp.pyw

Однако когда мы пытаемся запустить его без использования консоли, сценарий не запускается и не python.exe или же pythonw.exe появляется в диспетчере задач

pythonw myApp.pyw
pythonw myApp.py

Как мы решаем проблему? Система работает под управлением Python 2.7.8 x64.

7 ответов

ТЛ; др

  • Для устранения неполадок используйте перенаправление вывода при вызове:

    pythonw myApp.py 1>stdout.txt 2>stderr.txt
    

Это будет захватывать вывод stdout, например, из print() в файле stdout.txt и вывод stderr (например, из необработанных исключений) в файле stderr.txt; из PowerShell, используйте
cmd /c pythonw myApp.py 1>stdout.txt 2>stderr.txt).
Обратите внимание, что сам акт перенаправления stdout может фактически заставить ваш скрипт снова работать, если единственная причина его сбоя с pythonw было использование print (в Python 2.x - см. ниже).
Предостережение: эта техника перенаправления вывода, по-видимому, не работает при вызове *.pyw сценарии напрямую (в отличие от передачи пути файла сценария к pythonw.exe). Дайте мне знать, если вы знаете, почему и / или это работает для вас.

  • Чтобы исправить ваш скрипт:

Поместите следующее в начало любого скрипта Python 2.x или 3.x, с которым вы хотите запустить pythonw.exe:

import sys, os
if sys.executable.endswith("pythonw.exe"):
  sys.stdout = open(os.devnull, "w");
  sys.stderr = open(os.path.join(os.getenv("TEMP"), "stderr-"+os.path.basename(sys.argv[0])), "w")

Это гарантирует следующее при запуске скрипта с pythonw.exe:

  • print() звонки и явные звонки sys.stdout() эффективно игнорируются (не работают).
  • Вывод Stderr, в том числе из необработанного фатального исключения, отправляется в файл %TEMP%\stderr-<scriptFileName>; %TEMP% стандартная переменная среды Windows, которая указывает на папку текущего пользователя для временных файлов.

Другими словами: при наличии вышеуказанного кода проверьте файл %TEMP%\stderr-<scriptFileName> после того, как ваш скрипт потерпел неудачу, когда вызывается с pythonw.exe,

Для объяснения читайте дальше.


В Windows pythonw.exe предназначен для запуска сценариев GUI/no-UI-at-all, что означает, что стандартные входящие и выходные потоки - sys.stdin , sys.stdout , sys.stderr НЕ доступны

Это имеет два неприятных побочных эффекта:

  • С помощью print() - какие цели sys.stdout по умолчанию - вызывает исключение в Python 2.x.
    • Эта проблема была исправлена ​​в Python 3.x.
  • Любое необработанное исключение, включая одно, вызванное print() в 2.x - заставляет скрипт молча прерывать работу.
    • Сообщения об ошибках исключения идут в sys.stderr по умолчанию, что в данном сценарии недоступно.

Приведенный выше код исправляет эти проблемы:

  • отправка вывода stdout на нулевое устройство, фактически игнорируя любую попытку вывода на sys.stdout - явно или неявно через print(),

  • отправив весь вывод stderr во временный файл.


Различия между Python 2.x и Python 3.x:

Когда скрипт запускается с pythonw.exe, sys.stdin, sys.stdout, а также sys.stderr:

  • в Python 2.x: иметь неверные файловые дескрипторы
    • Возможный результат при попытке записи в sys.stdout или же sys.stderr это следующее исключение: IOError: [Errno 9] Bad file descriptor
    • Ошибка: из-за буферизации вывода это исключение может не появиться, пока вы не выведите, скажем, 4K байтов; Вы можете спровоцировать это мгновенно, вызывая pythonw.exe с -u (для небуферизованного вывода).
    • print() слепо пытается sys.stdout (по умолчанию), так что это провоцирует это исключение рано или поздно.
  • в Python 3.x: установлены в None
    • Это дополнено 3.x print() функция, выполняющая бездействие (бездействие), когда обнаруживает, что sys.stdout является None, чтобы print() операторы могут по умолчанию безопасно использоваться - они будут просто игнорироваться при запуске с pythonw.exe
    • Однако из этого следует, что пытается использовать sys.stdout.write() а также sys.stderr.write() все еще приводит к исключению.

Смотрите здесь для получения дополнительной информации.

Попробуйте добавить строку import sys; sys.stderr = open("errlog.txt", "w") к началу myApp.py, Тогда посмотрите в errlog.txt для отслеживания или любых других сообщений об ошибках.

Я столкнулся с той же проблемой в своем собственном сценарии и обнаружил, что при добавлении вывода ответа Росса сценарий будет фактически выполняться.

Похоже, что по какой-то причине перенаправление вывода устраняет проблему. Поскольку мне не интересно записывать вывод на диск, я вместо этого записал его на /dev/null (или эквивалент платформы) с:

if ( sys.platform == 'win32' and sys.executable.split( '\\' )[-1] == 'pythonw.exe'):
    sys.stdout = open(os.devnull, 'w')
    sys.stderr = open(os.devnull, 'w')

Оператор if гарантирует, что это произойдет только при запуске скрипта из pythonw.exe, Я не уверен, что это связано, но было важно сделать это до других импортов (включая, например, import logging).

У меня была похожая проблема.

После пошаговой отладки путем записи в файл журнала я обнаружил, что pythonw.exe аварийно завершил работу после оператора, который пытался использовать вызов: sys.stdout.write(). Оказывается, при запуске с pythonw.exe sys.stdout имеет значение None.

Если вы используете функции sys.stdout/stderr/stdin и намерены использовать вашу программу с pythonw.exe, добавьте проверку "Нет" - это хорошая идея.

У меня была похожая проблема после обновления памяти моего компьютера. Оказывается, мне пришлось переустановить подушку (библиотека, используемая для обработки изображений). Поэтому убедитесь, что он установлен, а если нет, установите его с помощью "pip install Pillow" в cmd.

Я не уверен, что понимаю вашу проблему, но я думаю, что это то, что вам нужно знать

вам нужно щелкнуть правой кнопкой мыши по файлу py или pyw и выбрать открыть с помощью... find python.exe (вероятно, C:\Python27\python.exe) .. установите флажок, который всегда показывает открытость... теперь вы можете просто удвоить щелкните по нему, если хотите запустить

(обычно установщик устанавливает это для вас...)

Это старый ответ, но я также хочу оставить здесь свое решение:

  • Открыть CMD (с повышенными привилегиями или нет - зависит от ваших потребностей)
  • Перейдите в каталог скрипта.py / .pyw - это важно
  • Запустите pythonw со скриптом в качестве аргумента

    cd E:\my\script\folder\
    pythonw script.py
    
Другие вопросы по тегам