Windows 10 で Python ファイル実行時にコマンドライン引数が渡されない件
拡張子 .py に Python.exe を関連付け、かつ PATH と PATHEXT を通した状態で foobar.py に対して、
$ foobar -h
を実行してもヘルプが出ない。-h
の部分が無視されて実行されてしまう。
この問題に対処したのでメモ。
前提
- Windows 10 Pro
- Python 3.7.4
対処方法
レジストリをいじる。
- HKEY_CLASSES_ROOT\Applications\python.exe\shell\open\command キー
- 既定エントリ
値を以下のように "%1"
から %1 %*
に変える。
"D:\bin1\python374\python.exe" "%1" ↓ "D:\bin1\python374\python.exe" %1 %*
ちなみに HKEY_CLASSES_ROOT\py_auto_file\shell\open\command をいじってもダメだった(assoc コマンドでは .py=py_auto_file
なのだが)。
Q: なんでこんな対処が必要?
Ans: 関連付けを解決する時に使われる assoc と ftype 設定の仕様だから
以下詳しく見ていく。
たとえば .py に D:\bin1\python374\python.exe を関連付けると、
$ D:\bin1\python374\python.exe foobar.py →普通はこう書かなきゃいけないところが $ foobar.py →これで済むようになる
このようになる。この時、内部的には assoc と ftype により、以下のような設定になっている。
assoc .py=py_auto_file ftype py_auto_file=D:\bin1\python374\python.exe %1 %*
ここで ftype については、ftype /? でヘルプを読んでみると、こう書いてある。
オープンコマンド内の %0 または %1 は、関連付けを使って開かれるファイル名で置き換えられます。……%* はすべてのパラメーターを取得し、
つまり、内部的には以下のようにして関連付けの解決が行われている。
foobar.py -h ↓ .py=py_auto_file だから ftype py_auto_file の設定に従おう D:\bin1\python374\python.exe %1 %* ↓ %1 は「関連付けを使って開かれるファイル名」 ↓ %* は「すべてのパラメーター」だから、 D:\bin1\python374\python.exe foobar.py -h
ここで、仮に ftype が D:\bin1\python374\python.exe %1
だとしよう( %*
が足りない)。どうなるか。
foobar.py -h ↓ .py=py_auto_file だから ftype py_auto_file の設定に従おう D:\bin1\python374\python.exe %1 ↓ %1 は「関連付けを使って開かれるファイル名」 D:\bin1\python374\python.exe foobar.py
このようになってしまい、-h
のコマンドライン引数部分が常にカットされてしまう結果となる。
参考:
Q: なんで Applications\python.exe だと直るけど py_auto_file だと直らないの?
Ans: 優先順位の問題で Applications\Python.exe の設定が優先される から(たぶん)。
Application Registration - Windows applications - Microsoft Docs を見ていると、どうもアプリの関連付け設定箇所は複数あり、かつ優先順位(priority) があるように読める。
記述は見当たらなかったが、HKEY_CLASSES_ROOT\XXXX よりも HKEY_CLASSES_ROOT\Applications\XXXX.exe の方が優先順位が高いのだと思われる。
つまり、HKEY_CLASSES_ROOT\Applications\Python.exe 側が %1
となっていたら、いくら HKEY_CLASSES_ROOT\py_auto_file 側を %1 %*
にしても、使われるのは優先順位の高い Applications\Python.exe 側の %1
になる、という話。