Skip to content

xandfis/MyContextMenuTools

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

My Context Menu Tools

My Context Menu Tools is a Windows 11 File Explorer context-menu extension for adding personal commands and modern-menu entries for apps that still only install legacy registry context-menu verbs.

The top-level Explorer entry is My Tools. Its subitems and cascading submenus are data-driven from:

%LOCALAPPDATA%\MyContextMenuTools\tools.jsonc

The config format is JSON with comments (.jsonc) and supports modular preset includes so useful integrations can live in separate files.

Schema

{
  "menuTitle": "My Tools",
  "menuTooltip": "Custom commands and legacy app integrations",
  "menuIcon": "C:\\Path\\To\\icon.png",
  "items": [
    {
      "include": "Presets\\7zip.jsonc"
    },
    {
      "id": "developer-tools",
      "title": "Developer Tools",
      "icon": "C:\\Path\\To\\icon.svg",
      "children": [
        {
          "id": "edit-text",
          "title": "Edit in Notepad",
          "command": "notepad.exe",
          "arguments": "%1",
          "excludeExtensions": [".exe", ".dll", ".png", ".jpg", ".zip"]
        },
        {
          "type": "separator"
        },
        {
          "id": "open-terminal",
          "title": "Open Terminal Here",
          "command": "wt.exe",
          "workingDirectory": "{parent}"
        }
      ]
    }
  ]
}

Items with children describe hierarchy in the config. On versions of Windows 11 that predate fixes enabling deeper context-menu hierarchies, nested leaves are flattened at runtime while keeping their configured titles. Items with command become verbs.

Items can be modularized with { "include": "relative\\path.jsonc" } or { "$include": "relative\\path.jsonc" }. Include paths are resolved relative to the file that contains them, and an included file can be a single item object, an array of item objects, or an object with an items array.

Divider lines can be represented with { "type": "separator" } or { "separator": true }. On versions of Windows 11 that predate fixes for ECF_ISSEPARATOR rendering in the modern context menu, those entries are ignored at runtime. The parser keeps accepting them so configs can leave separators in place and enable them when the platform behavior is available.

Command placeholders:

Placeholder Meaning
%1 or {path} First selected file or folder
%* or {paths} All selected files/folders
{parent} Parent directory of the first selected item
{container} Parent directory for files, or the selected/background folder for folders and backgrounds
{name} File or folder name of the first selected item
{stem} File or folder name of the first selected item without its final extension
{id} Item id

Filtering:

Field Behavior
appliesTo "files", "folders", "folderBackgrounds", "desktopBackground", "backgrounds", "all", or an array such as ["files", "folders"]
omitted appliesTo Applies to all file types, but not folders
includeExtensions Only show for these file extensions
excludeExtensions Show for all otherwise-matching extensions except these

Folder background and Desktop background menus are registered through the packaged Directory\Background shell target. desktopBackground matches when Explorer supplies the Desktop folder path for that background invocation; backgrounds targets both regular folder backgrounds and the Desktop background.

IExplorerCommand::GetIcon is documented as returning an icon resource string, for example shell32.dll,-249. For reliable Explorer rendering on Windows versions that predate fixes for SVG icon handling in this shell API, items without an icon use Assets\Extension.ico or Assets\Extension.dark.ico. Config items may still point at .svg or .png, but SVGs should have same-name .ico sidecars for older builds, for example Tool.svg, Tool.ico, and optionally Tool.dark.ico. The bundled config uses __appicon to reference Assets\AppIcon.ico.

Local development

Before running Build.ps1 or Setup-Wizard.ps1, install the Microsoft tooling this repo expects:

Tooling Needed for Notes
PowerShell All scripts Windows PowerShell 5.1 or PowerShell 7+ is fine.
Visual Studio Build Tools with C++ tools Build.ps1, or Setup-Wizard.ps1 when it builds Install the Desktop development with C++ workload, including MSVC, the Windows SDK, and C++ resource tools. On ARM64 Windows, include the ARM64 C++ build tools; install x64 C++ build tools too if you plan to pass -Architecture x64.
Windows App SDK tooling that provides winapp.exe Setup-Wizard.ps1 registration, Register-DebugPackage.ps1, and promoted extension profiles winapp must be available on PATH before package registration can create the debug identity.

The scripts do not install these prerequisites for you. A fast way to get the Build Tools and SDK is with winget:

winget install -e --id Microsoft.VisualStudio.BuildTools --override "--passive --wait --add Microsoft.VisualStudio.Workload.VCTools --includeRecommended"

For the guided one-stop setup path, run:

.\scripts\Setup-Wizard.ps1

The wizard can build the binaries, install or update the default config and presets, scan for supported apps, validate the config, and register the debug package. It skips rebuilding by default when build outputs are newer than source inputs. For repeatable runs, pass -NonInteractive plus any skip switches such as -SkipRegistration; non-interactive mode preserves an existing config and validates without prompting for fixes.

.\scripts\Build.ps1
.\scripts\Install-DefaultConfig.ps1
.\scripts\Ensure-AppContextMenuPresets.ps1
.\scripts\Validate-ToolsConfig.ps1
.\scripts\Register-DebugPackage.ps1

Register-DebugPackage.ps1 defaults to -ExplorerRestartMode Automatic, which tries the gentle path first for 10 seconds and prompts before escalating to the old forceful double-restart behavior. Use -ExplorerRestartMode Gentle to avoid Explorer restarts entirely, -ExplorerRestartMode ClearCache when menu or icon changes need Explorer's cache cleared, or -ExplorerRestartMode Force to restart before unregistering and again after registration.

Build and setup commands default to the native OS architecture. Pass -Architecture x64 or -Architecture arm64 only when you need to build a specific target.

Build and setup commands default to -PerformanceVerb Enabled, which adds a disabled informational item showing how long each top-level menu took to load. Use -PerformanceVerb Disabled with Build.ps1, Setup-Wizard.ps1, Register-DebugPackage.ps1, or Manage-ContextMenuExtensions.ps1 to build packages without that item.

Presets and validation

Preset files live under config\presets and are copied to %LOCALAPPDATA%\MyContextMenuTools\Presets by Install-DefaultConfig.ps1. To scan for supported apps that still rely on legacy context-menu verbs and add matching modular includes to the user config, run:

.\scripts\Ensure-AppContextMenuPresets.ps1

The scanner currently supports 7-Zip and Notepad++. It customizes copied preset files to the detected install paths. The 7-Zip preset uses 7zG.exe, including 7-Zip's -ad dialog switch for the legacy-style "Add to archive..." and "Extract files..." dialogs, so long-running archive operations show 7-Zip's GUI progress UI rather than a hidden console process.

If you add a preset for your own use case, please consider submitting a pull request so others can benefit from it too.

After editing presets or config, run:

.\scripts\Validate-ToolsConfig.ps1 -OfferFixes

The validator checks configured executables, searches common install locations such as %ProgramFiles%\7-Zip, offers to replace incorrect paths, and prompts for a manual path when an executable cannot be found.

Separate top-level entries

The default registration exposes a single top-level My Tools menu, which is the recommended default. Users who want a preset to appear as its own top-level context menu entry can create an extension profile. Profiles are separate debug packages backed by separate JSONC files under %LOCALAPPDATA%\MyContextMenuTools\Extensions.

# Show full instructions for managing optional top-level extension profiles
.\scripts\Manage-ContextMenuExtensions.ps1 -Help

# Show app-owned top-level extension profiles. With no profiles, this prints next-step examples.
.\scripts\Manage-ContextMenuExtensions.ps1 -Action List

# Show built-in presets that can be promoted to top-level entries.
# Preset names display lowercase, but -Preset accepts 7Zip / NotepadPlusPlus / SuperDelete.
.\scripts\Manage-ContextMenuExtensions.ps1 -Action ListPresets

# Promote detected 7-Zip commands to their own top-level "7-Zip" entry
.\scripts\Manage-ContextMenuExtensions.ps1 -Action Add -Preset 7Zip

# Add lock-aware deletion helpers as their own top-level file verb
.\scripts\Manage-ContextMenuExtensions.ps1 -Action Add -Preset SuperDelete -Targets files

# Refresh an existing profile package and its compiled config snapshot
.\scripts\Manage-ContextMenuExtensions.ps1 -Action Refresh -Id 7zip

# Add a custom top-level entry backed by a modular include
.\scripts\Manage-ContextMenuExtensions.ps1 -Action Add -Id archive-tools -Title "Archive Tools" -Include "..\Presets\7zip.jsonc" -Icon "%ProgramFiles%\7-Zip\7zFM.exe"

# Remove a profile and unregister its debug package
.\scripts\Manage-ContextMenuExtensions.ps1 -Action Remove -Id 7zip

# Find removable MSIX/AppX context menu packages that were not created by this project
.\scripts\Manage-ContextMenuExtensions.ps1 -Action ScanExternal

# Remove one external package reported by ScanExternal
.\scripts\Manage-ContextMenuExtensions.ps1 -Action RemoveExternal -ExternalPackageFullName "Package_1.0.0.0_x64__publisherid"

Each generated package uses deterministic profile CLSIDs recognized by MyContextMenuToolsExplorerCommand.dll, so the same runtime can load either the default tools.jsonc or a per-profile config file.

Profile creation and refresh generate a compiled snapshot beside the profile config, for example slot-01.compiled.json. Register-DebugPackage.ps1 also refreshes existing profile snapshots so promoted presets get the same first-load optimization as the default My Tools menu.

ScanExternal reads registered MSIX/AppX package manifests and lists packages outside this project that declare windows.fileExplorerContextMenus. RemoveExternal removes exactly one package returned by that scan using Remove-AppxPackage.

The Super Delete preset uses Windows Restart Manager to find processes that hold locks on the selected file. Its copy verb shows the locking process ID numbers in the menu and copies them to the clipboard; its delete verb asks for confirmation before terminating those processes and deleting the file.

This project intentionally runs user-configured commands as the current user. Treat tools.jsonc as executable configuration.

About

Data driven system for adding your own commands to the context menu

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors