Send Folder Rename Command to Windows Explorer

前端 未结 2 1774
既然无缘
既然无缘 2021-01-20 11:37

I have a shell extension made in .NET that creates folders (think of it as a context menu New -> New Folder option clone) and uses a InputBox to input the name of the folder

2条回答
  •  [愿得一人]
    2021-01-20 12:04

    Here is some code that does this kind of things. You use it like this:

    private void button1_Click(object sender, EventArgs e)
    {
        SelectItemInExplorer(Handle, @"d:\temp\new folder", true);
    }
    

    And the code:

    public static void SelectItemInExplorer(IntPtr hwnd, string itemPath, bool edit)
    {
        if (itemPath == null)
            throw new ArgumentNullException("itemPath");
    
        IntPtr folder = PathToAbsolutePIDL(hwnd, Path.GetDirectoryName(itemPath));
        IntPtr file = PathToAbsolutePIDL(hwnd, itemPath);
        try
        {
            SHOpenFolderAndSelectItems(folder, 1, new[] { file }, edit ? 1 : 0);
        }
        finally
        {
            ILFree(folder);
            ILFree(file);
        }
    }
    
    [DllImport("shell32.dll")]
    private static extern int SHOpenFolderAndSelectItems(IntPtr pidlFolder, uint cidl, IntPtr[] apidl, int dwFlags);
    
    [DllImport("shell32.dll")]
    private static extern void ILFree(IntPtr pidl);
    
    [DllImport("shell32.dll")]
    private static extern int SHGetDesktopFolder(out IShellFolder ppshf);
    
    [DllImport("ole32.dll")]
    private static extern int CreateBindCtx(int reserved, out IBindCtx ppbc);
    
    [ComImport, Guid("000214E6-0000-0000-C000-000000000046"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    internal interface IShellFolder
    {
        void ParseDisplayName(IntPtr hwnd, IBindCtx pbc, [In, MarshalAs(UnmanagedType.LPWStr)] string pszDisplayName, out uint pchEaten, out IntPtr ppidl, ref uint pdwAttributes);
        // NOTE: we declared only what we needed...
    }
    
    private static IntPtr GetShellFolderChildrenRelativePIDL(IntPtr hwnd, IShellFolder parentFolder, string displayName)
    {
        IBindCtx bindCtx;
        CreateBindCtx(0, out bindCtx);
        uint pchEaten;
        uint pdwAttributes = 0;
        IntPtr ppidl;
        parentFolder.ParseDisplayName(hwnd, bindCtx, displayName, out pchEaten, out ppidl, ref pdwAttributes);
        return ppidl;
    }
    
    private static IntPtr PathToAbsolutePIDL(IntPtr hwnd, string path)
    {
        IShellFolder desktopFolder;
        SHGetDesktopFolder(out desktopFolder);
        return GetShellFolderChildrenRelativePIDL(hwnd, desktopFolder, path);
    }
    

提交回复
热议问题