エクスプローラ上でPythonスクリプトにドラッグ&ドロップする。

Windows上では、たとえばテキストファイルをPythonスクリプトに食わせて処理させたい場合、テキストファイルをドラッグ&ドロップ(以下DnD)しようとしてもスクリプトがハイライトされず、DnDを受け付けません。

検索してみると、ベクターでDrop on Scriptというものがあるようですが、これはWindows2000までで、インストールしようとするとWindows 10は拒否してきます。32bitアプリだからというわけではないでしょうから、署名なのかマニフェストなのかそこらへんでしょうか。

どうやら一般的にはDnDを受け付けるバッチファイルを作成し、バッチファイルから引数をPythonスクリプトに渡す、ということがされているようです。

ですがそれだけのためにバッチファイルを書きたくないし、ファイルが増えるのもゴメンです。できればショートカット1つで済ませたい。

参考までにバッチファイルでやるときは、%* を使います。これですべての引数をPythonの sys.argv に渡せます。ファイル名はフルパス名で与えられるので、必要に応じて os.path などを使って加工します。


が、次のような使い方をする場合には面倒です。
data--+--1
      +--2
      +--3
      +--4
のようなディレクトリ構造を考えます。

1から4のディレクトリにはそれぞれ処理したいファイルが格納されています。すべてのディレクトリで同じように処理したい場合には、glob を使ってディレクトリとファイル名を展開すればいいですが、たとえば1と2だけ処理したい場合にはその手は使えません。

さらに1のディレクトリの中で複数ファイルがあって、その中のひとつだけを処理したい場合にはDnDでPythonスクリプトに食わせたいという場合があります。
そうすると、それぞれのディレクトリにスクリプト(とバッチファイル)をコピーして、処理したいファイルをDnDすればいいということになりますが、ここでスクリプトを変更したいという要求が出ます。すると、コピーしたすべてのスクリプトを忘れずに変更しないといけませんが、変更し忘れることもありえます。

そのため、以下のようなディレクトリ構造にします。
data--+--1
      +--2
      +--3
      +--4
      +--script
そしてスクリプトをscriptディレクトリに置いて、1から4にはスクリプトへのショートカットを作成します。そしてショートカットのプロパティの作業ディレクトリは "." にしておきます。すると、scriptにあるファイルを変更すれば済むかたちになります。
DnDで引数を渡したい場合には、バッチファイルを作成してスクリプトを呼び出す形にします。

バッチファイルの記述を以下のようにします。

script/DnD.bat:
@echo off
python ..\script\process.py %*

相対パスで呼び出しているのは、他のディレクトリでもちゃんとPythonスクリプトを参照するためです。こうすることで、このバッチファイルのショートカットのみを1から4の各ディレクトリにコピーしてやればいいことになります。
ただし、これがさらに改装が増えたりした場合には絶対パスに変えたほうがいいでしょう。

別の方法として、pyinstallerを使ってEXEファイルにしてしまうという方法があります。EXEファイルはDnDを受け付けますし、そのショートカットも同様ですので、これでも期待した動作ができるでしょう。pyinstallerに "--onefile" オプションを付けて実行すると、必要なモジュールまで含めて1つのEXEファイルを生成してくれます。

難点としては、Pythonスクリプトを変更するたびにpyinstallerでEXEファイルを作り直す必要があること、生成したEXEファイルが大きいこと、pyinstallerが作成する dist ディレクトリからscriptディレクトリにコピーしないといけないこと、などがあります。

やっぱりバッチファイルのショートカットが一番ラクですかね。

0 件のコメント:

コメントを投稿

Windowsでシンボリックリンクを試してみる。

きっかけは、1つのファイルを別の名前で起動したら違う動きになるようなスクリプトを書く、でした。  busybox なんかでは、同じ実行形式ファイルの名前を、lsにすればlsと同じ、cpとすればcpと同じ動作をするようにしてますが、Pythonスクリプトでそれと同じように argv...