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.

Était-ce utile?

La solution

Les poignées

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.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top