Python添加windows资源管理器上下文菜单 无条目限制
目前开发一个项目x1ntt/pychee6需要在资源管理器的上下文菜单中插入命令,于是调查了一下python能用的库。
目前来说,最好用的库是Context_ment ,接口设计简单,使用方便,同时还兼容Linux系统;再者就是通过使用COM的方式让资源管理器主动调用Python脚本。这种方案条目限制比较宽松,能有几百个条目,使用上也会更自由一点(繁琐)。
Context_menu
项目地址:saleguas/context_menu: A Python library to create and deploy cross-platform native context menus.
其基本原理是通过修改注册表来实现在资源管理器中添加条目,但是当条目超过16个的时候,多出来的部分不会显示。我猜这个是因为早期电脑性能不好,如果条目过多,上下文菜单需要很久才能弹出来,所以有这个限制(xp时代)。
具体使用例子可以看项目Readme,如果需要中文例子,可以看:Python跨平台上下文菜单库 —— context_menu 使用指南-CSDN博客
如果只是为了实现在上下文菜单中添加一两个命令,那么这个库就是最好的选择,忽略下面吧。
COM方案的实现
但是我的需求需要实现将lychee中的所有相册结构映射到上下文菜单中,数量会非常多,所以只能使用这个方案。具体可以看我的x1ntt/pychee6_cm项目。
找了很久,没有一个现成的库实现COM方案来做这件事,但是我找到了一个例子代码:py-tools/ShellExtension at master · winterTTr/py-tools (具体见shell_extension.py文件)。
这个例子是基于pywin32库实现的,它是python2编写的,可以交给AI改写为Python3。
简述COM
COM技术是微软公司制定的一种Windows平台下的软件模块复用技术。借助于COM技术,用户可以编写一些具有特定接口的软件模块(称为COM组件 ),它们可以以dll或exe的形式注册到Windows系统中来对外公开自己,其它的应用程序则可以借助于Windows提供的API来调用这些组件,从而在整个系统范围内实现了软件模块的复用 COM开发指南(1)—COM技术概述-CSDN博客
如果不打算深究这个技术,可以简单理解成server和client的关系。通过windows api实现一个server,同时实现一些接口,然后给server分配一个GUID,client就能根据GUID连接到server。至此,双方通过约定好的接口通信即可。
可以在com_objects找到pywin32实现的一些com接口。
要实现修改资源管理器上下文的功能,我们需要关注PyIShellExtInit和PyIContextMenu这两个接口
一个添加上下文菜单的例子
这里以我的x1ntt/pychee6_cm: 用于注册pychee.cli到windows资源管理的上下文菜单 项目作为例子。
src目录中有如下文件
| 代码文件 | 作用 |
|---|---|
| reg.py | 代码逻辑,实现com组件 |
| register.bat | 将reg.py中实现的组件注册到注册表 |
| unregister.bat | 取消注册 |
| debug_register.bat | 启用调试模式的注册,输出调试信息到调试窗口 |
| open_trace_window.bat | 打开调试窗口,本质是运行了site-packages\win32\lib\win32traceutil.py 需要调整为正确路径 |
| restart_explorer.bat | 重启资源管理器 |
修改过reg.py文件后,必须通过restart_explorer.bat重启资源管理器代码才会生效,重新注册不会生效。
例子解析
见pychee6_cm项目的reg.py文件
将类注册到注册表
from win32com.server import register
register.UseCommandLine(ShellExtension,
finalize_register=DllRegisterServer,
finalize_unregister=DllUnregisterServer)
导入win32com.server,将注册ShellExtension类,同时指定注册和取消注册时的回调函数。
DllRegisterServer函数将clsid(其实就是上面说的GUID),写进注册表,告诉资源管理器出现如下情况时调用clsid对应的com组件
| 注册表路径 | 含义 |
|---|---|
*\\shellex\\ContextMenuHandlers\\ |
任意文件右键 |
directory\\shellex\\ContextMenuHandlers\\ |
文件夹右键 |
directory\\background\\shellex\\ContextMenuHandlers\\ |
进入文件夹后右键空白处 |
Software\\Microsoft\\Windows\\CurrentVersion\\Shell Extensions\\Approved |
告知资源管理器使用这个组件 |
ShellExtension
这个就是实现的com组件,需要关注的重点是:
_reg_clsid_就是组件的唯一id也就是写进注册表的值,资源管理器通过这个值找到组件,可以通过任意方式得到诸如{7C15377B-26A0-4582-A594-12F95CABD4A2}的值(GUID)。_com_interfaces_表明该组件实现了什么接口,提供了什么功能,例如例子中提供了IID_IShellExtInit和IID_IContextMenu(详细文档PyIShellExtInit Object、PyIContextMenu Object)
接下来实现两个接口对应的几个函数即可
| 函数名 | 归属接口 | 调用时机及含义 |
|---|---|---|
| Initialize | IID_IShellExtInit | 点击右键时,用于获取待操作的目录或选中的文件 |
| QueryContextMenu | IID_IContextMenu | 点击右键时,用于提供菜单条目,在这里编辑菜单 |
| InvokeCommand | IID_IContextMenu | 点击具体条目时,调用对应的命令 |
| GetCommandString | IID_IContextMenu | 检索上下文菜单选项的动词或帮助文本 |
通过debug_register.bat注册之后,右键打开菜单,应该能在调试窗口中看到上面函数被调用。
Initialize
获取上下文菜单需要操作的目标(菜单上下文)
QueryContextMenu
方法中使用win32gui.InsertMenu函数构建菜单,这里需要注意的一点是QueryContextMenu参数中提供的idCmdFirst, idCmdLast两个参数,指定了InsertMenu的idCmd取值范围,如果超过这个范围,可能会导致混乱(具体我也不知道会发生什么),所以这个方案其实还是有条目数量限制的。
至于InsertMenu函数的参数含义,可以看这里:InsertMenuW 函数 (winuser.h) - Win32 apps | Microsoft Learn。因为pywin32本身是对windows api的封装,所以直接参考其开发手册应该没有问题。
InvokeCommand
参数传递的verb参数用来标记用户执行了那个条目,我本来以为这是idCmd的作用,但实际上verb只是个索引,它表示执行你插入的第几个菜单条目。
GetCommandString
我不知道它的作用是什么,目前没看出来实际作用。
最终实现的效果

Python添加windows资源管理器上下文菜单 无条目限制的更多相关文章
- 为Windows资源管理器右键菜单添加菜单项
为Windows资源管理器右键菜单添加菜单项 在Windows下命令行用的比较多,经常在资源管理器里翻到某个目录,若想要在此目录下跑命令,只能是打开cmd.exe,然后一路cd才能到达此目录. 每次都 ...
- 解决Windows资源管理器右键菜单打开EditPlus容易导致资源管理器无响应问题
这个问题确实很烦人,经常导致 资源管理器无响应,关闭后整个资源管理器彻底崩溃,原因未知.本着折腾和强迫症精神,这个问题一定要解决.方法如下: 1.不要用EditPlus自带的添加到系统右键菜单选项. ...
- 如何在Windows资源管理器右键菜单中 添加CMD
我们在用windows时经常需要在某个目录下执行执行一些dos命令,通常我们会在开始菜单的运行下键入:cmd,开启dos命令窗口,然后在cd到目标操作目录,每次这样操作比较麻烦.下面介绍一种直接在资源 ...
- [原创] Delphi小工具(Windows资源管理器右键菜单扩展)
两个小工具 1. 项目临时文件清理 2. Android Ndk 编译 c/c++ jni 源码工具. 下载后,点击Reg.bat就可以完成注册安装.不需要时点击 UnReg.Bat 就可以删除菜单. ...
- 怎样在Windows资源管理器中添加右键菜单以及修改右键菜单顺序
有时,我们需要在Windows资源管理器的右键菜单中添加一些项,以方便使用某些功能或程序. 比如我的电脑上有一个免安装版的Notepad++,我想在所有文件的右键菜单中添加一项用Notepad++打开 ...
- 如何添加“在这里打开PowerShell”到Windows中的上下文菜单
It was only a matter of time, right? Due to my recent infatuation passionate love affair with PowerS ...
- SharePoint 2010 "客户端不支持使用windows资源管理器打开此列表" 解决方法
SharePoint 2010 在“库”--“库工具”,有一个“使用资源管理器打开”的按钮,点上去报“客户端不支持使用windows资源管理器打开此列表”.如图: 解决方案:在“开始”--“管理工具” ...
- 出现“Windows资源管理器已停止工作”错误
出现"Windows资源管理器已停止工作"错误 什么是资源管理器呢,explorer.exe进程的作用就是让我们管理计算机中的资源! 今天开电脑的时候就一直提示windows资源管 ...
- Windows资源管理器文件名排序
Windows资源管理器文件名排序 Windows资源管理器文件名排序 背景:自然排序 什么是自然排序? 怎样按自然排序的规则进行排序? 基于Python的解决方案 参考材料 这学期担任了本科生教学助 ...
- SVN has atopping svn已停止工作 or windows资源管理器无限重启
准备在空间时间用用linux,就在自己的win7系统上安装了属性系统,用easyBCD安装的,谁知安装好之后win7系统下的svn客户端不能使用了,点击报错“SVN已停止工作”,随后怀疑是linux引 ...
随机推荐
- nginx集群同步方案
之前公司同事写过rsync加触发nginx reload脚本,适合nginx配置内容完全一致的情况. 今天写一个同步指定文件的脚本,修改完主服务器.使用scp传输到其他nginx服务器上重启NGINX ...
- [.net core] 创建和发布NuGet包 (dotnet CLI)
[原文] :https://docs.microsoft.com/zh-cn/nuget/quickstart/create-and-publish-a-package-using-the-dotne ...
- symfony4怎么切换到开发环境的问题
1.根目录下有.env文件,约17行有这句: APP_ENV=dev 默认开发环境 prod为生产环境 2..env.local.php文件(如果有)会覆盖.env的配置
- 如何基于 Kestrel 实现 socks5 代理
前言 之前做了个轮子NZOrz, 本来打算慢慢参照Kestrel和Yarp长久地写着玩 奈何川普上台,关税,订婚案,自身和钱包等等各种乐子层出不穷,无暇慢悠悠地写轮子玩 还有有些盆友也想知道能否直接使 ...
- Laravel RCE(CVE-2021-3129)漏洞复现
Laravel框架简介 Laravel是一套简洁.优雅的PHP Web开发框架(PHP Web Framework).它可以让你从面条一样杂乱的代码中解脱出来:它可以帮你构建一个完美的网络APP,而且 ...
- Marmoset Toolbag 4.02 八猴渲染器破解版 免费下载
猴安装包下载链接 https://pan.baidu.com/s/1Mgy3Mrlrb3Tvtc8w7Zn1nA?pwd=6666 提取码:6666 Marmoset Toolbag是由Monkey公 ...
- python中_自动生成的_pycache__文件夹
_pycache__文件夹可以看作该文件夹下文件已被python接管或者说编译过. 在第一次执行代码的时候,Python解释器已经把编译的字节码放在__pycache__文件夹中,这样以后再次运行的话 ...
- 国内首个「混合推理模型」Qwen3深夜开源,盘点它的N种对接方式!
今日凌晨,通义千问团队正式开源了 Qwen3 大模型,并且一口气发布了 8 个型号,其中包括 0.6B.1.7B.4B.8B.14B.32B 以及 30B-A3B 和 235B-A22B,使用者可以根 ...
- Multisim14.0安装包免费获取,超详细中文安装步骤助你快速上手!
Multisim14.0简介 Multisim14.0是由美国国家仪器公司(NI)推出的专业电子设计自动化](EDA)工具,广泛应用于电路设计.仿真验证.教学实验及科研开发领域.其核心功能是通过虚拟仿 ...
- 领域驱动的事实与谬误 一 DDD 与 MVC
本文有以下几个目的: 让新手少交智商税,少浪费时间看一些软文. 普及一个基本概念:了解一项观点的提出年代和最初初衷,才能更好地掌握其精粹. 我想指出市场上一些误人子弟的软文. 首先说明:文中所说的谬误 ...