pythonw.exeを使用するとPython subprocess.call()が失敗する
-
19-08-2019 - |
質問
python.exeを使用して実行すると正しく動作するPythonコードがいくつかありますが、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
ただし、 'stdout'パラメーターを指定しない場合、subprocess.call()は正常に起動します。
pythonw.exeが出力自体をリダイレクトしている可能性はありますが、新しいスレッドにstdoutを指定することをブロックされている理由がわかりません。
解決
sys.stdin
およびsys.stdout
ハンドルは無効です。これは、pythonwがデーモンとして実行されるときにコンソールサポートを提供しないため、subprocess.call()
のデフォルト引数が失敗するためです。
デーモンプログラムは、stdin / stdout / stderrを意図的に閉じて、代わりにロギングを使用するため、これを自分で管理する必要があります。subprocess.PIPEを使用することをお勧めします。
サブプロセスがエラーなどについて何を言っているのか本当に 気にしないのであれば、os.devnull
を使用できます(移植性は確かではありませんか?)お勧めしません。
他のヒント
レコードの場合、私のコードは次のようになります。
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()の呼び出しではstdinのパイプも指定する必要があり、その後すぐにパイプを閉じます。
これは古い質問ですが、pyInstallerでも同じ問題が発生しました。
実際、これはコンソールなしでexe用にpythonのコードを変換するフレームワークで発生します。
テストでは、フラグ<!> quot; console = True <!> quot;を使用すると、スペックファイル(pyInstaller)にエラーが発生しなくなりました。 。
解決策は、Piotr Lesnickiのヒントに従いました。