要实现“手机存储的IContextMenu Shell扩展”,可以按照以下步骤进行:
- 创建一个新的C#类库项目。
- 引用Shell32.dll和System.Windows.Forms命名空间。
- 在项目中创建一个类,并实现IContextMenu接口。代码示例如下:
using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using Shell32;
namespace PhoneStorageContextMenu
{
[ComVisible(true)]
[Guid("Your-GUID-Here")]
[ClassInterface(ClassInterfaceType.None)]
public class PhoneStorageContextMenu : IContextMenu
{
public void QueryContextMenu(IntPtr hMenu, uint indexMenu, uint idCmdFirst, uint idCmdLast, uint uFlags)
{
// 在上下文菜单中添加自定义项
Shell32.Shell shell = new Shell32.Shell();
Folder folder = shell.NameSpace("Your-Phone-Storage-Path");
FolderItem item = folder.ParseName("Your-File-Name");
FolderItemVerbs verbs = item.Verbs();
for (int i = 0; i < verbs.Count; i++)
{
MenuItem menuItem = new MenuItem(verbs.Item(i).Name);
menuItem.Click += MenuItem_Click;
ContextMenu menu = new ContextMenu(new MenuItem[] { menuItem });
MenuItem[] menuItems = { menu.MenuItems[0] };
menu.MergeMenu(hMenu, indexMenu, idCmdFirst + (uint)i, idCmdLast, uFlags);
}
}
public void InvokeCommand(IntPtr pici)
{
// 处理菜单项的点击事件
uint idCmd = (uint)(Marshal.ReadInt32(pici, 0) - 1);
Shell32.Shell shell = new Shell32.Shell();
Folder folder = shell.NameSpace("Your-Phone-Storage-Path");
FolderItem item = folder.ParseName("Your-File-Name");
FolderItemVerbs verbs = item.Verbs();
if (idCmd >= 0 && idCmd < verbs.Count)
{
verbs.Item(idCmd).DoIt();
}
}
public void GetCommandString(uint idCmd, uint uFlags, IntPtr pReserved, IntPtr pszName, uint cchMax)
{
// 获取菜单项的文字描述
if (uFlags == (uint)Shell32.GCS.VERB)
{
Shell32.Shell shell = new Shell32.Shell();
Folder folder = shell.NameSpace("Your-Phone-Storage-Path");
FolderItem item = folder.ParseName("Your-File-Name");
FolderItemVerbs verbs = item.Verbs();
if (idCmd >= 0 && idCmd < verbs.Count)
{
string verbName = verbs.Item(idCmd).Name;
if (cchMax < (uint)(verbName.Length + 1))
{
Marshal.ThrowExceptionForHR((int)Shell32.HRESULT.E_FAIL);
}
else
{
Marshal.GetNativeVariantForObject(verbName, pszName);
}
}
}
}
}
}
请注意,上述代码中的"Your-GUID-Here"应替换为您自己的GUID,"Your-Phone-Storage-Path"和"Your-File-Name"应替换为您的手机存储路径和文件名。
- 在项目中添加一个名为"Registration.cs"的类,并添加以下代码:
using System;
using System.Runtime.InteropServices;
namespace PhoneStorageContextMenu
{
public static class Registration
{
[DllImport("Shell32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
public static extern void SHChangeNotify(uint wEventId, uint uFlags, IntPtr dwItem1, IntPtr dwItem2);
[ComRegisterFunction]
public static void RegisterClass(Type t)
{
try
{
Shell32.Shell shell = new Shell32.Shell();
string className = t.FullName;
string subKey = $"CLSID\\{{{t.GUID.ToString().ToUpper()}}}\\InProcServer32";
using (Microsoft.Win32.RegistryKey key = Microsoft.Win32.Registry.ClassesRoot.OpenSubKey(subKey, true))
{
key.SetValue(null, System.Environment.SystemDirectory + "\\mscoree.dll", Microsoft.Win32.RegistryValueKind.String);
}
subKey = $"CLSID\\{{{t.GUID.ToString().ToUpper()}}}\\Implemented Categories\\{{{Shell32.CLSID.ShellContextMenu}}}";
using (Microsoft.Win32.RegistryKey key = Microsoft.Win32.Registry.ClassesRoot.CreateSubKey(subKey))