Python subprocess.call () échoue lors de l'utilisation de pythonw.exe
-
19-08-2019 - |
Question
J'ai du code Python qui fonctionne correctement lorsque je l'utilise pour l'exécuter, mais échoue si j'utilise 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()
Le message que je reçois est le suivant:
Exception thrown: [Error 6] The handle is invalid
Cependant, si je ne spécifie pas le paramètre 'stdout', subprocess.call () démarre normalement.
Je peux voir que pythonw.exe est peut-être en train de rediriger la sortie elle-même, mais je ne vois pas pourquoi on m'empêche de spécifier stdout pour un nouveau thread.
La solution
sys.stdin
et sys.stdout
ne sont pas valides, car pythonw ne fournit pas de support pour la console car il s'exécute en tant que démon, donc les arguments par défaut du sous-processus . call ()
échouent.
Les programmes Deamon ferment exprès stdin / stdout / stderr et utilisent plutôt la journalisation, de sorte que vous devez gérer cela vous-même: je suggérerais d'utiliser subprocess.PIPE.
Si vous n'aimez vraiment pas le contenu du sous-processus, vous pouvez utiliser os.devnull
(je ne suis pas sûr de savoir à quel point c'est?) mais je ne le recommanderais pas.
Autres conseils
Pour mémoire, mon code ressemble maintenant à ceci:
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())
Notez qu'en raison d'un bogue apparent dans le module de sous-processus, l'appel à Popen () doit également spécifier un canal pour stdin, que nous fermons immédiatement après.
C’est une vieille question, mais le même problème s’est posé avec pyInstaller.
En réalité, cela se produira avec tout framework convertissant du code en python pour exe sans console.
Lors de mes tests, j’ai observé que, si j’utilisais le drapeau "console = True", dans mon fichier de spécification (pyInstaller), l'erreur ne se produit plus. .
La solution a été de suivre la pointe de Piotr Lesnicki.