5

python.exeを使用して実行すると正しく機能するPythonコードがいくつかありますが、pythonw.exeを使用すると失敗します。

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

        試す:
            結果=subprocess.call(commandLine、shell = True、stdout = outputFile)
        それ外:
            print'例外がスローされました:'、str(sys.exc_info()[1])

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

私が受け取るメッセージは次のとおりです。

    スローされた例外:[エラー6]ハンドルが無効です

ただし、「stdout」パラメーターを指定しない場合、subprocess.call()は正常に起動します。

pythonw.exeが出力自体をリダイレクトしている可能性があることはわかりますが、新しいスレッドにstdoutを指定できない理由がわかりません。

4

3 に答える 3

7

記録のために、私のコードは次のようになります。

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 のパイプも指定する必要があることに注意してください。これはその後すぐに閉じます。

于 2008-12-22T14:19:21.973 に答える
7

sys.stdinおよびsys.stdoutハンドルは無効です。これは、pythonw がデーモンとして実行されるため、コンソール サポートが提供されないためです。したがって、のデフォルトの引数subprocess.call()は失敗します。

デーモン プログラムは意図的に stdin/stdout/stderr を閉じ、代わりにログを使用するため、これを自分で管理する必要があります。subprocess.PIPE を使用することをお勧めします。

サブプロセスがエラーに対して何を言っているかを本当に気にしない場合は、使用できますos.devnull(移植性がどれほどかはよくわかりません) が、それはお勧めしません。

于 2008-12-03T17:26:53.463 に答える
2

これは古い質問ですが、pyInstaller でも同じ問題が発生しました。

実のところ、これは Python のコードをコンソールなしで exe に変換するすべてのフレームワークで発生します。

私のテストでは、spec ファイル (pyInstaller) で "console=True" フラグを使用すると、エラーが発生しなくなることがわかりました。.

解決策は、Piotr Lesnicki のヒントに従いました。

于 2014-08-22T18:09:19.477 に答える