2008-12-03 2 views
5

У меня есть код Python, который работает правильно, когда я использую python.exe для его запуска, но сбой, если я использую pythonw.exe.Python subprocess.call() не работает при использовании pythonw.exe

 
    def runStuff(commandLine): 
     outputFileName = 'somefile.txt' 
     outputFile = open(outputFileName, "w") 

     try: 
      result = subprocess.call(commandLine, shell=True, stdout=outputFile) 
     except: 
      print 'Exception thrown:', str(sys.exc_info()[1]) 

    myThread = threading.Thread(None, target=runStuff, commandLine=['whatever...']) 
    myThread.start() 

сообщение я получаю:

 
    Exception thrown: [Error 6] The handle is invalid 

Однако, если я не указать параметр '' стандартный вывод, subprocess.call() начинает нормально.

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

ответ

7

sys.stdin и sys.stdout ручки являются недопустимыми, поскольку pythonw не обеспечивает поддержку консоли, как она работает, как Deamon, так по умолчанию аргументы subprocess.call() терпят неудачу.

Программы Deamon закрывают stdin/stdout/stderr специально и используют запись вместо этого, так что вам нужно управлять этим самостоятельно: я бы предложил использовать subprocess.PIPE.

Если вы действительно не волнует, что говорит, что процесс суб ошибок и все, вы могли бы использовать os.devnull (я не совсем уверен, как портативный это?), Но я бы не рекомендовал это.

6

Для записи, мой код теперь выглядит следующим образом:

def runStuff(commandLine): 
    outputFileName = 'somefile.txt' 
    outputFile = open(outputFileName, "w") 

    if guiMode: 
     result = subprocess.call(commandLine, shell=True, stdout=outputFile, stderr=subprocess.STDOUT) 
    else: 
     proc = subprocess.Popen(commandLine, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, stdin=subprocess.PIPE) 
     proc.stdin.close() 
     proc.wait() 
     result = proc.returncode 
     outputFile.write(proc.stdout.read()) 

Обратите внимание, что, из-за очевидной ошибки в модуле подпроцесса, вызов Popen() должен определить канал для стандартного ввода, а также , который мы закрываем сразу же после этого.

2

Это старый вопрос, но та же проблема возникла и с pyInstaller.

По правде говоря, это произойдет с любым фреймворком, который преобразует код в python для exe без консоли.

В моих тестах я заметил, что если я использую флаг «console = True» в моем spec-файле (pyInstaller), ошибка больше не возникает. ,

Решение было выполнено по указанию Петра Лесницкого.

+0

В настоящее время у меня такая же проблема, я сделал большое приложение с PyQt4, и я не могу заставить селен работать без консоли. Скажите, пожалуйста, как это исправить. https://stackoverflow.com/questions/46520823/selenium-dont-work-after-exporting-to-exe-in-windowed-mode-in-pyinstaller – 2017-10-02 10:54:53