diff --git a/PInvoke/Shell32/ShObjIdl.IExplorerCommand.cs b/PInvoke/Shell32/ShObjIdl.IExplorerCommand.cs
new file mode 100644
index 00000000..afdc925c
--- /dev/null
+++ b/PInvoke/Shell32/ShObjIdl.IExplorerCommand.cs
@@ -0,0 +1,460 @@
+using System;
+using System.Runtime.InteropServices;
+using System.Runtime.InteropServices.ComTypes;
+
+namespace Vanara.PInvoke
+{
+ public static partial class Shell32
+ {
+ /// Windows Explorer command states.
+ [PInvokeData("shobjidl_core.h", MSDNShortId = "61e94e50-9e12-4a2c-a6c7-64a9181f80b8")]
+ [Flags]
+ public enum EXPCMDFLAGS
+ {
+ /// Windows 7 and later. No command flags are set.
+ ECF_DEFAULT = 0x000,
+
+ /// The command has subcommands.
+ ECF_HASSUBCOMMANDS = 0x001,
+
+ /// A split button is displayed.
+ ECF_HASSPLITBUTTON = 0x002,
+
+ /// The label is hidden.
+ ECF_HIDELABEL = 0x004,
+
+ /// The command is a separator.
+ ECF_ISSEPARATOR = 0x008,
+
+ /// A UAC shield is displayed.
+ ECF_HASLUASHIELD = 0x010,
+
+ /// Introduced in Windows 7. The command is located in the menu immediately below a separator.
+ ECF_SEPARATORBEFORE = 0x020,
+
+ /// Introduced in Windows 7. The command is located in the menu immediately above a separator.
+ ECF_SEPARATORAFTER = 0x040,
+
+ /// Introduced in Windows 7. Selecting the command opens a drop-down submenu (for example, Include in library).
+ ECF_ISDROPDOWN = 0x080,
+
+ /// Introduced in Windows 8.
+ ECF_TOGGLEABLE = 0x100,
+
+ /// Introduced in Windows 8.
+ ECF_AUTOMENUICONS = 0x200,
+ }
+
+ /// EXPCMDSTATE values represent the command state of a Shell item.
+ // https://docs.microsoft.com/en-us/windows/win32/api/shobjidl_core/ne-shobjidl_core-_expcmdstate typedef enum _EXPCMDSTATE {
+ // ECS_ENABLED, ECS_DISABLED, ECS_HIDDEN, ECS_CHECKBOX, ECS_CHECKED, ECS_RADIOCHECK } ;
+ [PInvokeData("shobjidl_core.h", MSDNShortId = "41e76b6e-9294-40b3-bb8b-bbfe487fd023")]
+ [Flags]
+ public enum EXPCMDSTATE
+ {
+ /// The item is enabled.
+ ECS_ENABLED = 0x00,
+
+ /// The item is unavailable. It might be displayed to the user as a dimmed, inaccessible item.
+ ECS_DISABLED = 0x01,
+
+ /// The item is hidden.
+ ECS_HIDDEN = 0x02,
+
+ /// The item is displayed with a check box and that check box is not checked.
+ ECS_CHECKBOX = 0x04,
+
+ /// The item is displayed with a check box and that check box is checked. ECS_CHECKED is always returned with ECS_CHECKBOX.
+ ECS_CHECKED = 0x08,
+
+ ///
+ /// Windows 7 and later. The item is one of a group of mutually exclusive options selected through a radio button.
+ /// ECS_RADIOCHECK does not imply that the item is the selected option, though it might be.
+ ///
+ ECS_RADIOCHECK = 0x10,
+ }
+
+ ///
+ /// Provided by an IExplorerCommandProvider. This interface contains the enumeration of commands to be put into the command bar.
+ ///
+ ///
+ /// None of the methods of this interface should talk to network resources. They are called on the UI thread; communicating with
+ /// network resources would cause the UI to stop responding.
+ ///
+ // https://docs.microsoft.com/en-us/windows/win32/api/shobjidl_core/nn-shobjidl_core-ienumexplorercommand
+ [PInvokeData("shobjidl_core.h", MSDNShortId = "c9a21e84-dd95-413a-b9db-e02008185bef")]
+ [ComImport, Guid("a88826f8-186f-4987-aade-ea0cef8fbfe8"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
+ public interface IEnumExplorerCommand
+ {
+ /// Retrieves a specified number of elements that directly follow the current element.
+ ///
+ /// Type: ULONG
+ /// Specifies the number of elements to fetch.
+ ///
+ ///
+ /// Type: IExplorerCommand**
+ ///
+ /// Address of an IExplorerCommand interface pointer array of celt elements that, when this method returns, is an array of
+ /// pointers to the retrieved elements.
+ ///
+ ///
+ ///
+ /// Type: ULONG*
+ ///
+ /// When this method returns, contains a pointer to the number of elements actually retrieved. This pointer can be NULL
+ /// if this information is not needed.
+ ///
+ ///
+ ///
+ /// Type: HRESULT
+ /// If this method succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code.
+ ///
+ // https://docs.microsoft.com/en-us/windows/win32/api/shobjidl_core/nf-shobjidl_core-ienumexplorercommand-next HRESULT Next(
+ // ULONG celt, IExplorerCommand **pUICommand, ULONG *pceltFetched );
+ [PreserveSig]
+ HRESULT Next([In] uint celt, [Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] IExplorerCommand[] pUICommand, out uint pceltFetched);
+
+ /// Not currently implemented.
+ ///
+ /// Type: ULONG
+ /// Currently unused.
+ ///
+ ///
+ /// Type: HRESULT
+ /// If this method succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code.
+ ///
+ // https://docs.microsoft.com/en-us/windows/win32/api/shobjidl_core/nf-shobjidl_core-ienumexplorercommand-skip HRESULT Skip(
+ // ULONG celt );
+ [PreserveSig]
+ HRESULT Skip([In] uint celt);
+
+ /// Resets the enumeration to 0.
+ // https://docs.microsoft.com/en-us/windows/win32/api/shobjidl_core/nf-shobjidl_core-ienumexplorercommand-reset HRESULT Reset();
+ void Reset();
+
+ /// Not currently implemented.
+ ///
+ /// Type: IEnumExplorerCommand*
+ /// Currently unused.
+ ///
+ // https://docs.microsoft.com/en-us/windows/win32/api/shobjidl_core/nf-shobjidl_core-ienumexplorercommand-clone HRESULT Clone(
+ // IEnumExplorerCommand **ppenum );
+ [return: MarshalAs(UnmanagedType.Interface)]
+ IEnumExplorerCommand Clone();
+ }
+
+ /// Exposes methods that get the command appearance, enumerate subcommands, or invoke the command.
+ ///
+ /// None of the methods of this interface should communicate with network resources. These methods are called on the UI thread, so
+ /// communication with network resources could cause the UI to stop responding.
+ ///
+ // https://docs.microsoft.com/en-us/windows/win32/api/shobjidl_core/nn-shobjidl_core-iexplorercommand
+ [PInvokeData("shobjidl_core.h", MSDNShortId = "61e94e50-9e12-4a2c-a6c7-64a9181f80b8")]
+ [ComImport, Guid("a08ce4d0-fa25-44ab-b57c-c7b1c323e0b9"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
+ public interface IExplorerCommand
+ {
+ /// Gets the title text of the button or menu item that launches a specified Windows Explorer command item.
+ ///
+ /// Type: IShellItemArray*
+ /// A pointer to an IShellItemArray.
+ ///
+ ///
+ /// Type: LPWSTR*
+ /// Pointer to a buffer that, when this method returns successfully, receives the title string.
+ ///
+ ///
+ /// Type: HRESULT
+ /// If this method succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code.
+ ///
+ // https://docs.microsoft.com/en-us/windows/win32/api/shobjidl_core/nf-shobjidl_core-iexplorercommand-gettitle HRESULT GetTitle(
+ // IShellItemArray *psiItemArray, LPWSTR *ppszName );
+ [PreserveSig]
+ HRESULT GetTitle(IShellItemArray psiItemArray, [MarshalAs(UnmanagedType.LPWStr)] out string ppszName);
+
+ /// Gets an icon resource string of the icon associated with the specified Windows Explorer command item.
+ ///
+ /// Type: IShellItemArray*
+ /// A pointer to an IShellItemArray.
+ ///
+ ///
+ /// Type: LPWSTR*
+ ///
+ /// Pointer to a buffer that, when this method returns successfully, receives the resource string that identifies the icon source.
+ ///
+ ///
+ ///
+ /// Type: HRESULT
+ /// If this method succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code.
+ ///
+ /// The retrieved icon resource string is in the standard format, for instance "shell32.dll,-249".
+ // https://docs.microsoft.com/en-us/windows/win32/api/shobjidl_core/nf-shobjidl_core-iexplorercommand-geticon HRESULT GetIcon(
+ // IShellItemArray *psiItemArray, LPWSTR *ppszIcon );
+ [PreserveSig]
+ HRESULT GetIcon(IShellItemArray psiItemArray, [MarshalAs(UnmanagedType.LPWStr)] out string ppszIcon);
+
+ /// Gets the tooltip string associated with a specified Windows Explorer command item.
+ ///
+ /// Type: IShellItemArray*
+ /// A pointer to an IShellItemArray.
+ ///
+ ///
+ /// Type: LPWSTR*
+ /// Pointer to a buffer that, when this method returns successfully, receives the tooltip string.
+ ///
+ ///
+ /// Type: HRESULT
+ /// If this method succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code.
+ ///
+ // https://docs.microsoft.com/en-us/windows/win32/api/shobjidl_core/nf-shobjidl_core-iexplorercommand-gettooltip HRESULT
+ // GetToolTip( IShellItemArray *psiItemArray, LPWSTR *ppszInfotip );
+ [PreserveSig]
+ HRESULT GetToolTip(IShellItemArray psiItemArray, [MarshalAs(UnmanagedType.LPWStr)] out string ppszInfotip);
+
+ /// Gets the GUID of an Windows Explorer command.
+ ///
+ /// Type: GUID*
+ ///
+ /// A pointer to a value that, when this method returns successfully, receives the command's GUID, under which it is declared in
+ /// the registry.
+ ///
+ ///
+ ///
+ /// Type: HRESULT
+ /// If this method succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code.
+ ///
+ ///
+ /// This method is somewhat misnamed, given that it retrieves a GUID. To retrieve the command's canonical name, you must take
+ /// the additional step to pull it from the command's subkey. The GUID is the name of the subkey. where that information is stored.
+ ///
+ // https://docs.microsoft.com/en-us/windows/win32/api/shobjidl_core/nf-shobjidl_core-iexplorercommand-getcanonicalname HRESULT
+ // GetCanonicalName( GUID *pguidCommandName );
+ [PreserveSig]
+ HRESULT GetCanonicalName(out Guid pguidCommandName);
+
+ /// Gets state information associated with a specified Windows Explorer command item.
+ ///
+ /// Type: IShellItemArray*
+ /// A pointer to an IShellItemArray.
+ ///
+ ///
+ /// Type: BOOL
+ ///
+ /// FALSE if a verb object should not perform any memory intensive computations that could cause the UI thread to stop
+ /// responding. The verb object should return E_PENDING in that case. If TRUE, those computations can be completed.
+ ///
+ ///
+ ///
+ /// Type: EXPCMDSTATE*
+ ///
+ /// A pointer to a value that, when this method returns successfully, receives one or more Windows Explorer command states
+ /// indicated by the EXPCMDSTATE constants.
+ ///
+ ///
+ ///
+ /// Type: HRESULT
+ /// If this method succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code.
+ ///
+ // https://docs.microsoft.com/en-us/windows/win32/api/shobjidl_core/nf-shobjidl_core-iexplorercommand-getstate HRESULT GetState(
+ // IShellItemArray *psiItemArray, BOOL fOkToBeSlow, EXPCMDSTATE *pCmdState );
+ [PreserveSig]
+ HRESULT GetState(IShellItemArray psiItemArray, [MarshalAs(UnmanagedType.Bool)] bool fOkToBeSlow, out EXPCMDSTATE pCmdState);
+
+ /// Invokes a Windows Explorer command.
+ ///
+ /// Type: IShellItemArray*
+ /// A pointer to an IShellItemArray.
+ ///
+ ///
+ /// Type: IBindCtx*
+ ///
+ /// A pointer to an IBindCtx interface, which provides access to a bind context. This value can be NULL if no bind
+ /// context is needed.
+ ///
+ ///
+ ///
+ /// Type: HRESULT
+ /// If this method succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code.
+ ///
+ // https://docs.microsoft.com/en-us/windows/win32/api/shobjidl_core/nf-shobjidl_core-iexplorercommand-invoke HRESULT Invoke(
+ // IShellItemArray *psiItemArray, IBindCtx *pbc );
+ [PreserveSig]
+ HRESULT Invoke(IShellItemArray psiItemArray, IBindCtx pbc);
+
+ /// Gets the flags associated with a Windows Explorer command.
+ ///
+ /// Type: EXPCMDFLAGS*
+ /// When this method returns, this value points to the current command flags. One of more of the following values:
+ /// ECF_DEFAULT (0x000)
+ /// Windows 7 and later. No command flags are set.
+ /// ECF_HASSUBCOMMANDS (0x001)
+ /// The command has subcommands.
+ /// ECF_HASSPLITBUTTON (0x002)
+ /// A split button is displayed.
+ /// ECF_HIDELABEL (0x004)
+ /// The label is hidden.
+ /// ECF_ISSEPARATOR (0x008)
+ /// The command is a separator.
+ /// ECF_HASLUASHIELD (0x010)
+ /// A UAC shield is displayed.
+ /// ECF_SEPARATORBEFORE (0x020)
+ /// Introduced in Windows 7. The command is located in the menu immediately below a separator.
+ /// ECF_SEPARATORAFTER (0x040)
+ /// Introduced in Windows 7. The command is located in the menu immediately above a separator.
+ /// ECF_ISDROPDOWN (0x080)
+ /// Introduced in Windows 7. Selecting the command opens a drop-down submenu (for example, Include in library).
+ /// ECF_TOGGLEABLE (0x100)
+ /// Introduced in Windows 8.
+ /// ECF_AUTOMENUICONS (0x200)
+ /// Introduced in Windows 8.
+ ///
+ ///
+ /// Type: HRESULT
+ /// If this method succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code.
+ ///
+ // https://docs.microsoft.com/en-us/windows/win32/api/shobjidl_core/nf-shobjidl_core-iexplorercommand-getflags HRESULT GetFlags(
+ // EXPCMDFLAGS *pFlags );
+ [PreserveSig]
+ HRESULT GetFlags(out EXPCMDFLAGS pFlags);
+
+ /// Retrieves an enemerator for a command's subcommands.
+ ///
+ /// Type: IEnumExplorerCommand**
+ ///
+ /// When this method returns successfully, contains an IEnumExplorerCommand interface pointer that can be used to walk the set
+ /// of subcommands.
+ ///
+ ///
+ ///
+ /// Type: HRESULT
+ /// If this method succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code.
+ ///
+ ///
+ ///
+ /// Subcommands are displayed as menu drop-down items through the use of a Split button when commands are exposed at the top of
+ /// a Windows Explorer window. In that position, only the default command button is given an icon. In a normal menu, the icons
+ /// for all commands are shown.
+ ///
+ ///
+ /// Subcommands which themselves have subcommands are not supported by Windows Explorer. When a command has its own subcommands,
+ /// it must designate this status by specifying ECF_HASSUBCOMMANDS in the IExplorerCommand::GetFlags call.
+ ///
+ ///
+ // https://docs.microsoft.com/en-us/windows/win32/api/shobjidl_core/nf-shobjidl_core-iexplorercommand-enumsubcommands HRESULT
+ // EnumSubCommands( IEnumExplorerCommand **ppEnum );
+ [PreserveSig]
+ HRESULT EnumSubCommands(out IEnumExplorerCommand ppEnum);
+ }
+
+ /// Exposes methods to create Explorer commands and command enumerators.
+ ///
+ ///
+ /// None of the methods of this interface should communicate with network resources; they are called on the UI thread and doing so
+ /// would cause the UI to stop responding.
+ ///
+ ///
+ /// Each command should have its own unique GUID; the command provider is expected to create a command instance on a per-GUID basis.
+ ///
+ ///
+ // https://docs.microsoft.com/en-us/windows/win32/api/shobjidl_core/nn-shobjidl_core-iexplorercommandprovider
+ [PInvokeData("shobjidl_core.h", MSDNShortId = "f39ea1f7-28ba-4a5e-ac19-bcfc6052fdeb")]
+ [ComImport, Guid("64961751-0835-43c0-8ffe-d57686530e64"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
+ public interface IExplorerCommandProvider
+ {
+ /// Gets a specified Explorer command enumerator instance.
+ ///
+ /// Type: IUnknown*
+ /// A pointer to an interface used to set a site.
+ ///
+ ///
+ /// Type: REFIID
+ /// A reference to the IID of the requested interface.
+ ///
+ ///
+ /// Type: void**
+ /// When this function returns, contains the interface pointer requested in riid. This will typically be IEnumExplorerCommand.
+ ///
+ ///
+ /// Type: HRESULT
+ /// If this method succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code.
+ ///
+ // https://docs.microsoft.com/en-us/windows/win32/api/shobjidl_core/nf-shobjidl_core-iexplorercommandprovider-getcommands
+ // HRESULT GetCommands( IUnknown *punkSite, REFIID riid, void **ppv );
+ [PreserveSig]
+ HRESULT GetCommands([MarshalAs(UnmanagedType.IUnknown)] object punkSite, in Guid riid, [MarshalAs(UnmanagedType.IUnknown)] out object ppv);
+
+ // IExplorerCommand
+ /// Gets a specified Explorer command instance.
+ ///
+ /// Type: REFGUID
+ /// A reference to a command ID as a GUID. Used to obtain a command definition.
+ ///
+ ///
+ /// Type: REFIID
+ /// A reference to the IID of the requested interface.
+ ///
+ ///
+ /// Type: void**
+ /// When this function returns, contains the interface pointer requested in riid. This will typically be IExplorerCommand.
+ ///
+ ///
+ /// Type: HRESULT
+ /// If this method succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code.
+ ///
+ // https://docs.microsoft.com/en-us/windows/win32/api/shobjidl_core/nf-shobjidl_core-iexplorercommandprovider-getcommand HRESULT
+ // GetCommand( REFGUID rguidCommandId, REFIID riid, void **ppv );
+ [PreserveSig]
+ HRESULT GetCommand(in Guid rguidCommandId, in Guid riid, [MarshalAs(UnmanagedType.IUnknown)] out object ppv);
+ }
+
+ /// Exposes a single method that allows retrieval of the command state.
+ ///
+ /// When to Implement
+ ///
+ /// Implement this interface when you need to determine the command state dynamically (for instance, based on an item's properties).
+ /// This interface provides the same functionality as IExplorerCommand::GetState, without the overhead of that interface's
+ /// additional methods. Implement IExplorerCommandState when you only need to compute the command state.
+ ///
+ /// When to Use
+ ///
+ /// Do not call the method of IExplorerCommandState directly. Windows Explorer calls your IExplorerCommandState::GetState
+ /// implementation when the user wants to perform an action on the item.
+ ///
+ ///
+ // https://docs.microsoft.com/en-us/windows/win32/api/shobjidl_core/nn-shobjidl_core-iexplorercommandstate
+ [PInvokeData("shobjidl_core.h", MSDNShortId = "020a6f6f-1d45-44bd-a57f-ef8000976b5b")]
+ [ComImport, Guid("bddacb60-7657-47ae-8445-d23e1acf82ae"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
+ public interface IExplorerCommandState
+ {
+ /// Gets the command state associated with a specified Shell item.
+ ///
+ /// Type: IShellItemArray*
+ /// A pointer to an IShellItemArray with a single element that represents the Shell item.
+ ///
+ ///
+ /// Type: BOOL
+ ///
+ /// FALSE if a verb object should not perform any memory intensive computations that could cause the UI thread to stop
+ /// responding. The verb object should return E_PENDING in that case. If TRUE, those computations can be completed.
+ ///
+ ///
+ ///
+ /// Type: EXPCMDSTATE*
+ ///
+ /// A pointer to a value that, when this method returns successfully, receives one or more Windows Explorer command states
+ /// indicated by the EXPCMDSTATE constants.
+ ///
+ ///
+ ///
+ /// Type: HRESULT
+ /// If this method succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code.
+ ///
+ ///
+ /// This method provides the same functionality as GetState. Use IExplorerCommandState when you only need to know the command state.
+ ///
+ // https://docs.microsoft.com/en-us/windows/win32/api/shobjidl_core/nf-shobjidl_core-iexplorercommandstate-getstate HRESULT
+ // GetState( IShellItemArray *psiItemArray, BOOL fOkToBeSlow, EXPCMDSTATE *pCmdState );
+ [PreserveSig]
+ HRESULT GetState(IShellItemArray psiItemArray, [MarshalAs(UnmanagedType.Bool)] bool fOkToBeSlow, out EXPCMDSTATE pCmdState);
+ }
+ }
+}
\ No newline at end of file