単一PowerShellスクリプトで動くWindows右クリックメニュー編集ツールの仕組みを整理する

PowerShellカテゴリを表すパンダのイラスト PowerShell

この記事について
この記事は、生成AIを活用した自動生成フローで作成しています。参照元の情報をもとに整理していますが、筆者による実機確認は行っていません。

検証ステータス:unverified(実機未確認)

Windowsのエクスプローラー右クリックメニューはレジストリのコマンド、COMシェル拡張、Windows 11のパッケージアプリという複数の仕組みが混在して構成されています。「ROCI’s Context Menu Editor」は、これらを外部ライブラリに依存せず、単一のPowerShellスクリプトとWPF UIのみで一元管理できるように設計されたポータブルツールです。

Windowsコンテキストメニューの3層構造と無効化の仕組み

エクスプローラーのコンテキストメニューは単一のレジストリキーではなく、歴史的経緯の異なる3系統の情報源から動的に構築されます。一次情報では、ツールがこれらを同一一覧に統合して表示し、それぞれの特性に応じた「無効化(オフ)」の処理を行うと説明されています。

種類(Kind)格納場所無効化の動作
CommandHKCU/HKLM\Software\Classes\<class>\shell\<verb>verb配下に LegacyDisable 値を付与(キー自体は削除しない)
Shell extension<class>\shellex\ContextMenuHandlers(7-Zip、PowerToysなど)CLSIDを Shell Extensions\Blocked に登録
Windows 11 menuwindows.fileExplorerContextMenus を宣言するパッケージアプリCLSIDを Shell Extensions\Blocked に登録

Command形式の項目はキーを削除するのではなく LegacyDisable を設定することで、元の設定を失わずに非表示化されます。一方、DLLをロードするシェル拡張やWindows 11特有のパッケージアプリメニューは、各拡張のCLSIDをユーザーごとのブロックリストに追加することで読み込みを抑止します。

flowchart TD
    A[右クリックメニュー項目] --> B{項目の種類}
    B -->|Command| C[レジストリのverbキー]
    B -->|Shell extension| D[ContextMenuHandlersのCLSID]
    B -->|Windows 11 menu| E[パッケージアプリのCLSID]
    C --> F[無効化: LegacyDisable値を付与]
    D --> G[無効化: Shell Extensions/Blockedに追加]
    E --> G

また、サイドバーでは対象の表示場所(ファイル、フォルダー、フォルダー背景、デスクトップ、ドライブ、個別拡張子)によるフィルタリングが可能です。個別拡張子の抽出にあたっては、SystemFileAssociations\.ext、拡張子のProgID、PerceivedType、既定アプリのProgIDを組み合わせてメニュー構成を特定する仕組みになっています。

ROCI’s Context Menu Editorの主要機能と操作体系

ツール内では単純なオン・オフ切り替えにとどまらず、項目の編集や破損項目の整理など実用的なメンテナンス機能が網羅されています。

  • コマンドの追加と編集: 名前、実行コマンドライン(対象パスを表す %1 やフォルダーを表す %V)、アイコン、表示位置、Shiftキー押下時のみの表示設定、UACシールドアイコンの有無などを指定できます。

  • サブメニューのグループ化: SubCommands="" とネストされた shell キーの静的フォーマットを採用しており、メニューを階層化したり階層間を移動したりする操作がレジストリ編集レベルで完結します。

  • 破損エントリ(Broken entries)の検出: 参照先プログラムやDLLが存在しない項目、登録されていないハンドラーCLSIDを一覧化し、一括削除(Remove all)できます。誤検知を防ぐため絶対パスのみを検証対象とし、wt.exe などの単独コマンド名、UNCパス、Storeアプリフォルダーは対象外として扱われます。

  • 新規作成(New menu)の管理: ShellNew キー配下の拡張子を管理します。無効化時はキーを _ShellNew にリネームしてWindowsの認識から外し、有効化時に復元します。

  • 一括操作とテスト: 複数行を選択して一括でトグルや削除を実行できるほか、編集画面の「Test」ボタンから指定したファイル・フォルダーに対して %1 や %V を展開した状態でテスト実行できます。

送る(Send to)連携とWindows 11パッケージアプリ対応

「送る(Send to)」フォルダー内のショートカット管理に加え、通常の右クリック項目をSend To項目へ変換する機能が備わっています。

通常コマンドの変換

引数の末尾にファイルパスを渡すコマンド(例: app.exe -x "%1")は、引数末尾を除いたショートカットとしてSend Toに登録されます。WindowsのSend To機能自体が末尾に選択ファイルパスを自動付加するためです。引数位置が末尾以外にあるコマンドについては、変換不可の旨が表示されます。

Windows 11専用項目のCOMブリッジ

Windows 11形式のコンテキストメニュー項目はコマンドラインを持たず、エクスプローラーから直接COMハンドラーが呼び出されます。これをSend Toから呼び出すため、ツールは初回利用時に埋め込みC#コードから小さな実行ファイル CmeSendTo.exe(%LOCALAPPDATA%\ContextMenuEditor 配下)をコンパイルして配置します。ショートカットはこのブリッジを経由して元のCOMハンドラーを呼び出します。

安全性を担保するバックアップとレジストリ操作の実装方針

レジストリ編集を伴うツールにおいて、システム破壊を防ぐための設計が随所に施されています。

  1. 自動差分バックアップ: 編集や削除の実行前に、対象キーが Backups\<timestamp>_<name>.reg として自動エクスポートされます。ステータスバーからは直前の操作を取り消すUndoが呼び出せます。

  2. スコープに応じた権限管理: HKCU(現在のユーザー)の項目は管理者権限なしで変更可能です。全ユーザー向けの HKLM 項目を変更する際には、管理者としてツールを再起動するよう促されます。

  3. .NETレジストリAPIの直接利用: PowerShell標準のレジストリプロバイダー(Get-Item や Set-ItemProperty など)は、*\shell などのパスに含まれる * をワイルドカードとして誤解釈する問題があります。これを回避するため、すべての操作で .NET の Microsoft.Win32.Registry API が直接使用されています。

アーキテクチャと単一ファイルへのコンパイル構造

配布形態は1つの ContextMenuEditor.ps1 ですが、ソースリポジトリでは保守性を維持するために機能ごとにファイルが分割されています。

  • scripts/header.ps1: ヘルプブロックと引数定義(param())

  • scripts/start.ps1: アセンブリの読み込み、ネイティブ型定義、定数定義

  • functions/core/*.ps1: レジストリスキャン、Send To処理、TweaksエンジンなどUI非依存ロジック

  • functions/ui/*.ps1: WPFダイアログ、ビュー、Undo管理、コマンド編集画面

  • scripts/main.ps1: ウィンドウ構築とイベントハンドラーの接続

  • xaml/*.xaml: UI画面定義

  • native/*.cs: Win32相互運用コードおよびSend Toブリッジ(C#)

  • config/*.json: Tweaks定義(レジストリ値、検知スクリプト、元に戻す処理など)

これらを Compile.ps1 スクリプトが検証しながら単一のスクリプトへ結合します。出力時はBOMなし(PowerShell 5.1と7の互換性維持および irm | iex 経由での実行時の誤動作防止)で生成されます。

-LibraryOnlyを活用したスクリプトからの呼び出し

UIを起動せずにバックエンド処理のみをスクリプトから利用できるよう、-LibraryOnly スイッチが用意されています。これにより、CIや端末スクリプトからスキャン結果をオブジェクトとして取得可能です。

実行環境に応じた呼び出し例は以下のとおりです。

# 保存名: inspect_menu.ps1


# 実行前提: ContextMenuEditor.ps1 と同じディレクトリで実行すること


# 期待できる確認内容: GUIを表示せずに非標準の右クリックメニュー項目一覧を取得する


# 【実機確認前】

. .\ContextMenuEditor.ps1 -LibraryOnly

# スキャンを実行

Invoke-Scan

# Windows標準機能以外の項目を抽出して表示

$App.Items | Where-Object { -not $_.IsBuiltIn } | Format-Table Kind, Hive, Name, LocLabel, Enabled

実機での実行結果は未確認ですが、一次情報ではこのコマンドにより Kind、Hive、Name、LocLabel、Enabled などのプロパティを持つオブジェクト群が出力されると説明されています。

利用時の注意点と境界条件

運用にあたっては、ツールの設計思想に起因する以下の制約と動作仕様を把握しておく必要があります。

  • エクスプローラーの再起動: シェル拡張や一部のレジストリ変更は、即時反映されずエクスプローラープロセスの再起動を必要とします(ツールのステータスバーから再起動可能とされています)。

  • 壊れたエントリの判定境界: 不在パスの検出は絶対パスのみが対象です。環境変数PATHに依存する実行ファイル名やストアアプリのパスは誤判定防止のため検証がスキップされます。

  • NewメニューのProgID制約: 新規作成メニューに拡張子を追加する際、対象の拡張子に関連付けられたProgIDが存在しない場合は登録が拒否されます。

  • エクスポート/インポートの適用範囲: 設定のエクスポート(.reg出力)はユーザー固有(HKCU)の設定のみが対象となり、全ユーザー向け(HKLM)のプログラム固有エントリは除外されます。

まとめ

ROCI’s Context Menu Editorは、複雑化するWindowsの右クリックメニュー構造をPowerShellとWPFのみで整理できるポータブルなユーティリティです。

実環境への導入前に確認すべきポイントは以下のとおりです。

  • 変更対象が HKCU(現在のユーザー)か HKLM(マシン全体)かによって管理者権限の要否が変わる点

  • 単純削除ではなく LegacyDisable や Shell Extensions\Blocked を用いた非破壊的な制御が行われる点

  • スクリプト単体実行時のバックアップは実行ファイルと同じ階層の Backups フォルダーに保存される点

  • 自動生成される CmeSendTo.exe などのブリッジ機能が環境のセキュリティポリシーに抵触しないか確認する必要がある点

参考情報

  • A Windows context menu editor in one PowerShell file: https://github.com/RoeeIlouz/ROCIsContextMenu-Editor

  • A Windows context menu editor in one PowerShell file (DEV Community): https://dev.to/rocisapps/a-windows-context-menu-editor-in-one-powershell-file-2mc

文書情報

記事タイトル
単一PowerShellスクリプトで動くWindows右クリックメニュー編集ツールの仕組みを整理する
作成日
更新日
Source URL
https://papanda925.com/?p=17617

ライセンス: 本記事のうち、当サイトが権利を有する本文・自作図表は、特記なき限り CC BY 4.0 で利用できます。生成AIを活用して作成・編集した内容を含みます。コードについて、別途ライセンス表示またはリンク先GitHubリポジトリのライセンスがある場合は、その条件を優先します。引用・第三者資料・画像・商標等は本ライセンスの対象外です。 利用ポリシー

タイトルとURLをコピーしました