发送文件夹重命名命令到Windows资源管理器

时间:2011-12-27 17:28:41

标签: c# .net vb.net winapi windows-explorer

我在.NET中创建了一个shell扩展,用于创建文件夹(将其视为上下文菜单New - > New Folder选项克隆),并使用InputBox从用户输入文件夹的名称。相反,我想将文件夹上的rename命令发送到已打开的 Windows资源管理器窗口。它应该像Explorer让我们命名一个新文件夹一样:

Pic

在搜索时,我发现了这个:Windows Explorer Shell Extension: create file and enter "rename" mode。它说使用带有IShellView::SelectItem标志的SVSI_EDIT函数。我如何用.NET做到这一点?如果这很难,还有另一种方法可以做同样的事情吗?

2 个答案:

答案 0 :(得分:6)

这是一些执行此类操作的代码。你这样使用它:

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

代码:

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

答案 1 :(得分:2)

这是一种间接方法,但您可以使用SendKeys函数将F2键发送到当前打开的Windows资源管理器窗口,然后模拟所需文件夹名称的输入并发送输入密钥。