0

私が書いているプログラムについて少し助けが必要です。必要なのは、ファイルをデフォルト プログラムで起動し、そのプログラムの PID を追跡することだけです (後で閉じることができるようにします)。hereから次のコードを見つけました:

import psutil
import subprocess
import os

file = os.getcwd() + "\\" + input()
open = subprocess.Popen(["start", "/WAIT", file], shell=True)
psutil.Process(open.pid).get_children()[0].kill()

これにより、正しいプログラムでファイルが開かれますが、

IndexError: list index out of range  error on the 

psutil.Process(open.pid).get_children()[0].kill()ライン。

私が求めていることを達成する方法を誰かが知っているなら、助けていただければ幸いです! ありがとう

4

1 に答える 1

3

まず、その大きな式のどこで問題が発生したかを推測しようとするのではなく、それをバラバラに分解してみてください。open.pidProcess(open.pid)Process(open.pid).get_children()、およびを出力Process(open.pid).get_children()[0]すると、問題が何であるかは明らかですstart。プロセスには子がありません。

第二に、start常に新しいプロセスを起動するとは限りません。プロセスのコマンドを実行しOpenます。これは、コマンド文字列の場合もあれば、シェル拡張 DLL を介して呼び出される OLE の場合もあり、最終的に新しいプロセスを起動する場合もありますが、別のことを行うこともできます。最も一般的には、そのアプリの既存のプロセス内のファイル。たとえば、.docxWord が既に開いているときにファイルを渡した場合、Word の既存のコピーにそのファイルを処理するように要求します。*

word.exe* Word の最近のバージョンでは、古い OLE メカニズムに依存するのではなく、実際にはそれを行っていると思いますが、その場合は悪い例でした…</sub>

また、新しいプロセスを開始する必要がある場合でも、必ずしも制御された子プロセスとして開始するとは限りません。新しい切り離されたプロセスを起動し、OLE 経由でプロセスを見つけた場合と同じように動作する可能性があります。詳細が文書化されていないことは確かですが、それは理にかなっています (startあなたが彼らだったらどのように書くか想像してみてください)。かなり簡単にテストできます。

  • pskillツールを使用するかpsutil、Python 内からstartプロセスを強制終了します。アプリは気づきません。
  • お気に入りのサードパーティ コマンド ライン ツールを使用するか、プロセス エクスプローラーの GUI をポップアップして、アプリの親が誰であるかを確認します。

いずれにせよ、アプリが の子でない場合、 の子をstart調べても見つけることができませんstart

また、背後にある Win32 API start(および Python のos.startfile,を見るShellExecuteと、最新の Windows では、プロセスへのハンドルさえ返さないことに注意してください。


それで、どうすればこれを行うことができますか?

さて、startドキュメントが説明するように:

コマンドとしてファイルの名前を入力することにより、ファイルの関連付けを通じて非実行ファイルを実行できます。assocおよびを使用してコマンド スクリプトでこれらの関連付けを作成する方法の詳細については、ftype</p>

と を見てassocくださいftype。を実行assocしてファイルのファイル タイプの関連付けを取得し、 を使用してそのファイル タイプftypeのコマンドのコマンド文字列を取得し、 etc. 変数を自分で入力して実行します。(コマンドがコマンド文字列でない場合、それは古い OLE タイプのプログラムであり、これを行うことはできません。しかし、最初から新しいプロセスを取得していない可能性があるのはまさにそのケースです…)Open%0


ShellExecuteまたは、ドキュメントに次のように記載されていることに気付いたかもしれません。

を呼び出した結果として起動されるアプリケーションに関する情報を取得するにはShellExecute、 を使用しますShellExecuteEx

これを行うと、SEE_MASK_NOCLOSEPROCESSフラグfMaskに を設定することができ、hProcessメンバーはHINSTANCEプロセスの、 もちろん)。次に、通常の Win32 プロセス API を使用するか、単に pid を取得して で使用できますpsutil。これはすべて実行可能ですが、おそらく苦痛ctypesです。pywin32おそらくラッパーを使用したいと思うでしょう。

于 2015-04-20T05:14:47.163 に答える