単純な.pyまたは.pyw pythonファイルを実行すると、python.exe
タスクマネージャの下に表示されます。
python myApp.py
python myApp.pyw
ただし、コンソールを使用せずにスクリプトを実行しようとすると、スクリプトが実行されていないように見え、python.exe
またはpythonw.exe
がタスクマネージャの下に表示されます
pythonw myApp.pyw
pythonw myApp.py
問題をどのようにトラブルシューティングしますか?システムはPython 2.7.8 x64を実行しています。
tl; dr
トラブルシューティングを実行するには、呼び出し時に出力リダイレクトを使用します。
pythonw myApp.py 1>stdout.txt 2>stderr.txt
これは、ファイルstdout.txt
のprint()
などのstdout出力と、ファイルstderr.txt
のstderr出力(未処理の例外など)をキャプチャします。 PowerShellから、cmd /c pythonw myApp.py 1>stdout.txt 2>stderr.txt
)。
stdoutをリダイレクトするまさにその行為により、実際にスクリプトが再び機能する可能性があります、ifpythonw
での失敗の唯一の理由は、 print
の使用(Python 2.xで-下記を参照).
警告:この出力リダイレクト手法は、おそらくnot*.pyw
スクリプトを呼び出すときに機能します直接(スクリプトファイルパスを渡すのではなく) pythonw.exe
に)。 理由がわかっている場合や、うまくいくかどうかをお知らせください。
Python 2.xまたは3.xスクリプトの先頭に以下を配置pythonw.exe
で実行:
import sys, os
if sys.executable.endswith("pythonw.exe"):
sys.stdout = open(os.devnull, "w");
sys.stderr = open(os.path.join(os.getenv("TEMP"), "stderr-"+os.path.basename(sys.argv[0])), "w")
これにより、pythonw.exe
を使用してスクリプトを実行したときに、次のことが保証されます。
print()
呼び出しとsys.stdout()
への明示的な呼び出しは事実上無視されます(何もしません)。%TEMP%\stderr-<scriptFileName>
に送信されます。 %TEMP%
は、一時ファイル用の現在のユーザーのフォルダーを指す標準のWindows環境変数です。言い換えると、上記のコードを配置した後、スクリプトが%TEMP%\stderr-<scriptFileName>
で呼び出されたときに警告なしに失敗した後、ファイルpythonw.exe
を確認してください。
説明については、読んでください。
Windowsでは、pythonw.exe
はGUI/no-UI-at-allスクリプトを起動するためのものです。つまり、標準の入出力ストリーム-sys.stdin
、sys.stdout
、sys.stderr
は使用できません。
これには2つの厄介な副作用があります:
print()
-デフォルトでsys.stdout
をターゲットにします-Python 2.x。で例外が発生しますprint()
によってトリガーされたものを含む-スクリプトを中止サイレント。にしますsys.stderr
に送られますが、これはこのシナリオでは利用できないものです。上記のコードはこれらの問題を次のように修正します。
stdout出力をnullデバイスに送信し、明示的に、またはprint()
を介して暗黙的にsys.stdout
への出力の試みを事実上無視します。
すべてのstderr出力を一時ファイルに送信します。
Python 2.xとPython 3.xの違い:
pythonw.exe
、sys.stdin
、sys.stdout
、およびsys.stderr
を使用してスクリプトを実行すると、次のようになります。
sys.stdout
またはsys.stderr
に書き込もうとしたときのeventual結果は、次の例外です:IOError: [Errno 9] Bad file descriptor
pythonw.exe
を-u
で(バッファリングされていない出力用に)呼び出すことで、即座にそれを呼び出すことができます。print()
は盲目的にsys.stdout
(デフォルト)を試行するため、遅かれ早かれこの例外を引き起こします。None
sys.stdout
がNone
であることがわかったときにno-op(何もしない)を実行する3.x print()
関数で補完されるため、print()
ステートメントはデフォルトで安全に使用できます。pythonw.exe
で実行すると、ステートメントはignoredになります。sys.stdout.write()
およびsys.stderr.write()
を使用しようとしても例外が発生することになります。詳細については こちら を参照してください。
行import sys; sys.stderr = open("errlog.txt", "w")
をmyApp.py
の先頭に追加してみてください。次に、errlog.txt
でトレースバックまたはその他のエラーメッセージを探します。
自分のスクリプトでも同じ問題に直面し、Rossの回答からの出力を追加すると、スクリプトが実際に実行されることがわかりました。
何らかの理由で出力をリダイレクトすると問題が解決するようです。出力をディスクに書き込むことに興味がないので、代わりに/dev/null
(または同等のプラットフォーム)に出力しました。
if ( sys.platform == 'win32' and sys.executable.split( '\\' )[-1] == 'pythonw.exe'):
sys.stdout = open(os.devnull, 'w')
sys.stderr = open(os.devnull, 'w')
Ifステートメントは、スクリプトがpythonw.exe
から起動された場合にのみ発生することを保証します。関連しているかどうかはわかりませんが、他のインポート(import logging
など)の前に行うことが重要でした。
私は同様の問題を抱えていました。
ログファイルに書き込んで段階的にデバッグした後、呼び出しsys.stdout.write()を使用しようとしたステートメントの後でpythonw.exeがクラッシュしたことを発見しました。 pythonw.exeで実行すると、sys.stdoutはNoneになります。
Sys.stdout/stderr/stdinの関数を使用していて、プログラムをpythonw.exeで使用する場合は、「なし」のチェックを追加することをお勧めします。