implementation detail of shell context menu extensions
is the canonical verb,
which is returned by the
and which can be passed to
Canonical verbs permit your context menu to be
consistently invoked programmatically,
since they no longer need to rely on the menu text's
which can change based on the user's preferred language,
or which can change due to the whim of the shell
(For example, the shell extension might decide that instead
of a generic
Revert to previous version menu item,
it'll tailor the text to say something like
Revert to March 1, 2017 6:34pm,
which may look nicer to the user,
but it becomes impossible to identify
Another reason to support canonical verbs is to ensure that Explorer itself invokes your verb consistently.
A large category of Explorer hangs were traced back to hangs in shell context menu extensions. To mitigate this problem, Explorer actually juggles two context menus. The first context menu is shown to the user on the UI thread. If the user picks a command from the context menu, then Explorer hands the request to a background thread. The background thread creates a second context menu¹ and uses it to perform the requested operation. That way, if the operation hangs, it's a background thread that hangs, and that isn't quite so bad as hanging a UI thread.
Now, how does Explorer hand the request to a background thread? It takes the menu item the user selected and tries to obtain its corresponding canonical verb. If successful, then it uses that same canonical verb to invoke the command from the background thread. If the shell extension responsible for the menu item does not produce a canonical verb, then the shell applies various heuristics to the second context menu to try to find the item that appears to resemble the one selected by the user most closely.
If you cough up a canonical verb, then Explorer can reliably invoke your verb from the background thread. If you don't, then you end up being subjected to a heuristic, and heuristics sometimes fail.
¹ Explorer cannot simply use the original context menu from a background thread because the original context menu is a COM object that was created on the UI thread, which is a single-threaded apartment. Using it from a background thread requires marshaling, but if you did that and invoked the verb from the background thread, the marshaler would simply switch back to the UI thread and perform the operation there, because it must respect the threading model of the COM object, and the COM object says, "I can be used only on the UI thread."
Marshaling back to the UI thread to perform the operation means that if the operation hangs, we hang the UI thread, which was exactly the problem we were trying to avoid!