Bạn có thể bắt đầu tạo một dự án với SharpShell đăng ký một menu ngữ cảnh vỏ mới như trong tutorial này.
Ở đây, chúng tôi phải xác định một lớp thực hiện SharpContextMenu
. Để đơn giản chúng ta sẽ tạo menu cho bất kỳ filetype và luôn hiển thị nó:
[ComVisible(true)]
[COMServerAssociation(AssociationType.AllFiles)]
public class CopyFilesExtension : SharpContextMenu
{
protected override bool CanShowMenu()
{
return true;
}
protected override ContextMenuStrip CreateMenu()
{
var menu = new ContextMenuStrip();
var copyFiles = new ToolStripMenuItem { Text = "Copy Files To Folder..." };
copyFiles.Click += (sender, args) => CopyFiles();
menu.Items.Add(copyFiles);
return menu;
}
private void CopyFiles()
{
...
}
}
Nhưng tôi chắc chắn rằng bạn đã làm tất cả điều này, vấn đề ở đây là để thực hiện các phương pháp CopyFiles()
.
Một cách để làm điều này là hiển thị một hộp thoại yêu cầu tên của thư mục, một cái gì đó như thế này:
Sau đó, thực hiện CopyFiles()
như vậy:
private void CopyFiles()
{
using (var dialog = new CopyFileDialog())
{
if (dialog.ShowDialog() == DialogResult.OK)
{
var folder = Path.GetDirectoryName(SelectedItemPaths.First());
var newFolder = Path.Combine(folder, dialog.FolderName);
Directory.CreateDirectory(newFolder);
foreach (var path in SelectedItemPaths)
{
var newPath = Path.Combine(newFolder, Path.GetFileName(path));
File.Move(path, newPath);
}
}
}
}
Trong trên mã, chúng tôi đã yêu cầu tên của thư mục, sau đó tạo thư mục và cuối cùng di chuyển các tệp đã chọn vào thư mục đó.
Tuy nhiên, nếu bạn muốn làm điều đó bằng Đổi tên lệnh trong Windows Explorer chúng ta có thể bắt đầu bằng cách nhập số cần thiết Win32 chức năng:
class Win32
{
[DllImport("shell32.dll", CharSet = CharSet.Unicode)]
public static extern IntPtr ILCreateFromPath([In, MarshalAs(UnmanagedType.LPWStr)] string pszPath);
[DllImport("shell32.dll")]
public static extern int SHOpenFolderAndSelectItems(IntPtr pidlFolder, uint cidl, IntPtr[] apidl, int dwFlags);
[DllImport("shell32.dll")]
public static extern void ILFree(IntPtr pidl);
}
ILCreateFromPath
cho phép chúng ta có được PIDL từ tên tệp.
SHOpenFolderAndSelectItems
cho phép chúng tôi chọn tệp và gửi lệnh đổi tên.
ILFree
giải phóng không được quản lý PIDL
được tạo.
Với những Win32 chức năng chúng ta có thể định nghĩa CopyFiles()
như sau:
private void CopyFiles()
{
var folder = Path.GetDirectoryName(SelectedItemPaths.First());
var newFolder = Path.Combine(folder, "New Folder");
Directory.CreateDirectory(newFolder);
foreach (var path in SelectedItemPaths)
{
var newPath = Path.Combine(newFolder, Path.GetFileName(path));
File.Move(path, newPath);
}
RenameInExplorer(newFolder);
}
private static void RenameInExplorer(string itemPath)
{
IntPtr folder = Win32.ILCreateFromPath(Path.GetDirectoryName(itemPath));
IntPtr file = Win32.ILCreateFromPath(itemPath);
try
{
Win32.SHOpenFolderAndSelectItems(folder, 1, new[] { file }, 1);
}
finally
{
Win32.ILFree(folder);
Win32.ILFree(file);
}
}
Chúng tôi không thể sử dụng SharpShell.Interop.Shell32
kể từ khi phương pháp duy nhất có sẵn trong lớp này là ShellExecuteEx()
được sử dụng để khởi động quy trình mới.
Khi bạn tạo thư mục mới bằng cách sử dụng Explorer, thư mục này đặt tên cho thư mục là "Thư mục mới" và sau đó nó sẽ chuyển sang chế độ đổi tên. Khi bạn đang gõ tên thư mục và sau đó nhấn enter, bạn đang thực sự đổi tên thư mục. Điều gì xảy ra nếu người dùng đổi tên thư mục, sau đó nhấn enter trước khi các tệp sao chép xong? Việc đổi tên có thể sẽ thất bại vì các tệp vẫn đang được sao chép vào thư mục. Tôi nghĩ rằng cách tiếp cận này là không tốt và bạn tốt hơn off hiển thị một hình thức với một hộp văn bản cho người dùng. – Ove