32

Python から完全に独立したプロセスを起動しようとしています。引数を渡す必要があるため、os.startfile のような単純なものは使用できません。現在、私は subprocess.popen を使用しています。これにより、90%の方法が得られます。

args = ["some_exe.exe", "some_arg", "another_arg"]
subprocess.Popen(args, creationflags=DETACHED_PROCESS | CREATE_NEW_PROCESS_GROUP, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE)

std* の切り離された作成フラグとパイプで popen を使用すると、親プロセスが終了した後に存続する新しいプロセスが開始されます。それはすべて良いことです。問題は、新しい「子」プロセスがまだ親へのファントム ハンドルを保持していることです。したがって、親exeをアンインストールしようとすると(私のpythonスクリプトはpyinstallerを介してexeにバンドルされています)、msiexecは親exeがまだ使用中であると不平を言います。

したがって、目標は、元のプロセスへのハンドルを持たない「some_exe.exe」を実行する完全に独立したプロセスを生成することです。

注: これは Windows XP 以降の場合です。私はWin7で開発しています。

4

2 に答える 2

27

私は答えを見つけたと思います。Popenwithを使用するclose_fds = Trueことで、親へのハンドルなしで独立したプロセスを開始することができました。

ドキュメントについては、こちらを参照して検索してclose_fdsください。

または、Windows では、close_fds が true の場合、ハンドルは子プロセスによって継承されません。Windows では、close_fds を true に設定したり、stdin、stdout、または stderr を設定して標準ハンドルをリダイレクトしたりすることはできないことに注意してください。

このソリューションは Windows でのみ機能することに注意してください。*nix システムについてはまったくわかりません。

于 2012-11-27T21:46:54.347 に答える
4

私はこれを見つけまし

Windows (win xp) では、longtask.py が作業を完了するまで、親プロセスは終了しません。これは、CGI スクリプトで必要なものではありません。この問題は Python に固有のものではなく、PHP コミュニティでも問題は同じです。

解決策は、DETACHED_PROCESSプロセス作成フラグをwin APIの基礎となるCreateProcess関数に渡すことです。pywin32 をインストールしたことがある場合は、win32process モジュールからフラグをインポートできます。それ以外の場合は、自分で定義する必要があります。

DETACHED_PROCESS = 0x00000008

pid = subprocess.Popen([sys.executable, "longtask.py"], creationflags=DETACHED_PROCESS).pid

于 2012-11-27T21:24:04.707 に答える