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

3
我有一个用.NET制作的Shell扩展程序,它创建文件夹(类似于上下文菜单New -> New Folder选项),并使用InputBox从用户那里输入文件夹的名称。相反,我想将重命名命令发送到已经打开的Windows资源管理器窗口中的文件夹。它应该就像资源管理器让我们命名新文件夹一样简单:Pic
在搜索过程中,我发现了这篇文章:Windows Explorer Shell Extension: create file and enter "rename" mode,它建议使用IShellView::SelectItem函数和SVSI_EDIT标志。如何在.NET中实现这个功能呢?如果这很困难,是否有其他方法可以实现同样的效果?

3
你的 shell 扩展实现了 IShellView COM 接口吗? - M.Babcock
6
请注意,不建议或支持使用.NET shell扩展。 - Raymond Chen
2个回答

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

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

如果您知道文件夾名稱,請輸入其名稱以獲得焦點;否則,只需按日期排序文件夾,然後發送 {END} 鍵。 - Uri Goren
您可以自己激活资源管理器窗口,然后再将应用程序激活回来。 - Uri Goren

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接