C#下使用SharpShell自定义桌面鼠标右键菜单,一次选择多个文件进行后续处理
想做一个类似Winrar的右键菜单,用来处理日常桌面文档,研究了好几天。
一种比较简单的实现就是自定义注册表。比如对所有文件都适用的右键菜单,可以在HKEY_CLASSES_ROOT\*\shell注册表项下新建一个项目A,项目A下设置一个子项目Command,Command下设置一个后续处理参数C:\XXX.exe "%1"。这种网上有很多例子,可以自行检索「右键菜单 注册表」,也可以自定义菜单图标,多级菜单。
为什么最终没有用这种静态注册表的方式呢?因为这种方式不支持一次性获取多个文件或目录,并作为一个「大参数列表」传递给后续应用处理。
网上又扒了扒,得知需要实现这种需求,涉及到Windows Shell编程,不过资料并不是很多。后面参考了一篇国外大神的文章http://www.codeproject.com/Articles/512956/NET-Shell-Extensions-Shell-Context-Menus,在C#开发环境下得以实现,遂略作记录。
1、在VS中创建一个类库项目
2、管理NuGet程序包,搜索SharpShell,并安装
3、默认cs文件示例代码
using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;using System.Runtime.InteropServices;using System.Windows.Forms;using System.Diagnostics;using System.IO;using System.Reflection;using SharpShell.SharpContextMenu;using SharpShell.Attributes;namespace AuroraContextMenu{
[ComVisible(
true)]//如果按文件类型,按以下设置//[COMServerAssociation(AssociationType.ClassOfExtension, ".xlsx", ".xls")]//设置对全部文件和目录可用[COMServerAssociation(AssociationType.AllFiles), COMServerAssociation(AssociationType.Directory)]
publicclass ArrContextMenu : SharpContextMenu
{
///<summary>
/// 判断菜单是否需要被激活显示
///</summary>
///<returns></returns>
protectedoverridebool CanShowMenu()
{
returntrue;
}
///<summary>
/// 创建一个菜单,包含菜单项,设置ICON
///</summary>
///<returns></returns>
protectedoverride ContextMenuStrip CreateMenu()
{
var menu = new ContextMenuStrip();
//设定菜单项显示文字
var item = new ToolStripMenuItem("Aurora右键助手");
//添加监听事件
//item.Click += Item_Click;
//设置图像及位置
item.Image = Properties.Resources.logo;
item.ImageScaling = ToolStripItemImageScaling.None;
item.ImageTransparentColor = System.Drawing.Color.White;
item.ImageAlign = System.Drawing.ContentAlignment.MiddleLeft;
//设置次级菜单
Dictionary<string, string> subItemsInfo = new Dictionary<string, string>()
{
{ "复制完整路径", "copyPath" },
{ "合并Excel报表", "mergeExcelReport" },
{ "合并Excel工作表", "mergeExcelSheet" },
{ "转换为PDF文件...", "mergeExcelSheet" },
{ "以邮件附件发送...", "mailTo" },
{ "批量打印文档...", "batchPrint" }
};
foreach (KeyValuePair<string,string> kv in subItemsInfo)
{
var subItem = new ToolStripMenuItem(kv.Key);
subItem.Click += (o, e) =>
{
Item_Click(o, e, kv.Value);
};
item.DropDownItems.Add(subItem);
}
menu.Items.Add(item);
return menu;
}
//菜单动作
privatevoid Item_Click(object sender, EventArgs e, string arg)
{
string rootPath = getRootPath();
string appFile = string.Format(@"{0}\{1}", rootPath, "AuroraTools.exe");
if (!File.Exists(appFile))
{
MessageBox.Show(string.Format("找不到程序路径:{0}{1}", Environment.NewLine, appFile), "出错了", MessageBoxButtons.OK);
return;
}
List<string> paths = SelectedItemPaths.ToList();
paths.Add(arg);
string args = string.Join("", paths);
Process.Start(appFile, args);
}
//获取当前dll所在路径
privatestring getRootPath()
{
string codeBase = Assembly.GetExecutingAssembly().CodeBase;
UriBuilder uri = new UriBuilder(codeBase);
string path = Uri.UnescapeDataString(uri.Path);
return Path.GetDirectoryName(path);
}
}
}
该例子中设置了菜单图标,可以自己在PS中绘制一个24像素以内的png图片,放到资源文件中直接使用
4、选择强名称密钥文件,对程序集进行签名
5、Release项目,打开Release目录,可以看到升成的dll文件
6、用RegAsm.exe注册该dll文件,可以在自己电脑上搜一下该文件,将其COPY到dll同一目录,这里我写了一段bat注册和反注册代码
注册
@echooffcd /d %~dp0
echo 检查dll
set dllfile=AuroraContextMenu.dll
ifnotexist %dllfile% (
echo %dllfile% is notexist!
pause>nul
exit
)
".\RegAsm.exe" /codebase %dllfile%
pause
exit
反注册,反注册后需要重启资源管理器
@echooffcd /d %~dp0
echo 检查dll
set dllfile=AuroraContextMenu.dll
ifnotexist %dllfile% (
echo %dllfile% is notexist!
pause>nul
exit
)
".\RegAsm.exe" /codebase %dllfile% /u
echo 重启资源管理器
taskkill /f /im explorer.exe & start explorer.exe
pause
exit
7、注册成功后的效果
右键菜单dll只是一个中间件程序,对接的后续处理程序可以是c# wpf,python等各种应用程序,但需要接受命令行参数
以wpf为例,要使其接受命令行,需要在App.xaml中加上 Startup="Application_Startup"
<Application x:Class="AuroraTools.App"xmlns
="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x
="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:local
="clr-namespace:AuroraTools"StartupUri
="MainWindow.xaml"Startup
="Application_Startup"><Application.Resources>
</Application.Resources>
</Application>
并在App.xaml.cs中对Application_Startup进行定义,前面右键菜单传来的参数列表体现在e.Args中
using System;using System.Collections.Generic;using System.Configuration;using System.Data;using System.Linq;using System.Threading.Tasks;using System.Windows;namespace AuroraTools{
///<summary>/// App.xaml 的交互逻辑
///</summary>
publicpartialclass App : Application
{
privatevoid Application_Startup(object sender, StartupEventArgs e)
{
string s = string.Empty;
MessageBox.Show(string.Join(Environment.NewLine, e.Args));
App.Current.Shutdown();
}
}
}
完整的DEMO下载地址:
https://download.csdn.net/download/sinat_29203953/13669717
以上是 C#下使用SharpShell自定义桌面鼠标右键菜单,一次选择多个文件进行后续处理 的全部内容, 来源链接: utcz.com/a/76244.html