8

Python とは別の外部プログラムを実行しようとしています。通常は問題ありませんが、プログラムはゲームであり、Python インタープリターが組み込まれています。subprocess.Popen を使用すると、別のプログラムが開始されますが、元のプログラムの Python インスタンスの下で開始されるため、最初の Python コンソールが共有されます。最初のプログラムを正常に終了できますが、別のコンソールが必要です (主に、コンソールを隠して開始するためですが、subprocess.POpen を使用して Python からプログラムを開始すると表示されます)。

まるで「ダブルクリック」したかのように、2 番目のプログラムを完全に単独で開始できればと思います。また、クロスプラットフォームの互換性を目指しているため、os.system は機能しません。これは Windows でのみ使用できます。

4

2 に答える 2

7

まるで「ダブルクリック」したかのように、2 番目のプログラムを完全に単独で開始できればと思います。

2.7 および 3.3 の時点で、Python にはクロスプラットフォームでこれを行う方法がありません。将来、新しいshutil.openメソッドが追加される可能性があります (その名前ではない可能性があります)。詳細については、 http://bugs.python.org/issue3177を参照してください。しかしそれまでは、関心のあるプラットフォームごとに独自のコードを作成する必要があります。

幸いなことに、あなたがしようとしていることshutil.openは、最終的に提供することが期待されているものよりも単純で一般的ではありません。つまり、コード化するのはそれほど難しくありません。

  • OS X には、openあなたが望むことを正確に実行するというコマンドがあります。だから、あなたはただすることができますpopen open /Applications/MyGame.app.
  • Windows では、同等のコマンドは ですstartが、残念ながら、これcmd.exeはスタンドアロン プログラムではなく、シェルの一部です。幸いなことに、Python にはos.startfile同じことを行う関数が付属しているので、 os.startfile(r'C:\Program Files\MyGame\MyGame.exe').
  • FreeDesktop 互換の *nix システム (最近のほとんどの Linux ディストリビューションなどを含む) には、xdg-open「xdg-open はユーザーの優先アプリケーションでファイルまたは URL を開きます」という非常によく似たコマンドがあります。繰り返しますが、ただpopen xdg-open /usr/local/bin/mygame.
  • 他のプラットフォームで実行する予定がある場合は、最適な同等のものを見つけるために少し調査を行う必要があります。それ以外の場合、Mac と Windows 以外の場合は、 を試みpopen xdg-open、それが失敗した場合はエラーをスローします。

(テストされていない) 例については、http://pastebin.com/XVp46f7Xを参照してください。

これは、実際にダブルクリックして Finder/Explorer/Nautilus/etc で起動できるものを実行する場合にのみ機能することに注意してください。たとえば、「./script.py」を起動しようとすると、設定によっては、スクリプトを含むテキスト エディターが起動するだけの場合があります。

また、OS X では、その中の UNIX 実行可能ファイルではなく、.app バンドルを実行する必要があります。(場合によっては、UNIX 実行可能ファイルの起動 (.app バンドル内またはスタンドアロンのどちらでも) が機能する可能性がありますが、当てにしないでください。)

また、この方法でプログラムを起動することは、コマンドラインから実行することと同じではないことに注意してください。特に、Windows/Launch Services/GNOME/KDE/ から環境、現在のディレクトリ/ドライブなどを継承します。等 端末セッションからではなく、セッション。子プロセスをさらに制御する必要がある場合は、 、 、および/または別のソリューションのドキュメントを参照する必要がopenありxdg-openますos.startfile

最後に、open/ xdg-open/os.startfileが成功したからといって、実際にゲームが正しく起動したとは限りません。たとえば、起動してウィンドウを作成する前にクラッシュした場合でも、成功したように見えます。

必要なことを行うライブラリについては、PyPI を調べてみてください。http://pypi.python.org/pypi/desktop可能性のようです。

または、問題 3177 のパッチに目を通し、最も気に入ったものを選択することもできます。私の知る限り、それらはすべて純粋な Python であり、追加された関数をまたはの代わりに独自のモジュールに簡単にドロップできosますshutil

簡単なハックとして、を (ab) 使用できる場合がありますwebbrowser.open。「一部のプラットフォームでは、この関数を使用してファイル名を開こうとすると、動作し、オペレーティング システムに関連付けられたプログラムが起動する可能性があることに注意してください。ただし、これはサポートされておらず、移植性もありません。」特に IIRC は、OS X 10.5 以降では動作しません。ただし、ファイル名から file: URL を作成すると、実際にOS X と Windows で動作し、すべてではありませんがほとんどの構成で Linux でも動作します。もしそうなら、それはクイック&ダーティスクリプトには十分かもしれません. 動作するように文書化されていないことに注意してください。一部のユーザーにとっては壊れる可能性があり、将来的に壊れる可能性があります。また、Python 開発者による悪用と明示的に見なされているため、これ以上深刻なことは期待できません。また、上記のより正しい方法と同様に、「script.py」または「Foo.app/Contents/MacOS/foo」の起動、環境変数の受け渡しなどで同じ問題が発生します。

あなたの質問の他のほとんどすべては、無関係で間違っています。

通常は問題ありませんが、プログラムはゲームであり、Python インタープリターが組み込まれています。

それは問題ではありません。ゲームが C コードから stdout に書き込んでいる場合、まったく同じことを行います。

subprocess.Popen を使用すると、別のプログラムが開始されますが、元のプログラムの Python インスタンスの下で開始されます。

いいえ、そうではありません。埋め込まれた Python インタープリターが Python のまったく新しいインスタンスである、まったく新しいプロセスを開始します。たとえば、ゲームが埋め込んでいるものとは異なるバージョンの Python を実行することで確認できます。

最初の Python コンソールを共有するようにします。

いいえ、そうではありません。それらは同じ tty/cmd ウィンドウを共有するかもしれませんが、それは同じことではありません。

最初のプログラムを正常に終了できますが、別のコンソールが必要です (主に、コンソールを隠して開始するためですが、subprocess.POpen を使用して Python からプログラムを開始すると表示されます)。

必要に応じて、子プロセスの stdout と stderr をログファイルなどにいつでもパイプして、親プロセスの出力とは別に表示することができます。しかし、これは、あなたが実際に気にかけていることとは何の関係もない接線で進んでいると思います.

また、クロスプラットフォームの互換性を目指しているため、os.system は機能しません。これは Windows でのみ使用できます。

違う; os.system「Unix、Windows」で利用できます--おそらくあなたが気にかけているすべての場所にあります。ただし、同じ tty を使用して、スクリプトのサブシェルで子プログラムを実行するため、機能しません。(そして、他にも多くの問題があります。たとえば、子プロセスが終了するまでブロックするなどです。)

于 2012-10-25T23:24:20.700 に答える
2

subprocess.Popen を使用すると、別のプログラムが開始されますが、元のプログラムの Python インスタンスの下で開始されます...

正しくない。

...最初の Python コンソールを共有するようにします。

これが問題の核心です。別のコンソールで実行したい場合は、別のコンソールを実行し、代わりにプログラムを実行するように指示する必要があります。

…クロスプラットフォーム対応を目指している…

申し訳ありませんが、クロスプラットフォームの方法はありません。プラットフォームに適したコンソール/ターミナルを実行する必要があります。

于 2012-10-25T22:12:54.900 に答える