Python subprocess.call() falla al usar pythonw.exe
multithreading (3)
Tengo un código de Python que funciona correctamente cuando uso python.exe para ejecutarlo, pero falla si uso 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()
El mensaje que recibo es:
Exception thrown: [Error 6] The handle is invalid
Sin embargo, si no especifico el parámetro ''stdout'', subprocess.call () comienza bien.
Puedo ver que pythonw.exe podría estar redireccionando la salida, pero no veo por qué estoy bloqueado para especificar stdout para un nuevo hilo.
sys.stdin
y sys.stdout
no son válidos porque pythonw no proporciona soporte de consola ya que se ejecuta como un deamon, por lo que los argumentos predeterminados de subprocess.call()
están fallando.
Los programas de Deamon cierran stdin / stdout / stderr a propósito y usan el registro en su lugar, por lo que tiene que administrarlo usted mismo: Sugeriría usar subproceso.PIPE.
Si realmente no le importa lo que dice el subproceso de errores y todo eso, puede usar os.devnull
(¿no estoy seguro de qué tan portátil es?) Pero no lo recomendaría.
Para el registro, mi código ahora se ve así:
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())
Tenga en cuenta que, debido a un error aparente en el módulo de subproceso, la llamada a Popen () también debe especificar un canal para stdin, que cerramos inmediatamente después.
Esta es una vieja pregunta, pero el mismo problema ocurrió con pyInstaller también.
En verdad, esto sucederá con cualquier marco que convierta código en python para exe sin consola.
En mis pruebas, observé que si utilizo la marca "console = True" en mi archivo spec (pyInstaller) el error ya no ocurre. .
La solución fue seguir el consejo de Piotr Lesnicki.