Question

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 from the user. Instead I want to send the rename command on the folder to the already open Windows Explorer window. It should be just like how Explorer lets us name a new folder:

Pic

On searching, I found this : Windows Explorer Shell Extension: create file and enter "rename" mode. It says to use the IShellView::SelectItem function with the SVSI_EDIT flag. How do I do that with .NET? If that's hard, is there another way to do the same?

Was it helpful?

Solution

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);
}

OTHER TIPS

This is kind of an indirect approach, but you can use the SendKeys function in order to send the F2 key to the currently open windows explorer window, and then simulate the typing of the desired folder name and send the Enter key.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top