web-dev-qa-db-ja.com

Pythonから完全に独立したプロセスを起動します

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をアンインストールしようとすると(my pythonスクリプトはpyinstallerを介してexeにバンドルされています)、msiexecは親exeがまだ使用中であると文句を言います。

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

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

29
greenhat

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

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

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

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

23
greenhat

私はこれを見つけました ここ

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

4
f p