ctxmenu

Command line

Every subcommand and switch, what each one writes, and what it refuses to touch.

The same .exe is the window and a diagnostic tool. Output goes to the console it was started from, in the language the window is set to.

No arguments opens the window

ctxmenu on its own opens the window. It does not print a usage message. The window is the product, so the bare command hands you the product. The list of commands and switches lives behind ctxmenu --help.

Choosing a language for one run

--lang de and --lang en go in front of the command, never after it.

ctxmenu --lang en scan

The flag covers the window and every subcommand alike, and it leaves the saved setting as it is. It has to lead because --name, --args and --sub all take free text. A global flag that might be hiding inside one of those values is a flag nobody can reason about.

Reading

Nothing in this table writes to the registry.

CommandWhat it prints
ctxmenu scanthe context menu entries, as a table
ctxmenu programsthe same entries, grouped by the program they belong to
ctxmenu filetype .jpgthe resolution chain of one file type
ctxmenu createdthe entries this tool created
ctxmenu packagedthe entries of the new Windows 11 menu, --json for JSON
ctxmenu favouritesthe favourites
ctxmenu backupsthe backups taken so far
ctxmenu handler statuswhether the Windows 11 handler is installed

Switches for scan

These belong to scan alone. The other reading subcommands take no options.

SwitchEffect
--category <name>one category instead of all of them
--scope <name>user, machine, machine32 or all. The default is all
--all-typeswalk the file type chain as well, for the curated list plus your own extensions
--every-typeinstead of the curated list: every extension registered on this machine
--jsonwrite JSON to stdout
--quietdrop the progress output

The category names are allfiles, allfilesystemobjects, unknown, directory, directorybackground, directoryaudio, directoryimage, directoryvideo, folder, desktopbackground and drive. The same names work for create and for favourite place.

ctxmenu scan --category directory
ctxmenu scan --all-types --json
ctxmenu scan --every-type

Naming a key

Every command that changes something takes a key. The key is the full path below a Classes root, written the way reg.exe writes it.

ctxmenu hide "HKCU\SOFTWARE\Classes\Directory\shell\MyEntry" --yes

Anything above that root is refused. So is any path that ends in a collecting key such as shell, because such a path names a container and not an entry.

The plain scan table does not print the key. ctxmenu scan --json carries it in the registry_path field, and the window shows it in the detail pane of the selected entry.

Changing

CommandWhat it does
ctxmenu hide <key> --yessets the hide flag
ctxmenu show <key> --yesclears it again
ctxmenu shift-only <key> --yesshows the entry only on Shift and right-click
ctxmenu always-show <key> --yesclears that again
ctxmenu delete <key> --yesbacks the key up, then deletes it
ctxmenu backup-allbacks up every place this tool touches
ctxmenu restore <path>plays a backup directory back into the registry
ctxmenu handler installoffers your own entries in the upper Windows 11 menu. Needs admin rights once
ctxmenu handler removetakes that offer back

Each of the four flag verbs and delete takes a backup before it writes, and asks for elevation when the key needs it.

Leave --yes off and nothing is written

Without --yes the command names the key it would touch. For the four flag verbs it also states whether that step would need administrator rights. This is the cheapest way to check a key you typed by hand.

Creating an entry

create writes into HKCU. Pick the target with one of --category <name>, --ext .png or --perceived image.

ctxmenu create --category directory --name "Open with Notepad" --command "\"C:\Windows\notepad.exe\" \"%1\""
SwitchEffect
--name <text>the label the menu shows
--command <line>the command line the entry runs
--key <name>the registry key name, when it should differ from the label
--icon <ref>an icon reference
--positiontop or bottom, to pin the entry to one end of the menu
--extendedthe entry appears only on Shift and right-click

--sub replaces --command and builds a submenu instead of a single entry. One --sub per child, split at the first vertical bar. A --sub-icon applies to the --sub in front of it.

ctxmenu create --category directory --name "Tools" --sub "Open|\"C:\Windows\notepad.exe\" \"%1\"" --sub "List|cmd /c dir \"%1\" & pause"

%1 stays empty in the background categories

In directorybackground and desktopbackground, Windows leaves %1 empty. %V carries the path there instead. The tool warns about this, because an entry that does nothing looks exactly like an entry that works.

Favourites

ctxmenu favourite add --name "Shrink PNG" --url https://squoosh.app --mode clipboard
ctxmenu favourite place <id> --ext .png
ctxmenu favourite remove <id>
ctxmenu favourite run <id> C:\pictures\shot.png

favourite add takes one of three sources.

SourceSwitches
A program--exe <path>, optionally --args <line>
A web tool without an endpoint--url <address>, optionally --mode clipboard or --mode open
A web tool that uploads the file--endpoint <address>, optionally --raw and --field <name>

An endpoint favourite takes further switches: --header "Name: Value", --result save, --result open or --result report, --suffix .min, --json-path output.url, and --insecure to allow an unencrypted http:// address.

favourite place puts a favourite into the menu. It takes the same three target switches as create: --category <name>, --ext .png or --perceived image. favourite run runs one the way a click would, and reports on the console.

Opening the window in a given state

These switches open the window instead of printing anything.

SwitchWhat opens
--tab <name>the window on categories, filetypes, programs, favourites, services or backups
--search <text>the window with the search box filled in
--ext .pngthe file types tab, that extension selected
--service <id>the services tab, that service selected and its tool list loaded. The id is the one in services.json
--new <category>the editor for a new entry of that category, filled in with an example. Nothing is written

The window with the search box filled in, the table below it showing only the entries that match.

ctxmenu --tab services
ctxmenu --search 7-zip
ctxmenu --new directory

Diagnostic switches

SwitchEffect
--window 1600x1000opens the window at that size in pixels on the leftmost screen. The minimum is 900x600
--synthetic <n>opens the window with n generated rows. --bench <frames> turns it into a measured run
--theme-probeflips the system theme once, reports whether the window followed, then restores it
--smokeopens the smoke test window
--versionprints the version
--helpprints the command and switch list

Capturing the output

One trap here belongs to Windows and not to this program. The release build is linked as a windowed program. The attribute is #![cfg_attr(not(debug_assertions), windows_subsystem = "windows")] in ctxmenu/src/main.rs, and it keeps a double-click from flashing a console. Two things follow from it.

A windowed process starts with no standard handles at all. The program calls AttachConsole(ATTACH_PARENT_PROCESS) before its first write, so a command typed into a console does get its output. Started from Explorer the attach fails, the program stays silent, and that is what the double-click case wants.

The shell also does not wait for a windowed process. ctxmenu scan --json > scan.json therefore leaves the file empty, and it leaves no error behind to explain why.

Redirecting to a file needs one of these two

Wait for the process explicitly, or work in a debug build. The windows_subsystem attribute applies to not(debug_assertions) only, so a debug build keeps the console subsystem and redirects the way any console program does. Console work that runs longer than a single command is easier there.

Start-Process ctxmenu -ArgumentList 'scan','--json' -Wait -RedirectStandardOutput scan.json
cargo run -- scan --json > scan.json

Last updated

On this page