Elm*_*lmo 3 .net c# vb.net winapi windows-explorer
我在.NET中创建了一个shell扩展,用于创建文件夹(将其视为上下文菜单New - > New Folder选项克隆),并使用InputBox从用户输入文件夹的名称.相反,我想将文件夹上的rename命令发送到已经打开的 Windows资源管理器窗口.它应该像Explorer让我们命名一个新文件夹一样:
在搜索时,我发现了这个:Windows资源管理器Shell扩展:创建文件并进入"重命名"模式.它说要使用IShellView::SelectItem
带有SVSI_EDIT
标志的函数.我如何用.NET做到这一点?如果这很难,还有另一种方法可以做同样的事情吗?
以下是一些执行此类操作的代码.你这样使用它:
private void button1_Click(object sender, EventArgs e)
{
SelectItemInExplorer(Handle, @"d:\temp\new folder", true);
}
Run Code Online (Sandbox Code Playgroud)
和代码:
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);
}
Run Code Online (Sandbox Code Playgroud)