Struct cbfsshell::ShellMenu

Properties   Methods   Events   Config Settings   Errors  

The ShellMenu struct enables customizing Shell context menu items and commands.

Syntax

cbfsshell::ShellMenu

Remarks

The ShellMenu struct provides a simple way to create custom context menu items for any items selected in the Windows Shell. An application may add such menu items to perform global or item-specific operations when a user chooses the command in the context menu displayed by the Shell for the selected items.

The struct communicates with the Windows Shell through a proxy DLL that is loaded by Explorer in order to add a custom menu item to context menus and handle invocation of that menu item. The set of modules included in this product is discussed in the Deployment Instructions.

Installation and Initialization

First, call the install method to register the proxy DLL with the Windows Shell. Installation should be done at least once before using the library on a new system, but may be done several times to update the values of the proxy_path and scope properties.

component.Install();

Following the installation, any custom menu items that will be added to the Windows context menu must be registered in the Windows Registry. To do this, call the register_menu_item method for each custom menu item.

component.RegisterMenuItem("MyMenuItem");

The next step is to call initialize, which will perform the necessary operations to facilitate communication between the system and your code. Initialization only needs to be called once per application launch.

component.Initialize();

Adding Menu Items

Call the activate method to start serving context menu items and begin handling requests from the Windows Shell. After calling activate, the menu_items collection will be populated with the previously registered menu items.

component.Activate(); // If activation was successful this prints out "MyMenuItem" Console.WriteLine(component.MenuItems[0].Verb);

The Windows Registry only stores the unique text identifiers, or verbs, of the added menu items. As such, their additional properties, such as captions and icons are initialized to their default values every time the menu_items collection is populated. To customize these properties, they must be set manually after calling the activate method, or by handling the on_update_menu event. For example:

component.OnUpdateMenu += (s, e) => { int itemCount = 0; foreach (MenuItem item in component.MenuItems) { if (item != null) { item.Caption = "Menu item #" + itemCount; item.Icon = "shell32.dll,-249"; // icon resource string included with the Windows Shell itemCount++; } } };

Once the component is activated, the menu items from the menu_items collection will appear in the File-Explorer's right-click context menu for any selected Windows Shell items.

Note: Menu items may not be visible in the context menu if their caption property is set to an empty string.

When a user clicks on a context menu item, the on_invoke_menu event is fired, and the selected_items collection is populated with the Windows Shell items selected in Windows File Explorer. An application may use the context provided by the selected_items collection to perform actions specifically tailored to the user's selections. For example:

component.OnInvokeMenu += (s, e) => { if (e.Verb.Equals("MyMenuItem")) { Console.WriteLine("Selected items: "); for (int i = 0; i < component.SelectedItems.Count; i++) { SelectedItem item = component.SelectedItems[i]; Console.WriteLine(item.FileName); } } };

Deactivation and Uninstall

To stop handling Windows Shell requests and render all custom menu items inactive, call the deactivate method.

component.Deactivate();

Since the menu items registered via the register_menu_item method are not automatically removed from the Windows Registry, it is recommended to call unregister_menu_item to unregister each menu item individually during the application's uninstall routine.

component.UnregisterMenuItem("MyMenuItem");

Finally, to detach the component from the Windows Shell and unregister the proxy DLL from the system, call the uninstall method. Normally, this is done when the application is removed from the system.

component.Uninstall();

PIDLs

A PIDL (or an IDL) is a fundamental Windows Shell concept. At a high level, it is pretty simple, as it is just a value that represents a Windows Shell item in the Windows Shell Namespace. It is a bit like a full filesystem path for a physical file or folder, except that it is a binary object and not a string. The name "PIDL" and "IDL" can be used interchangeably. The leading P stands for pointer, the IDL stands for item identifier list, and PIDL generally refers to an IDL itself rather than the pointer to it.

The below information is provided as a general knowledge. Your application will deal with PIDLs only when they denote some Windows Shell items that are not necessarily a part of the Windows Shell namespace extension that you create. Such PIDLs can be used with the Windows Shell API if you decide to call it directly. When CBFS Shell exposes these PIDL values they will appear hex-encoded. If an application needs to call a shell function, it has to decode the PIDL before calling that function.

Just like a full filesystem path is a list of strings separated by the directory separator (on Windows, it is the \ (backslash) character), a PIDL is a list (L is for list) of Ids (identifiers). Unlike a filesystem path, though, a PIDL is binary, and Ids are separated by a special PIDL separator (two consecutive zero bytes).

Microsoft provides more details about PIDLs here Identifying Namespace Objects.

Verbs

The ShellMenu struct is built so that one Explorer command with one GUID is registered in the registry. Verbs are used to identify individual menu items.

A verb is an alphanumeric string that identifies a menu item. Use verbs specific to your application to avoid collisions with other applications. For example, generic words "open" or "edit" are inappropriate because they are or may be used by the Windows Shell or other applications, while "OpenWithMyFineTool" should be ok, as long as "MyFineTool" is not generic.

Each menu item with a distinct verb must be registered before it can be used. This is done by creating the corresponding keys in the registry. Registration is done using the register_menu_item. To remove an item, use unregister_menu_item.

In Windows 11, a command and its GUID should additionally be declared in a sparse package manifest that you include into your application. This is done as follows: <?xml version="1.0" encoding="utf-8"?> <Package ... xmlns:desktop4="http://schemas.microsoft.com/appx/manifest/desktop/windows10/4" xmlns:desktop5="http://schemas.microsoft.com/appx/manifest/desktop/windows10/5" IgnorableNamespaces="uap uap2 uap3 rescap desktop desktop4 desktop5 uap10 com"> <Identity Name="..." ProcessorArchitecture="neutral" Publisher="CN=..." Version="1.0.0.0" /> ... <Applications> <Application Id="..." Executable="..." uap10:TrustLevel="mediumIL" uap10:RuntimeBehavior="win32App"> <Extensions> <desktop4:Extension Category="windows.fileExplorerContextMenus"> <desktop4:FileExplorerContextMenus> <desktop5:ItemType Type="*"> <desktop5:Verb Id="Your verb here" Clsid="Your command GUID here" /> <desktop5:Verb Id="Your second verb here" Clsid="Your command GUID here" /> </desktop5:ItemType> </desktop4:FileExplorerContextMenus> </desktop4:Extension> </Extensions> </Application> </Applications> </Package> The command GUID for use in the manifest can be obtained using the CommandGUID configuration setting.

Troubleshooting

Following are some helpful resources for troubleshooting issues related to the display of menu items.

  • If you are developing your application and you stop and start repeatedly while keeping Windows File Explorer open, there may be a memory/cache issue. To avoid this situation one should terminate Explorer and reopen it.
  • If your context menu items do not appear at all or an excess number of menu items appear, this may indicate a registration/deregistration issue. Try running the application with administrative privileges.
  • If you are seeing strange behavior not contained in this list, please reach out to us with a description of the problem and we are happy to help. Our support team is available over email at support@callback.com

Object Lifetime

The new() method returns a mutable reference to a struct instance. The object itself is kept in the global list maintainted by CBFSShell. Due to this, the ShellMenu struct cannot be disposed of automatically. Please, call the dispose(&mut self) method of ShellMenu when you have finished using the instance.

Property List


The following is the full list of the properties of the struct with short descriptions. Click on the links for further details.

menu_items_countThe number of records in the MenuItem arrays.
menu_item_captionSpecifies the menu item's caption.
menu_item_enabledSpecifies that a menu item is enabled.
menu_item_flagsFlags of the item.
menu_item_iconSpecifies the icon of the menu item.
menu_item_verbA verb (text identifier) of the item.
menu_item_visibleSpecifies that a menu item is visible.
proxy_pathThis property specifies the path to the native proxy DLL.
scopeThis property specifies whether the struct is registered for the current user or for all users.
selected_items_countThe number of records in the SelectedItem arrays.
selected_item_file_nameContains a file name of the selected item.
selected_item_idContains an Id of the selected item.
selected_item_pidlContains a PIDL of the selected item.

Method List


The following is the full list of the methods of the struct with short descriptions. Click on the links for further details.

activateThis method tells the struct to start handling the requests sent to the namespace extension.
configSets or retrieves a configuration setting.
deactivateThis method tells the struct to stop handling the requests sent to the namespace extension.
initializeThis method initializes the core library.
installThis method registers context menu information to the system.
register_menu_itemThis method adds a menu item to the Windows Registry.
uninstallThis method unregisters context menu information from the system.
unregister_menu_itemThis method unregisters a previously registered menu item.

Event List


The following is the full list of the events fired by the struct with short descriptions. Click on the links for further details.

on_errorThis event is fired if an unhandled error occurs during an event.
on_invoke_menuThis event is fired when an item of the context menu is invoked.
on_update_menuThis event is fired when the context menu needs to be updated.

Config Settings


The following is a list of config settings for the struct with short descriptions. Click on the links for further details.

CanonicalNameA human-readable name of the command.
CommandGUIDA GUID of the Explorer command.
IPCFormatThe fixed name of the RPC endpoint.
IsInstalledSpecifies whether the installation was performed.
ProductGUIDID of the proxy DLL.
ServerStartArgumentsThe arguments to pass with the command.
ServerStartCommandLineThe command line to run when the server is not available.
ServerStartOperationThe operation verb.
ServerStartShowOptionDefines how the application windows should be shown.
ServerStartTimeToWaitOptional time to wait before retrying RPC connection.
ServerStartWorkingDirectoryThe working directory.
BuildInfoInformation about the product's build.
LicenseInfoInformation about the current license.

menu_items_count Property (ShellMenu Struct)

The number of records in the MenuItem arrays.

Syntax

fn menu_items_count(&self ) -> Result<i32, CBFSShellError> 

Default Value

0

Remarks

This property controls the size of the following arrays:

The array indices start at 0 and end at menu_items_count - 1.

This property is read-only.

Data Type

i32

menu_item_caption Property (ShellMenu Struct)

Specifies the menu item's caption.

Syntax

fn menu_item_caption(&self , MenuItemIndex : i32) -> Result<String, CBFSShellError> 
fn set_menu_item_caption(&self, MenuItemIndex : i32, value : String) -> Option<CBFSShellError> fn set_menu_item_caption_ref(&self, MenuItemIndex : i32, value : &String) -> Option<CBFSShellError>

Default Value

String::default()

Remarks

Specifies the menu item's caption.

This field contains the caption or title of the menu item - the text of the item, visible to a user.

The MenuItemIndex parameter specifies the index of the item in the array. The size of the array is controlled by the MenuItemsCount property.

Data Type

String

menu_item_enabled Property (ShellMenu Struct)

Specifies that a menu item is enabled.

Syntax

fn menu_item_enabled(&self , MenuItemIndex : i32) -> Result<bool, CBFSShellError> 
fn set_menu_item_enabled(&self, MenuItemIndex : i32, value : bool) -> Option<CBFSShellError>

Default Value

false

Remarks

Specifies that a menu item is enabled.

This field specifies whether the menu item is enabled and can be selected by a user.

The MenuItemIndex parameter specifies the index of the item in the array. The size of the array is controlled by the MenuItemsCount property.

Data Type

bool

menu_item_flags Property (ShellMenu Struct)

Flags of the item.

Syntax

fn menu_item_flags(&self , MenuItemIndex : i32) -> Result<i32, CBFSShellError> 

Default Value

0

Remarks

Flags of the item.

This field is a combination of zero or more flags that specify the attributes of the menu item. The possible flags include:

CMF_DEFAULT0x00No command flags are set

CMF_HAS_SUBCOMMANDS0x01Not used.

CMF_HASSPLITBUTTON0x02A split button is displayed.

CMF_HIDELABEL0x04The label is hidden.

CMF_ISSEPARATOR0x08The command is a separator.

CMF_HASLUASHIELD0x0010A UAC shield is displayed.

CMF_ISDROPDOWN0x0080Selecting the command opens a drop-down submenu.

CMF_TOGGLEABLE0x0100The item is a switch.

The MenuItemIndex parameter specifies the index of the item in the array. The size of the array is controlled by the MenuItemsCount property.

This property is read-only.

Data Type

i32

menu_item_icon Property (ShellMenu Struct)

Specifies the icon of the menu item.

Syntax

fn menu_item_icon(&self , MenuItemIndex : i32) -> Result<String, CBFSShellError> 
fn set_menu_item_icon(&self, MenuItemIndex : i32, value : String) -> Option<CBFSShellError> fn set_menu_item_icon_ref(&self, MenuItemIndex : i32, value : &String) -> Option<CBFSShellError>

Default Value

String::default()

Remarks

Specifies the icon of the menu item.

The field may be set to an icon resource string in the standard format, for instance "shell32.dll,-249". When set, this icon will be displayed next to the menu item caption.

The MenuItemIndex parameter specifies the index of the item in the array. The size of the array is controlled by the MenuItemsCount property.

Data Type

String

menu_item_verb Property (ShellMenu Struct)

A verb (text identifier) of the item.

Syntax

fn menu_item_verb(&self , MenuItemIndex : i32) -> Result<String, CBFSShellError> 

Default Value

String::default()

Remarks

A verb (text identifier) of the item.

This field contains a Verb, which is a unique text identifier of the item. If a menu item is a child item, this value of this field is <ParentVerb>::<Verb>.

The MenuItemIndex parameter specifies the index of the item in the array. The size of the array is controlled by the MenuItemsCount property.

This property is read-only.

Data Type

String

menu_item_visible Property (ShellMenu Struct)

Specifies that a menu item is visible.

Syntax

fn menu_item_visible(&self , MenuItemIndex : i32) -> Result<bool, CBFSShellError> 
fn set_menu_item_visible(&self, MenuItemIndex : i32, value : bool) -> Option<CBFSShellError>

Default Value

false

Remarks

Specifies that a menu item is visible.

This field specifies whether the menu item is visible and can be seen by a user.

The MenuItemIndex parameter specifies the index of the item in the array. The size of the array is controlled by the MenuItemsCount property.

Data Type

bool

proxy_path Property (ShellMenu Struct)

This property specifies the path to the native proxy DLL.

Syntax

fn proxy_path(&self ) -> Result<String, CBFSShellError> 
fn set_proxy_path(&self, value : String) -> Option<CBFSShellError> fn set_proxy_path_ref(&self, value : &String) -> Option<CBFSShellError>

Default Value

String::default()

Remarks

This property may be used to specify the path to the native proxy DLL, which is loaded by the Windows Shell. The value may be in one of these formats:

  1. The name of the directory with Proxy DLLs. In this case, the struct will choose the first DLL with the appropriate architecture.
  2. The full path with the name of the DLL. In this case, just this DLL will be loaded.
  3. The full path with wildcards in the name part (a pattern). In this case, the struct will choose the first DLL that matches the passed pattern.

If left empty, the struct will automatically attempt to locate the appropriate DLL by searching the directory where the application's executable resides.

Data Type

String

scope Property (ShellMenu Struct)

This property specifies whether the struct is registered for the current user or for all users.

Syntax

fn scope(&self ) -> Result<i32, CBFSShellError> 
fn set_scope(&self, value : i32) -> Option<CBFSShellError>

Default Value

0

Remarks

This property specifies whether the information related to the struct is written to the registry for the current user or for all users.

In the latter case, administrative rights are required to successfully execute the install and uninstall methods. If the user account of the process that calls these methods does not have such rights, the call will fail with an error.

Data Type

i32

selected_items_count Property (ShellMenu Struct)

The number of records in the SelectedItem arrays.

Syntax

fn selected_items_count(&self ) -> Result<i32, CBFSShellError> 

Default Value

0

Remarks

This property controls the size of the following arrays:

The array indices start at 0 and end at selected_items_count - 1.

This property is read-only.

Data Type

i32

selected_item_file_name Property (ShellMenu Struct)

Contains a file name of the selected item.

Syntax

fn selected_item_file_name(&self , SelectedItemIndex : i32) -> Result<String, CBFSShellError> 

Default Value

String::default()

Remarks

Contains a file name of the selected item.

If an item is a filesystem object and its PIDL can be resolved to a filesystem path, this field contains a full path on the filesystem; otherwise, the field is empty.

The SelectedItemIndex parameter specifies the index of the item in the array. The size of the array is controlled by the SelectedItemsCount property.

This property is read-only.

Data Type

String

selected_item_id Property (ShellMenu Struct)

Contains an Id of the selected item.

Syntax

fn selected_item_id(&self , SelectedItemIndex : i32) -> Result<String, CBFSShellError> 

Default Value

String::default()

Remarks

Contains an Id of the selected item.

If a selected item comes from within the virtual Windows Shell folder managed by the ShellFolder struct, this field contans an application-defined Id. In other cases, this field is empty and the application may use the PIDL field to identify the item.

The SelectedItemIndex parameter specifies the index of the item in the array. The size of the array is controlled by the SelectedItemsCount property.

This property is read-only.

Data Type

String

selected_item_pidl Property (ShellMenu Struct)

Contains a PIDL of the selected item.

Syntax

fn selected_item_pidl(&self , SelectedItemIndex : i32) -> Result<Vec<u8>, CBFSShellError> 

Remarks

Contains a PIDL of the selected item.

This field contains the PIDL of the selected item.

The SelectedItemIndex parameter specifies the index of the item in the array. The size of the array is controlled by the SelectedItemsCount property.

This property is read-only.

Data Type

Vec

activate Method (ShellMenu Struct)

This method tells the struct to start handling the requests sent to the namespace extension.

Syntax

fn activate(&self) -> Option<CBFSShellError>

Remarks

This method is used to tell the component to begin handling Windows Shell requests and start firing the corresponding events.

Customizing Menu Items

When activate is called to start handling Windows Shell requests the first time after the application is launched, the menu_items collection gets populated with the menu items, registered in the Windows Registry. The items in the menu_items collection initially don't contain any values in their properties except for Verb and ParentVerb. An application should fill those items' properties either right after using the activate method or dynamically, in response to the on_update_menu event.

Note: Registered menu items may not appear in the context menu if their Caption property is set to an empty string.

Menu Item Persistence

When the deactivate method is called to stop the struct, registered menu items will remain in the menu_items list. If the component is restarted by calling this method after deactivation, the properties of these menu items will not need to be repopulated.

config Method (ShellMenu Struct)

Sets or retrieves a configuration setting.

Syntax

fn config(&self, configuration_string : &String) ->  Result<String, CBFSShellError>

Remarks

config is a generic method available in every struct. It is used to set and retrieve configuration settings for the struct.

These settings are similar in functionality to properties, but they are rarely used. In order to avoid "polluting" the property namespace of the struct, access to these internal properties is provided through the config method.

To set a configuration setting named PROPERTY, you must call Config("PROPERTY=VALUE"), where VALUE is the value of the setting expressed as a string. For boolean values, use the strings "True", "False", "0", "1", "Yes", or "No" (case does not matter).

To read (query) the value of a configuration setting, you must call Config("PROPERTY"). The value will be returned as a string.

deactivate Method (ShellMenu Struct)

This method tells the struct to stop handling the requests sent to the namespace extension.

Syntax

fn deactivate(&self) -> Option<CBFSShellError>

Remarks

This method tells the component to stop handling Windows Shell requests and stop firing the corresponding events.

initialize Method (ShellMenu Struct)

This method initializes the core library.

Syntax

fn initialize(&self) -> Option<CBFSShellError>

Remarks

This method initializes the core library and must be called each time the application starts before attempting to use other struct's methods. The only exceptions to this are install, uninstall, register_menu_item, and unregister_menu_item.

If the application explicitly specifies the path to the proxy DLL, it should do this through the proxy_path property before calling this method.

install Method (ShellMenu Struct)

This method registers context menu information to the system.

Syntax

fn install(&self) -> Option<CBFSShellError>

Remarks

This method is used to install the native proxy DLL that integrates with the Windows Shell.

Before calling this method, you may change the default values of the proxy_path, and scope properties. These values are used during installation.

Registry Scope and User Permissions

The scope property specifies whether the information is written to the registry for the current user or for all users.

In the latter case, administrative rights are required to execute this method successfully. If the user account of the process that calls this method does not have such rights, the call will fail with an ERROR_PRIVILEGE_NOT_HELD () error.

register_menu_item Method (ShellMenu Struct)

This method adds a menu item to the Windows Registry.

Syntax

fn register_menu_item(&self, verb : &String) -> Option<CBFSShellError>

Remarks

This method registers a menu item to the Windows Registry. Menu items must be registered before they can be used in a context menu. Normally, this is only needs to be done once during application installation.

The Verb parameter specifies a unique text identifier of the context menu item, further referred to as Verb. A verb is the only aspect of the menu item that gets stored in the Windows Registry.

It is possible to create a menu item with a submenu that contains child items. Note that only one level of submenus is supported on Windows 11, so the struct limits addition of items to one level of submenus too.

To create a submenu, when adding a child item, set Verb to the format <ParentVerb>::<Verb>, where ParentVerb denotes the menu item that is a parent for a submenu. Note that the parent's verb is used only in this method to specify the parent, and the struct passes just the Verb part to the event handlers. Thus, the verb must be unique across all items added via ShellMenu.

Windows Registry Pollution

Menu items registered with the register_menu_item method are not automatically removed from the Windows Registry. To avoid polluting the Registry, it is recommended to unregister each item before the uninstall method is called.

Customizing Menu Items

When activate is called to start handling Windows Shell requests the first time after the application is launched, the menu_items collection gets populated with the menu items, registered in the Windows Registry. The items in the menu_items collection initially don't contain any values in their properties except for Verb and ParentVerb. An application should fill those items' properties either right after using the activate method or dynamically, in response to the on_update_menu event.

Note: Registered menu items may not appear in the context menu if their Caption property is set to an empty string.

Registry Scope and User Permissions

The scope property specifies whether the information is written to the registry for the current user or for all users.

In the latter case, administrative rights are required to execute this method successfully. If the user account of the process that calls this method does not have such rights, the call will fail with an ERROR_PRIVILEGE_NOT_HELD () error.

uninstall Method (ShellMenu Struct)

This method unregisters context menu information from the system.

Syntax

fn uninstall(&self) -> Option<CBFSShellError>

Remarks

This method is used to uninstall the proxy DLL that integrates with the Windows Shell from the system.

Before calling this method, you may change the default value of the scope property.

Windows Registry Pollution

Menu items registered with the register_menu_item method are not automatically removed from the Windows Registry. To avoid polluting the Registry, it is recommended to unregister each item before the uninstall method is called.

Registry Scope and User Permissions

The scope property specifies whether the information is written to the registry for the current user or for all users.

In the latter case, administrative rights are required to execute this method successfully. If the user account of the process that calls this method does not have such rights, the call will fail with an ERROR_PRIVILEGE_NOT_HELD () error.

Handling Multiple Components

As ShellFolder and ShellMenu structs share a proxy DLL and a product GUID, they store some common information in a registry key. Calling the Uninstall method of one of the components will delete a shared registry key as well.

Each struct should be uninstalled properly by calling the corresponding Uninstall method. At the same time, if an application needs to uninstall just one struct and keep the other(s), it should call the Uninstall method of that struct and then call the Install method of the other structs to restore the common information in the shared registry key.

unregister_menu_item Method (ShellMenu Struct)

This method unregisters a previously registered menu item.

Syntax

fn unregister_menu_item(&self, verb : &String) -> Option<CBFSShellError>

Remarks

This method is used to remove a menu item that was registered with register_menu_item from the Windows Registry. This should normally be done once per each menu item after the uninstall method has been called.

The Verb parameter specifies the unique text identifier of the context menu item. If an item is a child in a submenu, this child's own verb is enough (a parent verb should not be specified).

Registry Scope and User Permissions

The scope property specifies whether the information is written to the registry for the current user or for all users.

In the latter case, administrative rights are required to execute this method successfully. If the user account of the process that calls this method does not have such rights, the call will fail with an ERROR_PRIVILEGE_NOT_HELD () error.

on_error Event (ShellMenu Struct)

This event is fired if an unhandled error occurs during an event.

Syntax

// ShellMenuErrorEventArgs carries the ShellMenu Error event's parameters.
pub struct ShellMenuErrorEventArgs {
  fn error_code(&self) -> i32
  fn description(&self) -> &String
}

// ShellMenuErrorEvent defines the signature of the ShellMenu Error event's handler function.
pub trait ShellMenuErrorEvent {
  fn on_error(&self, sender : ShellMenu, e : &mut ShellMenuErrorEventArgs);
}

impl <'a> ShellMenu<'a> {
  pub fn on_error(&self) -> &'a dyn ShellMenuErrorEvent;
  pub fn set_on_error(&mut self, value : &'a dyn ShellMenuErrorEvent);
  ...
}

Remarks

This event fires if an unhandled error occurs. Developers can use this information to track down unhandled errors that occur in the struct.

ErrorCode contains an error code and Description contains a textual description of the error.

on_invoke_menu Event (ShellMenu Struct)

This event is fired when an item of the context menu is invoked.

Syntax

// ShellMenuInvokeMenuEventArgs carries the ShellMenu InvokeMenu event's parameters.
pub struct ShellMenuInvokeMenuEventArgs {
  fn verb(&self) -> &String
  fn context(&self) -> i64
}

// ShellMenuInvokeMenuEvent defines the signature of the ShellMenu InvokeMenu event's handler function.
pub trait ShellMenuInvokeMenuEvent {
  fn on_invoke_menu(&self, sender : ShellMenu, e : &mut ShellMenuInvokeMenuEventArgs);
}

impl <'a> ShellMenu<'a> {
  pub fn on_invoke_menu(&self) -> &'a dyn ShellMenuInvokeMenuEvent;
  pub fn set_on_invoke_menu(&mut self, value : &'a dyn ShellMenuInvokeMenuEvent);
  ...
}

Remarks

This event is fired when a user invokes, or clicks on, a context menu item that has been registered with register_menu_item. To obtain the list of the Windows Shell items for which the context menu was displayed, use the selected_items property.

The Verb parameter contains the unique text identifier of the menu item that was invoked.

The Context parameter is a unique identifier that remains the same across multiple event calls for the same operation. Since the event may fire multiple times for the same operation, its value may be used to avoid performing the same tasks more than once.

UI Considerations

Event handlers are called in the context of threads that run in the MTA (multithreaded apartment) state. This state is not suitable for showing UI elements. Thus, event handlers should create an STA thread and use it to display a needed window. For example:

var thread = new Thread(() => { ... } // "..." is the code that an event handler executes in a helper thread thread.SetApartmentState(ApartmentState.STA); thread.IsBackground = true; thread.Start(); thread.Join(); // optional, if your code should work synchronously

on_update_menu Event (ShellMenu Struct)

This event is fired when the context menu needs to be updated.

Syntax

// ShellMenuUpdateMenuEventArgs carries the ShellMenu UpdateMenu event's parameters.
pub struct ShellMenuUpdateMenuEventArgs {
  fn verb(&self) -> &String
  fn context(&self) -> i64
}

// ShellMenuUpdateMenuEvent defines the signature of the ShellMenu UpdateMenu event's handler function.
pub trait ShellMenuUpdateMenuEvent {
  fn on_update_menu(&self, sender : ShellMenu, e : &mut ShellMenuUpdateMenuEventArgs);
}

impl <'a> ShellMenu<'a> {
  pub fn on_update_menu(&self) -> &'a dyn ShellMenuUpdateMenuEvent;
  pub fn set_on_update_menu(&mut self, value : &'a dyn ShellMenuUpdateMenuEvent);
  ...
}

Remarks

This event is fired when the system needs to update the context menu before it is displayed. The event fires separately for each menu item that was registered via register_menu_item. An event handler is expected to update the menu item in the menu_items collection if such an update is required, and such updates will be reflected in the displayed menu. To obtain the list of Windows Shell items for which the context menu is about to be displayed, use the selected_items property.

The Verb parameter contains the unique text identifier of the corresponding menu item that may be updated.

The Context parameter is a unique identifier that remains the same across multiple event calls for the same operation. Since the event may fire multiple times for the same operation, its value may be used to avoid performing the same tasks more than once.

UI Considerations

Event handlers are called in the context of threads that run in the MTA (multithreaded apartment) state. This state is not suitable for showing UI elements. Thus, event handlers should create an STA thread and use it to display a needed window. For example:

var thread = new Thread(() => { ... } // "..." is the code that an event handler executes in a helper thread thread.SetApartmentState(ApartmentState.STA); thread.IsBackground = true; thread.Start(); thread.Join(); // optional, if your code should work synchronously

Config Settings (ShellMenu Struct)

The struct accepts one or more of the following configuration settings. Configuration settings are similar in functionality to properties, but they are rarely used. In order to avoid "polluting" the property namespace of the struct, access to these internal properties is provided through the config method.

ShellMenu Config Settings

CanonicalName:   A human-readable name of the command.

This configuration setting is used to specify a human-readable name of the Explorer command as this command is written in the registry in the form of a GUID (the value of the GUID can be retrieved via the CommandGUID setting). The default value is "CBFS Shell context menu extension". Adjust this setting before calling the install method. If not set, the default value is used during the installation.

CommandGUID:   A GUID of the Explorer command.

This read-only configuration setting contains a GUID of the Explorer command that is used to register all menu items in the registry. A human-readable canonical name for the GUID may be specified using the CanonicalName config setting.

IPCFormat:   The fixed name of the RPC endpoint.

If the Windows Shell and the server operate in different desktop sessions, set this configuration before installing the native proxy DLL.

IsInstalled:   Specifies whether the installation was performed.

This configuration setting returns true if the struct finds the required registry entries, put there by a previous call to the install method; otherwise, false is returned. In the latter case, an application should use the install method again.

ProductGUID:   ID of the proxy DLL.

A product GUID (also known as project ID) is used to distinguish among various installations performed by different applications. The GUID of the Explorer command (CommandGUID) is derived from this ID.

ServerStartArguments:   The arguments to pass with the command.

Set this configuration setting before installing the native proxy DLL.

ServerStartCommandLine:   The command line to run when the server is not available.

This command is executed using the ShellExecute function of the Windows Shell API.

Set this configuration setting before installing the native proxy DLL.

ServerStartOperation:   The operation verb.

This command is executed using the ShellExecute function of the Windows Shell API. You may pass an optional operation verb to this function.

Set this configuration setting before installing the native proxy DLL.

ServerStartShowOption:   Defines how the application windows should be shown.

This value corresponds to the nShowCmd parameter of the ShellExecute function. The default value is 1 ("show normal").

Set this configuration setting before installing the native proxy DLL.

ServerStartTimeToWait:   Optional time to wait before retrying RPC connection.

The time is specified in milliseconds. The default value is 3000 (3 seconds). Set this configuration setting before installing the native proxy DLL.

ServerStartWorkingDirectory:   The working directory.

This path specifies a working directory for the started process.

Set this configuration setting before installing the native proxy DLL.

Base Config Settings

BuildInfo:   Information about the product's build.

When queried, this setting will return a string containing information about the product's build.

LicenseInfo:   Information about the current license.

When queried, this setting will return a string containing information about the license this instance of a struct is using. It will return the following information:

  • Product: The product the license is for.
  • Product Key: The key the license was generated from.
  • License Source: Where the license was found (e.g., RuntimeLicense, License File).
  • License Type: The type of license installed (e.g., Royalty Free, Single Server).

Trappable Errors (ShellMenu Struct)

ShellMenu Errors

2    An item with given ID cannot be found. The CBFSSHELL_ERR_FILE_NOT_FOUND constant is provided for convenience and may be used in place of the numeric value.
20    Cannot load native proxy DLL. The CBFSSHELL_ERR_CANT_LOAD_PROXY constant is provided for convenience and may be used in place of the numeric value.
28    The major version of the proxy DLL doesn't match the major version of the .NET assembly. The CBFSSHELL_ERR_PROXY_VERSION_MISMATCH constant is provided for convenience and may be used in place of the numeric value.
38    End of data stream has been reached and no data could be read. The CBFSSHELL_ERR_STREAM_EOF constant is provided for convenience and may be used in place of the numeric value.
55    Proxy DLL not installed properly. The CBFSSHELL_ERR_NOT_INSTALLED constant is provided for convenience and may be used in place of the numeric value.
56    Installation of the native proxy DLL failed. The CBFSSHELL_ERR_INSTALL_FAILED constant is provided for convenience and may be used in place of the numeric value.
57    Uninstallation of the native proxy DLL failed. The CBFSSHELL_ERR_UNINSTALL_FAILED constant is provided for convenience and may be used in place of the numeric value.
58    Initialization of the native proxy DLL failed. The CBFSSHELL_ERR_INIT_FAILED constant is provided for convenience and may be used in place of the numeric value.
59    The current license and the ID in the native proxy DLL name don't match. The CBFSSHELL_ERR_PROXY_NAME_MISMATCH constant is provided for convenience and may be used in place of the numeric value.
60    Writing to the Windows registry failed. The CBFSSHELL_ERR_CANT_WRITE_TO_REGISTRY constant is provided for convenience and may be used in place of the numeric value.
61    This Menu instance has already been started. The CBFSSHELL_ERR_ALREADY_STARTED constant is provided for convenience and may be used in place of the numeric value.
62    A menu item with the same verb is already registered. The CBFSSHELL_ERR_MENU_ITEM_ALREADY_REG constant is provided for convenience and may be used in place of the numeric value.
63    No menu items have been registered. The CBFSSHELL_ERR_MENU_ITEM_NOT_REG constant is provided for convenience and may be used in place of the numeric value.
87    The passed parameter was not valid. The CBFSSHELL_ERR_INVALID_PARAMETER constant is provided for convenience and may be used in place of the numeric value.
122    The provided buffer is too small to accommodate all the data that must be placed in it. The CBFSSHELL_ERR_INSUFFICIENT_BUFFER constant is provided for convenience and may be used in place of the numeric value.