「Windowsの右クリックメニューから複数ファイルをまとめて開く」の版間の差分

Notion-MW
Notion-MW
 
(同じ利用者による、間の4版が非表示)
108行目: 108行目:
==== 複数種類に一括で追加? ====
==== 複数種類に一括で追加? ====


<code>HKEY_CLASSES_ROOT</code>には<code>PerceivedType</code>という値があり、これに<code>video</code>などと指定されている場合は<code>HKEY_CLASSES_ROOT\SystemFileAssociations\video</code>にある設定が反映される(これによって複数種類のファイルに共通するメニューが作れる)…というような情報もあったのだが、手元のWindows 11では全く反映されなかった。
<code>HKEY_CLASSES_ROOT</code>には<code>PerceivedType</code>という値があり、これに<code>video</code>などと指定されている場合は<code>HKEY_CLASSES_ROOT\SystemFileAssociations\video</code>にある設定が反映される(これによって複数種類のファイルに共通するメニューが作れる)…というような情報もあったのだが、手元のWindows 11では全く反映されなかった。(追記&#58; [https://www.pg-fl.jp/program/winreg/classes.htm#reg_hkcr_systemfileassociations Windows レジストリ 解剖記&#58; HKEY_CLASSES_ROOT &#45; Programming Field]に、<code>image</code>のような定義済みの名前以外には無効と記載あり)


そもそも<code>PerceivedType</code>に複数種類が指定できるか不明だったりと色々と意義が怪しいので諦めて各拡張子ごとに追加するのがよいのではないかと思う。CLSIDの部分は共通化されているわけなのでそれほど非効率な二重管理ということにもならないだろう。(そもそもこの辺のWindowsの仕様はころころ変わるっぽいのであまり頑張ってもしょうがないかも?)
そもそも<code>PerceivedType</code>に複数種類が指定できるか不明だったりと色々と意義が怪しいので諦めて各拡張子ごとに追加するのがよいのではないかと思う。CLSIDの部分は共通化されているわけなのでそれほど非効率な二重管理ということにもならないだろう。(そもそもこの辺のWindowsの仕様はころころ変わるっぽいのであまり頑張ってもしょうがないかも?)
157行目: 157行目:
動作確認できたサンプルとしては、[https://github.com/microsoft/Windows-classic-samples/tree/main/Samples/Win7Samples/winui/shell/appshellintegration/NonDefaultDropMenuVerb https&#58;//github.com/microsoft/Windows&#45;classic&#45;samples/tree/main/Samples/Win7Samples/winui/shell/appshellintegration/NonDefaultDropMenuVerb]はIContextMenuを使って実装されており、dllをビルドしてCLSIDのInProcServer32でそれを指定するとちゃんと右クリックメニューが追加される。
動作確認できたサンプルとしては、[https://github.com/microsoft/Windows-classic-samples/tree/main/Samples/Win7Samples/winui/shell/appshellintegration/NonDefaultDropMenuVerb https&#58;//github.com/microsoft/Windows&#45;classic&#45;samples/tree/main/Samples/Win7Samples/winui/shell/appshellintegration/NonDefaultDropMenuVerb]はIContextMenuを使って実装されており、dllをビルドしてCLSIDのInProcServer32でそれを指定するとちゃんと右クリックメニューが追加される。


また、メニューを追加する関数であるQueryContextMenuが呼ばれる時点で、引数となっているファイルの情報がわかる(Initialize関数においてIDataObjectが渡されているのでそれをクラスのフィールドなどとして持っておけばよい)ので、特定の拡張子のファイルのみに対してメニューを表示することもできる。もちろんファイルの内容まで読み取ってからメニューを表示するといったこともできるが、そこまですると右クリックするだけで動作が重くなるといった副作用が大きくなるのでやめた方が無難だろう。ただ、スタートメニューへのピン留め<code>&#123;a2a9545d&#45;a0c2&#45;42b4&#45;9708&#45;a0b2badd77c8&#125;</code>やPDF XChange Editor(9.3や10.2.1で確認)のメニューは実際にそのような挙動をする(余談だが、InfoTipの表示もexplorerが操作しづらくなる原因なのでshowinfotipを0にしたほうがいい)(サムネイルなどはバックグラウンドで並列に走るので操作にはあまり影響がない)。またエラーが発生した場合はexplorer自体が強制終了することもあり、全体的に実装は慎重に行ったほうがよい。
また、メニューを追加する関数であるQueryContextMenuが呼ばれる時点で、引数となっているファイルの情報がわかる(Initialize関数においてIDataObjectが渡されているのでそれをクラスのフィールドなどとして持っておけばよい)ので、特定の拡張子のファイルのみに対してメニューを表示することもできる。もちろんファイルの内容まで読み取ってからメニューを表示するといったこともできるが、そこまですると右クリックするだけで動作が重くなるといった副作用が大きくなるのでやめた方が無難だろう。ただ、スタートメニューへのピン留め<code>&#123;a2a9545d&#45;a0c2&#45;42b4&#45;9708&#45;a0b2badd77c8&#125;</code>やPDF XChange Editor(9.3や10.2.1で確認)のメニューは実際にそのような挙動をする(余談だが、InfoTipの表示もexplorerが操作しづらくなる原因なので<code>HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced</code>の<code>ShowInfoTip</code>を0にしたほうがいい)(サムネイルなどはバックグラウンドで並列に走るので操作にはあまり影響がない)。またエラーが発生した場合はexplorer自体が強制終了することもあり、全体的に実装は慎重に行ったほうがよい。


==== コード例 ====
==== コード例 ====
220行目: 220行目:
<ul>
<ul>
<li><p>Windows 11の右クリックメニューに追加してくれるソフト</p>
<li><p>Windows 11の右クリックメニューに追加してくれるソフト</p>
<p>[https://github.com/ikas-mc/ContextMenuForWindows11 link_preview]</p>
<p>[https://github.com/ikas-mc/ContextMenuForWindows11 https://github.com/ikas-mc/ContextMenuForWindows11]</p>
<p>フォルダ背景を右クリックしたメニューに追加できない([https://github.com/ikas-mc/ContextMenuForWindows11/issues/44 https://github.com/ikas-mc/ContextMenuForWindows11/issues/44])(いや、使ってみたら普通にできてるっぽい?)、アプリ1つにつき1メニューしか追加できない([https://github.com/ikas-mc/ContextMenuForWindows11/issues/45 https://github.com/ikas-mc/ContextMenuForWindows11/issues/45])(これはWindows側がそういう仕様っぽいので厳しそう)</p></li>
<p>フォルダ背景を右クリックしたメニューに追加できない([https://github.com/ikas-mc/ContextMenuForWindows11/issues/44 https://github.com/ikas-mc/ContextMenuForWindows11/issues/44])(いや、使ってみたら普通にできてるっぽい?)、アプリ1つにつき1メニューしか追加できない([https://github.com/ikas-mc/ContextMenuForWindows11/issues/45 https://github.com/ikas-mc/ContextMenuForWindows11/issues/45])(これはWindows側がそういう仕様っぽいので厳しそう)</p></li>
<li><p>Microsoftの関連するサンプル<br />
<li><p>Microsoftの関連するサンプル<br />
234行目: 234行目:
まずは、COMを用いて実装するという方法がある。基本的にはこちらが綺麗な解決策である。
まずは、COMを用いて実装するという方法がある。基本的にはこちらが綺麗な解決策である。


IExecuteCommandというインターフェースを具体的に実装している[https://learn.microsoft.com/en-us/windows/win32/shell/samples-executecommandverb Microsoftのサンプル]があったので、それを参考に、「任意コマンドを引数にとり、取得したファイル・フォルダの情報をそのコマンドの標準入力にUTF&#45;8で送信する」というプログラムを作成した。
IExecuteCommandというインターフェースを具体的に実装している[https://learn.microsoft.com/en-us/windows/win32/shell/samples-executecommandverb Microsoftのサンプル]があったので、それを参考に、「取得したファイル・フォルダの情報を引数または標準入力として渡しつつ指定されたコマンドを起動する」というプログラムを作成した。


[https://github.com/ge9/ExecuteCommand-Pipe link_preview]
[https://github.com/ge9/ExecuteCommand-Pipe https://github.com/ge9/ExecuteCommand-Pipe]


COMを使っていることからわかるように、コマンドラインを介さず直接Explorerからデータが送られてくるので、他の方法に共通してみられるパス長さやファイル個数の制限が(事実上)皆無であり、非常に強力である。
COMを使っていることからわかるように、コマンドラインを介さず直接Explorerからデータが送られてくるので、他の方法に共通してみられるパス長さやファイル個数の制限が(事実上)皆無であり、非常に強力である。