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注册和反注册代码

注册

@echooff

cd /d %~dp0

echo 检查dll

set dllfile=AuroraContextMenu.dll

ifnotexist %dllfile% (

echo %dllfile% is notexist!

pause>nul

exit

)

".\RegAsm.exe" /codebase %dllfile%

pause

exit

反注册,反注册后需要重启资源管理器

@echooff

cd /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、注册成功后的效果

C#下使用SharpShell自定义桌面鼠标右键菜单,一次选择多个文件进行后续处理

右键菜单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

回到顶部