Click here to Skip to main content
15,884,237 members
Articles / Programming Languages / C#
Article

Explorer Shell Context Menu

Rate me:
Please Sign up or sign in to vote.
4.55/5 (22 votes)
27 May 2008CPOL 123.1K   7.9K   73   33
Add the Windows Explorer Shell Context Menu to your application
Screenshot -

Introduction

I am currently working on an Advanced text editor, and I was looking for a way to implement the Window's shell context menu in my code. I came across Andreas Johansson's WebLog which provided me with the answer. He took some of the code that Steven Roebert created and placed it in one file for ease of use. His code had several errors that were easily corrected, and now I am posting the finished product.

Using the Code

The code is pretty straightforward to use:

  1. Add the ShellContextMenu.cs file to your project.
  2. Create a new instance of the ShellContextMenu class.
  3. Call the ShowContextMenu method with the proper arguments.
    1. FileInfo/DirectoryInfo Array - A list of files/directories that need the Context Menu
    2. Point - Point to Display Context Menu
C#
// Sample code

ShellContextMenu ctxMnu = new ShellContextMenu();
FileInfo[] arrFI = new FileInfo[1];
arrFI[0] = new FileInfo(this.treeMain.SelectedNode.Tag.ToString());
ctxMnu.ShowContextMenu(arrFI, this.PointToScreen(new Point(e.X, e.Y)));

History

  • 12/10/07 - Created article
  • 27/05/08 - Cleaned code a bit

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer Halliburton
United States United States

Comments and Discussions

 
QuestionThanks. Works well. I made minor changes to make it work in WinUI 3 Pin
Gautam Jain21-Aug-22 23:08
Gautam Jain21-Aug-22 23:08 
QuestionApps in open with submenu doesn't work Pin
baconYao3-Dec-20 15:29
baconYao3-Dec-20 15:29 
AnswerRe: Apps in open with submenu doesn't work Pin
baconYao8-Dec-20 21:45
baconYao8-Dec-20 21:45 
AnswerRe: Apps in open with submenu doesn't work Pin
chipmonkery22-Jan-22 23:36
chipmonkery22-Jan-22 23:36 
QuestionMultiple file Pin
Member 137674963-Aug-19 4:40
Member 137674963-Aug-19 4:40 
AnswerRe: Multiple file Pin
Dennys Hsieh30-Jan-23 15:02
Dennys Hsieh30-Jan-23 15:02 
BugMoving files blocks UI Pin
davidcole10-Feb-14 4:53
davidcole10-Feb-14 4:53 
BugProblem with drive Pin
davidcole30-Dec-13 13:12
davidcole30-Dec-13 13:12 
GeneralMy vote of 5 Pin
Mazen el Senih24-Sep-12 6:56
professionalMazen el Senih24-Sep-12 6:56 
General"Send to" menu visible but doesn't execute. Pin
Roland Schneider 45122121-Dec-10 5:22
Roland Schneider 45122121-Dec-10 5:22 
AnswerRe: "Send to" menu visible but doesn't execute. Pin
NuFox Hast23-Jul-12 0:04
NuFox Hast23-Jul-12 0:04 
GeneralRe: "Send to" menu visible but doesn't execute. Pin
Gautam Jain21-Aug-22 23:04
Gautam Jain21-Aug-22 23:04 
GeneralAdd my menu to shell context menu Pin
Jen8915-Nov-10 3:28
Jen8915-Nov-10 3:28 
AnswerRe: Add my menu to shell context menu Pin
NuFox Hast22-Jul-12 23:59
NuFox Hast22-Jul-12 23:59 
GeneralRe: Add my menu to shell context menu Pin
Murdahl23-Jul-13 22:41
Murdahl23-Jul-13 22:41 
GeneralDoes not work on 64 bit Pin
uhax10119-Jun-10 1:55
uhax10119-Jun-10 1:55 
GeneralRe: Does not work on 64 bit Pin
Roland Schneider 45122121-Dec-10 1:55
Roland Schneider 45122121-Dec-10 1:55 
GeneralRe: Does not work on 64 bit Pin
Member 1032848630-Jul-14 21:34
Member 1032848630-Jul-14 21:34 
AnswerSome tweaks (drives, files and folders, desktop items) Pin
MANSATAN29-Apr-10 11:28
MANSATAN29-Apr-10 11:28 
QuestionRe: Some tweaks (drives, files and folders, desktop items) Pin
Member 795200327-May-11 19:18
Member 795200327-May-11 19:18 
AnswerRe: Some tweaks (drives, files and folders, desktop items) Pin
Jpmon131-May-11 4:00
Jpmon131-May-11 4:00 
QuestionRe: Some tweaks (drives, files and folders, desktop items) Pin
matthew4392-Aug-11 8:58
matthew4392-Aug-11 8:58 
AnswerRe: Some tweaks (drives, files and folders, desktop items) Pin
davidcole22-Jan-14 11:57
davidcole22-Jan-14 11:57 
GeneralRe: Some tweaks (drives, files and folders, desktop items) Pin
Colin Lamarre2-Mar-18 2:15
Colin Lamarre2-Mar-18 2:15 
I used the original FileBrowser to come up with this:

C#
private IShellFolder GetRootFolder()
{
    IntPtr folderEnumPtr = IntPtr.Zero;
    IEnumIDList folderEnum = null;
    IntPtr pidlSubItem;
    int celtFetched;
    IntPtr winHandle = IntPtr.Zero;
    IShellFolder oParentFolder = null;

    SHCONTF folderFlag =
        SHCONTF.FOLDERS |
        SHCONTF.INCLUDEHIDDEN;

    IntPtr tempPidl;
    SHFILEINFO info;

    if (_oRootFolder == null)
    {
        //My Computer
        info = new SHFILEINFO();
        tempPidl = IntPtr.Zero;
        SHGetSpecialFolderLocation(IntPtr.Zero, CSIDL.DRIVES, out tempPidl);

        SHGetFileInfo(tempPidl, 0, ref info, cbFileInfo, SHGFI.PIDL | SHGFI.DISPLAYNAME | SHGFI.TYPENAME);

        string sysfolderName = info.szTypeName;
        string mycompName = info.szDisplayName;

        try
        {
            oParentFolder = GetDesktopFolder();

            if (oParentFolder.EnumObjects(winHandle, folderFlag, out folderEnumPtr) == S_OK)
            {
                folderEnum = (IEnumIDList)Marshal.GetTypedObjectForIUnknown(folderEnumPtr, typeof(IEnumIDList));
                while (folderEnum.Next(1, out pidlSubItem, out celtFetched) == S_OK && celtFetched == 1)
                {
                    IntPtr shellFolderPtr;
                    if (oParentFolder.BindToObject(
                                pidlSubItem,
                                IntPtr.Zero,
                                ref IID_IShellFolder,
                                out shellFolderPtr) == S_OK)
                    {
                        IntPtr strr = Marshal.AllocCoTaskMem(MAX_PATH * 2 + 4);
                        Marshal.WriteInt32(strr, 0, 0);
                        StringBuilder buf = new StringBuilder(MAX_PATH);

                        string txt = "";
                        if (oParentFolder.GetDisplayNameOf(
                                        pidlSubItem,
                                        SHGNO.INFOLDER,
                                        strr) == S_OK)
                        {
                            StrRetToBuf(strr, pidlSubItem, buf, MAX_PATH);
                            txt = buf.ToString();
                        }

                        Marshal.FreeCoTaskMem(strr);

                        if (txt == mycompName)
                        {
                            _oRootFolder = (IShellFolder)Marshal.GetTypedObjectForIUnknown(shellFolderPtr, typeof(IShellFolder));
                            break;
                        }
                    }
                }
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.ToString());
        }
        finally
        {
            if (folderEnum != null)
            {
                Marshal.ReleaseComObject(folderEnum);
                Marshal.Release(folderEnumPtr);
            }
        }
    }

    return _oRootFolder;
}


so if Parent is null then use that like this:


C#
if (arrFI[n].Parent == null)
    oParentFolder = GetRootFolder();
else
...


modified 2-Mar-18 8:30am.

GeneralRe: Some tweaks (drives, files and folders, desktop items) Pin
fabricedupre@free.fr9-Mar-16 9:30
fabricedupre@free.fr9-Mar-16 9:30 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.